我真的想了解继承的原理,
说我们有A类和B类,B扩展了A,A包含一些在public和方法上设置的属性(引用类型和原始类型)
这些属性和方法是否已复制到B类中?我确实读过那些方法没有被复制,但是可以通过引用来访问。
创建B的实例时继承的引用类型属性如何?它们必须在内存中占用一些空间,该引用存储在哪里?在A或B类中?他们将原始类型复制到类B中吗,并且它们是否位于发现B其他属性的位置相同?
或者当您创建类B的对象时,实际上您创建了A和B的对象并且它们保持某种关系?
一些解释会有所帮助。
答案 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!!
讨论:
有A
和B
两个类。类B
扩展了A
。 A
是超类,而B
是其子类。这两个类分别具有两个构造函数,一个是默认的无参数构造函数,另一个是带有参数的构造函数。
类A
具有原始类型和引用类型的公共属性:int aNumber
和java.lang.StringBuilder aString
。有公共方法getMyNumber
,getMyString
和java.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"));
这将使用提供的参数B
和2
构造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属性。