在Sub和Super中定义的私有方法,都可以在Sub的Object上调用这两种方法,那么为什么说私有方法不被继承呢?

时间:2019-05-06 17:46:10

标签: java inheritance private-methods

根据Oracle Tutorials

  

子类不继承其父类的私有成员。但是,如果超类具有用于访问其私有字段的公共或受保护的方法,则子类也可以使用这些方法。

[问题] 对于Sub extends Super类关系, 据了解,Oracle文档是这样说的,只是为了支持“只能重写继承的方法”这一事实,但是这是一种误导性语句,好像它暗示着=> 方法没有被继承,那么它就不会作为Sub类对象的行为出现,并且如果这样,则绝不能在Sub类的对象上调用它。但是Super类中的方法可以在Sub类的对象上调用Super类定义的私有方法。 请参考以下几点和相关代码,并建议我的理解是否有差距?

我一直很了解继承的三点内容

  1. Sub继承了所有实例方法和字段(包括私有实例)。
  2. 如果方法在Super中是私有的,则它在Sub中不可见,但这并不意味着Sub的对象没有该行为。

第1点和第2点的代码

public class Super{
    private void privateMethod(){
        System.out.println("private method defined in Super");
    }
    public void m(){
        privateMethod();
    }
}

public class Sub extends Super{

} 
public void Other{
    public static void main(String[] args){
        Sub s = new Sub();
        s.m(); 
    }
}

我们创建了Sub对象,m()Sub继承,并且其public意味着Super外部的代码可以访问它。在调用m()时,我们可以调用privateMethod()。如果不继承私有方法,则将发生某些运行时异常,而事实并非如此。

  1. Overriding仅适用于Sub类中的 visible 实例方法。如果在两个类SubSuper中都定义了一个方法,则该对象既具有功能,又可以由可以访问特定方法的代码调用这两个方法(请参见下面的代码)

第3点的代码

public class Super{
    private void privateMethod(){
        System.out.println("private method defined in Super");
    }
    public void m(){
        privateMethod();
    }
}

public class Sub extends Super{
    private void privateMethod(){
        System.out.println("private method defined in Sub");
    }
    public void m2(){
        privateMethod();
    }
} 
public class Other{
    public static void main(String[] args){
        Sub s = new Sub();
        s.m(); // m() will invoke private method of Super
        s.m2(); // m2() will invoke private method of Sub
    }
}

Sub类不会继承Super的私有方法,这意味着不能在Sub的对象上调用该方法,因为该行为未继承,因此不是(不属于)对象。以上我们看到情况并非如此。

2 个答案:

答案 0 :(得分:1)

我认为关键的区别在于Java语言规范如何使用术语“继承”。 (请注意,JLS是权威文档,而不是Java教程。)

JLS 8.2, Class Members说:

  

被声明为私有的类的成员不会被该类的子类继承。

但是,在描述new运算符的行为时,JLS 15.9.4, Run-Time Evaluation of Class Instance Creation Expressions说(强调我):

  

新对象包含在指定类类型中声明的所有字段及其所有超类的新实例。

这意味着超类字段不是子类继承的,但是子类的 instance 对象仍然包含这些字段。相同的概念也适用于私有方法

尽管可以在子类的实例上调用超类的私有方法,但该方法在形式上并不是该子类的一部分。 私有方法仍然属于超类。

这是由于子类型(“ is-a”)关系而起作用的。子类型的实例是的实例。 该类不会将那些成员继承到其自身中,但是该类的 instance 仍包含它们。

答案 1 :(得分:0)

在您给出的示例中,来自类privateMethod的{​​{1}}实际上是私有的,不能被Super继承。这样的设计意味着我们不希望子类具有Sub的行为,这就是为什么将privateMethod包装在公共方法中是不合逻辑的,然后privateMethod类可以执行该方法并具有“私人行为”。 因此,这种实现方式不会在现实生活中使用。

并且由于Sub未被privateMethod继承,因此在其中实现的Sub不是替代,而是恰好具有相同签名的方法。如果您尚未在privateMethod中定义方法,则将无法使用Sub(即s.m2())。

  

但是Super类中的方法可以调用由定义的私有方法   超级班

这就是它的含义:任何类都可以使用本身定义的方法,无论是公共方法还是私有方法。