Java私有方法覆盖

3

我遇到了这样的情况。我们有一个类,假设叫Main,其中有一个私有方法print。还有另一个类Main1,它扩展了Main类并重新定义了print方法。由于main1是Main1类的一个对象,我希望main1的print方法被调用...

public class Main {
    public static void main(String[] args) {
       Main main1 = new Main1();
       List<String> list = new ArrayList<String>();
       main1.print(list);
    }

    private void print(List<String> string) {
       System.out.println("main");
    }

}

class Main1 extends Main {
    public void print(List<String> string) {
       System.out.println("main1");
    }
}

在这种情况下,当我们运行程序时,它会打印“main”。这让我很困惑,因为该方法是私有的,甚至不是Main1类的一部分。

你能澄清一下你的问题吗?为什么你认为它不是私有的或者Main1的一部分? - Sean Owen
我也很困惑,当没有这样的方法(没有参数的print)时,你如何调用main1.print(); - Buhake Sindi
你已经收到了正确的答案。这是来自Java语言规范的相关段落:http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.8.1。 - Nicola Musatti
4个回答

13
答案并不太难:
  • main1变量的类型Main(而不是Main1
  • 因此,您只能调用该类型的方法
  • Main中唯一可能带有List<String>参数的print方法是私有方法
  • 调用代码在Main类内部,因此它可以调用该类中的私有方法
因此将调用Main.print(List<String>)
请注意,将main1的类型更改为Main1将导致调用另一个print(List<String>)方法。

1
+1:如果您将“print”设置为非私有,则会使用继承。私有成员无法遵循继承。 - Peter Lawrey
1
我认为您错过了问题的主要点,即为什么Main1.print()没有覆盖Main.print()。 - Nicola Musatti
私有方法不能被覆盖。这是语言规范。 - kingori

1
如果你想要覆盖你的 print 方法,你必须将它声明为 public
public class Main {

   public void print(List<String> string) {
   }

}

否则它会调用你的私有方法,而不会在派生类中寻找实现。

1

您的代码中私有方法不会被继承且没有发生方法覆盖。 您可以通过在 Main1.print() 方法上添加 @Override 注释来查看此情况。如果添加了该注释,将产生编译错误。

Main.java:17: method does not override or implement a method from a supertype
        @Override
        ^
1 error

在您的情况下,Main1.print() 和 Main.print() 是不同的,彼此之间没有关联(没有覆盖,没有重载)。因此,如果您将 main1 指定为 Main,则会调用 Main.print()。如果您将 main1 指定为 Main1,则会调用 Main1.print()。

1

你的 main1 是 Main 类型,但是用 Main1 实例化了它!这没问题,因为它是 Main 的子类。然而,当你调用 print 方法时(顺便说一下,应该是 main1.print(list);),它将调用 Main 类中的私有方法!如果你将方法的可见性更改为 protected 或 public,在这种情况下,Main1 类中的 print 方法将被调用,因为实例化对象具有多态行为(请记住,它毕竟是根据你提供的代码一个 Main1 对象!)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接