【问题标题】:Override "private" method in java覆盖java中的“私有”方法
【发布时间】:2021-09-09 02:46:51
【问题描述】:

这个想法有些模棱两可,我需要澄清一下。

我的问题是使用此代码时:

public class B {

    private void don() {
        System.out.println("hoho private");
    }
    public static void main(String[] args) {
        B t = new A();
        t.don();
    }
}

class A extends B {
    public void don() {
        System.out.println("hoho public");
    }
}

输出为hoho private

这是因为main函数与方法don在同一个类中,还是因为覆盖?

我在一本书中读过这个想法,当我将main 函数放在另一个类中时,出现编译器错误。

【问题讨论】:

  • 一些不错的阅读:stackoverflow.com/questions/2000137/…
  • 你在隐藏而不是覆盖。
  • 除了在类型之外不可见(也许与这里的问题更相关),私有方法是不是多态的——只有在类型上定义的方法表达式将永远被调用;不会发生动态调度。在所示示例中,t 表达式的类型为 B,因此 t.don()始终调用 B 的 don运行时类型A 是无关紧要的,并且不允许“覆盖”这种私有方法。
  • 那么this的工作原理即使子类对象被分配给子类引用它仍然调用父类私有方法
  • @user2864740 的评论不仅解决了真正的模棱两可的行为。

标签: java


【解决方案1】:

您不能覆盖private 方法。如果您将A 转换为B,它是不可见的。您可以覆盖protected 方法,但这不是您在这里所做的(是的,如果您将main 移动到A,那么您将获得另一种方法. 当你打算覆盖时,我会推荐@Override 注解,

class A extends B {
    @Override
    public void don() { // <-- will not compile if don is private in B.
        System.out.println("hoho public");
    }
}

在这种情况下,为什么编译器没有提供使用 t.don()private 的错误?

The Java Tutorials: Predefined Annotation Types 说(部分)

虽然在重写方法时不需要使用此注解,但它有助于防止错误。如果标有@Override 的方法未能正确覆盖其超类之一中的方法,则编译器会生成错误。

【讨论】:

  • 谢谢 Elliott,但是主函数如何使用 t.don() 而它是类 B 中的私有方法
  • @basel 因为它是BinB 中的每个函数都可以访问类B 中的私有方法。
  • @ElliottFrisch 但是使用@Override 应该会产生编译时错误,对吧?我们正在尝试覆盖 private 方法。 (这是一个真正的问题,我并不是要纠正你:))
  • @Kaushik private 方法不会被继承,因此您不能覆盖它们。正确的。当你打算Override 时使用注解,当你实际上没有Override 一个方法时会导致编译错误。这完全是我的观点。
【解决方案2】:

您不能覆盖私有方法,但您可以毫无问题地在派生类中引入私有方法。派生类无法访问祖先的私有方法。

由于tB类型的on对象,调用don()方法会调用B处定义的方法。它甚至不知道有一个在类 A

中也命名为 don() 的方法

【讨论】:

    【解决方案3】:

    不,私有方法不能被覆盖,因为它在任何其他类中都不可见。您已经为您的子类声明了一个与超类方法无关的新方法。一种看待它的方法是问自己在 Derived 类中编写 super.func() 是否合法。

    【讨论】:

    • 私有方法可以在非常具体的场景中从其他类可见。将可见性与继承混淆是错误的,因为它们并不总是匹配。
    • @Kröw : 请更新你的知识,你不能直接从外部类调用或覆盖私有方法,间接你可以从同一个类中声明的公共方法调用它,并且可以调用公共方法从外面看,但这仍然是间接的,间接的一切皆有可能! ..........具体!
    • 私有方法可以直接从嵌套类调用。
    【解决方案4】:

    这是因为主函数和方法“don”在同一个类中

    不,这是因为 Adon()Bdon() 方法无关,尽管具有相同的名称和参数列表。 private 方法隐藏在它们的类中。它们不能由外部调用者直接调用,例如您的情况下的 main 方法,因为它们被封装在类中。它们不参与方法覆盖。

    【讨论】:

    • 在这种情况下,为什么编译器在使用私有的 t.don() 时没有给出编译错误??
    • 因为它在Java语言中有效
    【解决方案5】:

    私有成员对任何其他类都不可见,甚至是孩子

    您不能覆盖私有方法,但话又说回来,您也不能调用它。但是,您可以在子项中创建具有相同名称的相同方法。

    public class A
    {
        private int calculate() {return 1;}
        public void visibleMethod()
        {
            System.out.println(calculate());
        };
    }
    
    public class B extends A
    {
        private int calculate() {return 2;}
        public void visibleMethod()
        {
            System.out.println(calculate());
        };
    }
    

    如果您调用 A.visibleMethod(),它会打印出 1。

    如果你调用 B.visibleMethod(),它会打印 2。

    如果B中没有实现私有的calculate()方法,它不会编译,因为调用它的公共方法看不到A中的私有方法。

    【讨论】:

    • 但是我可以在 B 中覆盖 calculate 而不必重新实现 visibleMethod 吗?
    猜你喜欢
    • 1970-01-01
    • 2011-01-01
    • 1970-01-01
    • 2014-05-28
    • 2013-01-31
    • 2011-05-25
    • 2023-04-09
    相关资源
    最近更新 更多