【问题标题】:Java - Access Modifiers and Which Methods Are CalledJava - 访问修饰符和调用哪些方法
【发布时间】: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 postthissuper 不要“坚持”。因此,对于第一种情况,getName() 应该使用Student 的实现,因为this 指的是Student 实例(无论访问修饰符如何)。但是好像不是这样的。。

提前致谢!

【问题讨论】:

    标签: java inheritance this super access-modifiers


    【解决方案1】:

    在每种情况下,Person.printName() 都会调用 getName()

    Case 1 中,唯一可见的版本是Person.getName(),因此PersonStudent 都调用它。

    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# 中情况并非如此,它需要 PersongetName 上的 virtual 关键字才能以这种方式工作。
      猜你喜欢
      • 2013-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-25
      • 1970-01-01
      • 1970-01-01
      • 2017-08-17
      • 2014-01-08
      相关资源
      最近更新 更多