继承:在原来的基础上再进行扩展 所以子类包含了超类的东西 构造函数负责初始化 所以最好的办法当然是每个类负责自己的数据成员的初始化 如果没调用超类的构造 那么子类的初始化很可能没完全完成 从而数据成员采用的就是默认的初始值,而不是你想要的初值比如 class A { int i; public A(int i) { this.i = i; } public int getI() { return i; } }class B extends A { public B(int i) { super(i); //没有这个则A中的i为0而不是10 } public static void main(String[] args) { B b = new B(10); int i = b.getI(); //如果你没有调用超类构造,那么获得的i就是默认值0,而不是你所想要的10 } }这只是我的一点认识 不代表只有这点用处
楼主想法能理解。不错,是会产生的多个对象。 当你创建一个子类对象时,这个对象里面还有一个父类的子对象(subobject),这个子对象(subobject)同父类自己创建的对象相同,只是从外面看来它被包裹在子类对象里面. 这个subobject正确初始化是非常重要的,而且只有一个办法来保证这一点,调用父类的构造函数来初始化、因为只有父类的构造函数才有权限的执行初始化的信息。 比如B extends A B b; --这是定义,在stack空间中 b = new B(); --这是初始化,因为new,系统在heap中分配一个内存空间. 但在初始化b时,首先要初始化A,所以这里就会产生一个A的子对象(subobject),然后调用A的构造方法。构造行为是从父类“向外”发展的,所以父类会在子类的构造函数访问它之前先进行初始化。 这是我理解的继承。
所以子类包含了超类的东西
构造函数负责初始化
所以最好的办法当然是每个类负责自己的数据成员的初始化
如果没调用超类的构造
那么子类的初始化很可能没完全完成
从而数据成员采用的就是默认的初始值,而不是你想要的初值比如
class A
{
int i;
public A(int i)
{
this.i = i;
} public int getI()
{
return i;
}
}class B extends A
{
public B(int i)
{
super(i); //没有这个则A中的i为0而不是10
} public static void main(String[] args)
{
B b = new B(10);
int i = b.getI(); //如果你没有调用超类构造,那么获得的i就是默认值0,而不是你所想要的10
}
}这只是我的一点认识
不代表只有这点用处
所以实例化和初始化并不是一个过程。
它们的超类对象肯定没有被生成。既然你的类是继承得到的,那你的类就已经包含所有超类的东西了。只不过你从代码里只能看到你新添的东西。不信你可以在子类里输出一个超类的成员。如果不考虑访问权限和变量作用域的存在,你调用super和直接将父类构造函数的内容复制过来是一样的,但真是由于java存在访问权限和变量作用域,为了保证正确性,才有了super这样的关键字。
你的问题是没有正确理解继承,有关super和直接复制的区别又涉及到多态。
建议现好好理解书本。
是
超类构造函数的执行仍然是发生在子类里面的。不仅仅是构造函数,就算是在普通函数里面出现“super.函数”这样的语句也是如此。
而且我前面说了,构造函数的作用是初始化,不是实例化。起实例化作用的是new,初始化发生在实例化之后。
子类继承父类的一切,所以子类中也包括父类中定义的private成员,这些成员需要父类的构造方法来初始化。
所以编译器设计这样一种规则。
比如B extends A
B b; --这是定义,在stack空间中
b = new B(); --这是初始化,因为new,系统在heap中分配一个内存空间.
但在初始化b时,首先要初始化A,所以这里就会产生一个A的子对象(subobject),然后调用A的构造方法。构造行为是从父类“向外”发展的,所以父类会在子类的构造函数访问它之前先进行初始化。
这是我理解的继承。
调试的时候可以看到,子类的对象中除了包括自己定义的field之外,还使用inherited指出其他继承的field,这里面都是从父类继承下来的field