Java - 访问修饰符和调用哪些方法
Posted
技术标签:
【中文标题】Java - 访问修饰符和调用哪些方法【英文标题】:Java - Access Modifiers and Which Methods Are Called 【发布时间】:2018-04-18 02:10:53 【问题描述】:所以我有以下两种情况:
案例 1:
public class Person
private String name = "Person";
private String getName()
return name;
public void printName()
System.out.println( getName() );
public class Student extends Person
private double gpa = 0;
private String getName()
return “Student”;
public class Driver
public static void main(String[] args)
Person p = new Person();
Student s = new Student();
p.printName(); // “Person”
s.printName(); // “Person”
案例 2:
public class Person
private String name = "Person";
public String getName()
return name;
public void printName()
System.out.println( getName() );
public class Student extends Person
private double gpa = 0;
public String getName()
return “Student”;
public class Driver
public static void main(String[] args)
Person p = new Person();
Student s = new Student();
p.printName(); // “Person”
s.printName(); // “Student”
案例 2 最有意义(这是预期的行为)。
但是为什么案例 1 的输出与案例 2 不同(“Person”而不是“Student”)?
据我了解,非静态调用隐式使用this
。并且从此SO post、this
和super
不要“坚持”。因此,对于第一种情况,getName()
应该使用Student
的实现,因为this
指的是Student
实例(无论访问修饰符如何)。但是好像不是这样的。。
提前致谢!
【问题讨论】:
【参考方案1】:在每种情况下,Person.printName()
都会调用 getName()
。
在Case 1
中,唯一可见的版本是Person.getName()
,因此Person
和Student
都调用它。
在Case 2
中,Student.getName()
覆盖Person.getName()
,因此调用了前者。
因此应用于getName()
的不同可见性会影响结果。当它是public
(或protected
)时,它可以被覆盖并且调用的方法将取决于对象。当它是private
时,没有覆盖并且总是调用Person.getName()
。
【讨论】:
【参考方案2】:对于案例 1,Student#getName
确实不 覆盖 Person#getName
,因为方法是 private
,这意味着其他类无法访问它们。因为Student#getName
隐式覆盖Person#getName
(因为现在两者都是public
),所以Student
在案例2 中打印。
【讨论】:
我也在努力学习 Java。这些也可以设置为受保护并且仍然有效吗? @DanielZuzevich 绝对!只要子类能够覆盖其父类的方法,那么子类就会调用其getName
。
请注意,Java 中的 public
对象方法也是 virtual
。因此,为什么案例 2 会以它的方式工作;在 C++/C# 中情况并非如此,它需要 Person
的 getName
上的 virtual
关键字才能以这种方式工作。以上是关于Java - 访问修饰符和调用哪些方法的主要内容,如果未能解决你的问题,请参考以下文章