Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的继承到底发生了什么?_Java_Inheritance - Fatal编程技术网

Java中的继承到底发生了什么?

Java中的继承到底发生了什么?,java,inheritance,Java,Inheritance,假设我有两个类Parent和Child,并且Child继承自Parent。我在Parent中有三种方法,其中两种是公共的,一种是私有的 通常我们说所有的非私有方法都被继承到子类中,但我不清楚到底发生了什么。Java是复制子类中的方法,还是使用某种引用来维护这种关系 class Parent{ // Private method private void method1(){ System.out.println("In private method of Pare

假设我有两个类
Parent
Child
,并且
Child
继承自
Parent
。我在
Parent
中有三种方法,其中两种是公共的,一种是私有的

通常我们说所有的非私有方法都被继承到
子类中,但我不清楚到底发生了什么。Java是复制
子类中的方法,还是使用某种引用来维护这种关系

class Parent{
    // Private method
    private void method1(){
        System.out.println("In private method of Parent class");
    }
    void method2(){
    // calling private method
        method1();
    }
    void method3(){
    // calling private method
        method1();
    }
}

class Child extends Parent{

}

class MainClass{
   public static void main(String[] args){
       Child child = new Child();
       // calling non-private method which internally calls the private method
       child.method2();
   }
}
Java是复制子类中的方法还是使用某种引用来维护关系

class Parent{
    // Private method
    private void method1(){
        System.out.println("In private method of Parent class");
    }
    void method2(){
    // calling private method
        method1();
    }
    void method3(){
    // calling private method
        method1();
    }
}

class Child extends Parent{

}

class MainClass{
   public static void main(String[] args){
       Child child = new Child();
       // calling non-private method which internally calls the private method
       child.method2();
   }
}
后者。看一看。Java递归地一次查找一个类的方法。调用第一个匹配方法。这就是调用虚(默认)方法比调用
final
方法慢的原因


通常,当您从包含该方法的类继承时,不会复制该方法中的实际代码

Java不复制这些方法。继承的方法只保留在父类中

现在你们一定想知道,孩子们是如何访问它们的

答案在于理解超级关键字

super关键字用于引用直接父类的对象。super做的第一件事是初始化父类的对象。这意味着它负责创建父类的对象,并用于引用该对象

super()隐式地是子类构造函数中的第一条语句,但是您也可以显式地这样做

现在重要的部分是:

如果您有以下内容

super();
不是作为子类构造函数中的第一条语句,然后生成编译错误,说明:

call to super must be first statement in constructor.
原因是:

因为假定子类具有继承的方法,但不具有它们的副本。

继承的方法基本上是与父类一起使用的,因此首先创建父类的对象很重要,以便在使用下列方法时

instance_of_child.method_of_parent();
该方法实际上将从父类的对象调用,父类已由super创建(显式或隐式使用)

这就是为什么可以使用子类构造函数的原因,如:

Child()
{
 super();
 parent_method();
}
但不象:

Child()
{
 parent_method();
 super();
}

因为继承的方法parent_method()需要引用super()提供的父类的对象。

方法体不会复制到子类的未定义方法体中。相反,当你打电话时

Child child1 = new Child();
child1.method1();
它将查看其层次结构,每次找不到实现时都会提升一个级别。首先,它将检查没有实现的子级。上面的一级是父级,因此它将使用该级。正如上面@Dante所正确提到的,这是通过子类构造函数中的super()调用实现的。此图像可能有助于您更好地了解:

我认为你的困惑某种程度上与这一点有关 私有方法的非继承性。所以,我也想解决这个问题

为什么不继承私有成员?

您可以说私有成员不是继承的,因为没有任何地方可以显式地引用值。也就是说,像
this.value
这样的任何代码都不能在
Child
中使用,也不能从某些调用代码中使用
obj.value
(显然)。 然而,在另一种意义上,你可以说价值是继承的。如果您认为<<代码>子< /代码>的每个实例也是<代码>父< /代码>的实例,则该对象必须包含<代码> <代码> > <代码>父< /代码>。即使
Child
类对它一无所知,私有成员名称值仍然存在于
Child
的每个实例中。因此,从这个意义上讲,您可以说值在
子类中是“继承的”。因此,如果不使用“继承”一词,请记住子类不知道父类中定义的私有成员。但是还要记住,这些私有成员仍然存在于子类的实例中

注意:JLS状态():

声明为私有的类的成员不会被继承 该类的子类。仅声明类的成员 protected或public由包中声明的子类继承 而不是在其中声明类的

都不是

继承是一种编程语言概念,而不是实际操作。当您调查编译的
子类时,例如使用
javap
,您不会发现任何与
父类的三种方法相关的工件。将有信息表明
Child
具有超类
Parent
,但没有提及继承的方法,既不是作为引用也不是作为副本

当您实际尝试通过编译时类型为
Child
的变量调用其中一个方法时,
Child
在概念上继承了来自
Parent
的方法,就像在
Test
类中一样。然后由编译器找到继承的方法,以便正确编译包含调用的代码。编译器是否在每次解析调用的目标方法时搜索类层次结构,或者是否收集某些数据结构中的现有方法以加快后续查找,以及使用哪些数据结构,也取决于编译器

这个过程比你想象的要复杂得多。可能有多个候选者,其中编译器必须选择一个,甚至可能由于歧义而失败。该过程的结果将决定调用是否有效,如果有效,则决定sin