应该如何跟踪具有继承的 Java 程序?

Posted

技术标签:

【中文标题】应该如何跟踪具有继承的 Java 程序?【英文标题】:How the Java program with inheritance should be traced? 【发布时间】:2019-08-30 10:55:45 【问题描述】:

我正在寻找一种方法来解释应如何跟踪以下 Java 程序(调用哪个方法等),尤其是访问修饰符和继承如何影响方法调用。

我有两个类 A 和 B,其中 B 扩展 A。 A类有私有方法process() B类有公共方法process() A 类有公共方法callProcess(),它调用process()。 在主程序中,我创建一个对象B并调用方法callProcess()

class A 
    private void process()
        System.out.println("Process A.");
    
    public void callProcess()
        process();
    

class B extends A 
    public void process()
        System.out.println("Process B.");
    

class MethodTest
    public static void main(String[] args)
        B b1 = new B();
        b1.callProcess();
    

我希望调用来自 B 的 process(),因为调用 process() 的对象属于 B 类型,但是会调用来自 A 的 process()。 更奇怪的是,如果我将 A 中 process() 的修饰符更改为 public,那么 B 中的 process() 就会被调用。

【问题讨论】:

您正在创建 B 类的对象,并调用 A 类上的公共函数 b1.callProcess()。调用被执行并调用 A 类中的 process() 方法,如那是带有签名的私有函数,因此不会被扩展类 B 覆盖。当您更改类 A 中方法 process() 的修饰符时,它与类 B 中方法 process() 的签名完全匹配,继承的类方法将优先,因此当你再次调用时,方法 b1.callProcess() ,类 B 中的 process() 方法被执行。 【参考方案1】:

是的,对于隐式覆盖,被覆盖的方法不能具有比覆盖更严格的访问级别。

【讨论】:

【参考方案2】:

由于来自Aprocessprivate 方法,所以B 完全不知道它的存在并且不能被覆盖。

同样,当您在B 的实例上调用callProcess 时,它会调用A.callProcess(因为它没有在B 中被覆盖)。 A 只知道自己的 process 方法(不能被覆盖)并调用它。

如果您要将Aprocess 方法的可见性更改为publicprotected,那么它可以在B 中被覆盖,只要签名匹配即它们必须具有相同的可见性。

【讨论】:

那么,为什么当 B 中的 process() 被覆盖时,它仍然不调用 A 中的 process() 呢? 在您的代码中,processB被覆盖。私有方法不能被覆盖,实际上子类甚至不知道它们的存在。如果您在父类中有私有方法,在子类中有公共方法,那么它们也可能具有完全不同的名称和签名。它们是完全不同的。 protectedpublic 方法可以被覆盖。当您将A.process 的签名更改为public 时,它与B.process 的签名匹配,因此会被覆盖,因此B.callProcess 会调用被覆盖的process 方法。

以上是关于应该如何跟踪具有继承的 Java 程序?的主要内容,如果未能解决你的问题,请参考以下文章

如何跟踪具有访问令牌的用户是否仍具有有效会话?

在 C# 中如何收集程序崩溃的堆栈跟踪

我应该如何跟踪打开的 DataReader?

对具有变化属性的对象进行建模

如何使用Java跟踪JVM文件系统访问

如何使用开始和停止 UIButtons 连续跟踪位置坐标并查找距离 [关闭]