Java继承是复制超级内容吗?

时间:2018-11-01 00:19:46

标签: java inheritance

我真的想了解继承的原理,

说我们有A类和B类,B扩展了A,A包含一些在public和方法上设置的属性(引用类型和原始类型)

这些属性和方法是否已复制到B类中?我确实读过那些方法没有被复制,但是可以通过引用来访问。

创建B的实例时继承的引用类型属性如何?它们必须在内存中占用一些空间,该引用存储在哪里?在A或B类中?他们将原始类型复制到类B中吗,并且它们是否位于发现B其他属性的位置相同?

或者当您创建类B的对象时,实际上您创建了A和B的对象并且它们保持某种关系?

一些解释会有所帮助。

2 个答案:

答案 0 :(得分:0)

假设有一个动物类:

public class Animal {
    private String _name;

    public Animal(String name) { _name = name;}

    public String getName() {return _name;}
}

现在有一个Dog类:

public class Dog extends Animal {
    public Dog() {
        super("Dog");
    }
}

现在,如果您这样做:

 Animal dog = new Dog();
 System.out.println(dog.getName());

这是使变量名称从Dog类到Animal可用的方式。

答案 1 :(得分:0)

  

Java继承是复制超级内容吗?

     

我真的想了解继承的原理,

     

假设我们有A类和B类,B扩展了A类,A类包含一些属性   (引用类型和原始类型)在public和方法上设置

     

这些属性和方法是否已复制到类B中?


公共属性和方法由子类B继承。考虑类A及其子类B

public class A {

    public int aNumber = 99;
    public StringBuilder aString = new StringBuilder("sb");
    private String privateVar = "private stuff";

    public A() {
    }

    public A(int i, StringBuilder s) {
        aNumber = i;
        aString = s;
    }

    public int getMyNumber() {
        return aNumber*2;
    }
    public StringBuilder getMyString() {
        return aString.append("!!");
    }
    @Override
    public String toString() {
        return aNumber + " : " + aString;
    }
}

public class B extends A {

    public B() {
    }

    public B(int i, StringBuilder s) {
        super(i, s);
    }
}


下面的类在继承方面具有一些代码来测试上述两个类的行为:

public class TestingInheritance {
    public static void main(String [] args) {

        A a = new A(3, new StringBuilder("test1"));
        System.out.println("A: " + a);

        B b = new B();
        System.out.println("b: " + b);
        System.out.println("b.aNumber: " + b.aNumber);
        System.out.println("b.getMyNumber: " + b.getMyNumber());
        System.out.println("");

        B b2 = new B(2, new StringBuilder("xx"));
        System.out.println("b2: " + b2);
        System.out.println("b2.aString: " + b2.aString);
        System.out.println("b2.getMyString: " + b2.getMyString());

        //System.out.println("Private: " + b.privateVar);
    }
}


输出:

A: 3 : test1
b: 99 : sb
b.aNumber: 99
b.getMyNumber: 198

b2: 2 : xx
b2.aString: xx
b2.getMyString: xx!!


讨论:

AB两个类。类B扩展了AA是超类,而B是其子类。这两个类分别具有两个构造函数,一个是默认的无参数构造函数,另一个是带有参数的构造函数。

A具有原始类型和引用类型的公共属性:int aNumberjava.lang.StringBuilder aString。有公共方法getMyNumbergetMyStringjava.lang.Object类的重写toString。请注意,还有一个私有变量privateVar

来自TestingInheritance的代码详细信息:


(i)考虑:

B b = new B();

这将构造B的实例。这继承了其超类A的属性和方法。

System.out.println("b: " + b); // b: 99 : sb

新创建的对象b具有从其超类A继承的属性值;因此,它将通过覆盖的toString方法打印属性默认值。请注意,在类A中为属性定义的默认值为99和一个StringBuilder对象,其字符串值为“ sb”。

以下使用默认属性值打印继承的A的属性和方法结果。

System.out.println("b.aNumber: " + b.aNumber); // 99
System.out.println("b.getMyNumber: " + b.getMyNumber()); // 198


(ii)考虑:

B b2 = new B(2, new StringBuilder("xx"));

这将使用提供的参数B2构造new StringBuilder("xx")的实例。注意在类B的构造函数中,语句super(i, s);这是必需的。而且,如果未指定,则会出现编译时错误。

System.out.println("b2: " + b2); // 2 : xx

这将在B类的构造函数中打印提供的参数值,这些参数值又通过参数A传递给super(i, s)类的构造函数。创建B类的实例(使用构造函数)后,A类的构造函数将运行,首先 -参见super(...)语句(这是构造函数代码中的第一个语句。

以下显示继承的属性值和方法返回值。

System.out.println("b2.aString: " + b2.aString); // xx
System.out.println("b2.getMyString: " + b2.getMyString()); // xx!!


(iii)最后,如果未注释程序TestingInheritance,则以下语句将无法编译。将会出现错误:TestingInheritance.java:18: error: privateVar has private access in A

System.out.println("Private: " + b.privateVar);

但是,可以通过B类中定义的公共方法在A中访问private属性。