黑马程序员技术交流社区

标题: 关于对象创建的猜想? [打印本页]

作者: 最初的理想    时间: 2012-2-9 19:25
标题: 关于对象创建的猜想?
本帖最后由 最初的理想 于 2012-2-10 15:11 编辑

都知道在子类调用构造方法时候会隐含调用父类构造器super()语句,那么可以说在创建一个子类对象的同时也就创建了一个父类对象吗?如果是的话,那么这就是一个递归的过程了,是不是这回事呢?java是否也像javascript一样有对象链这个概念呢?如果没有的话,可不可以这样说,super()语句没有创建父类对象,只是把继承给子类的一些成员进行了初始化,以便于子类能够有效继承,但是这一说法有点问题,比如我们在子类中可以通过super语句调用父类成员,如果真的没有父类对象,那么调用父类成员岂不是非法操作了吗?成员不是都依附在实例对象上吗?大家如何看待这个问题。
作者: 戚雪晖    时间: 2012-2-9 21:34
父类本来就是抽取出来的共性部分,你创建其子类对象的时候,super()必然是先创建了共性的部分,也可以说是父类对象已经存在了!!而你的目的想要创建的对象是子类对象,比如你不可能说动物是猫,因此再把子类特有的部分构造进去,这样就在原有的基础上加上了子类特有的部分,因此就产生了子类对象。而且现在只有一个对象,算是父类这个对象的扩展。你可以想象:一个动物对象(假设它是实际存在的),哥们就是上帝,你给他一抓老鼠的特有功能,它就一猫;给它一啃骨头的功能,它就一狗。
作者: 杜明辉    时间: 2012-2-9 22:44
构造方法不能继承:子类继承父类所有的成员变量和成员方法,但不继承父类的构造方法
调用父类构造方法:子类的构造方法必须调用父类的构造方法!
    如果子类的构造方法中没有显示地调用父类构造方法,也没有使用this关键字调用重载的其它构造方法,则系统默认调用父类无参数的构造方法
    如果子类构造方法中既未显式调用父类构造方法,而父类中又没有无参的构造方法,则编译出错
    在子类的构造方法中可使用语句super() 调用父类的构造方法
在创建子类的对象时,Java虚拟机首先执行父类的构造方法,然后再执行子类的构造方法。在多级继承的情况下,将从继承树的最上层的父类开始,依次执行各个类的构造方法,这可以保证子类对象从所有直接或间接父类中继承的实例变量都被正确地初始化。例如以下父类Base和子类Sub分别有一个实例变量a和b,当构造Sub实例时,这两个实例变量都会被初始化。
public class Base{
private int a;
public Base(int a){ this.a=a;}
public int getA(){return a;}
}
public class Sub extends Base{
private int b;
public Sub(int a,int b){super(a); this.b=b;}
public int getB(){return b;}
public static void main(String args[]){
Sub sub=new Sub(1,2);
System.out.println("a="+sub.getA()+" b="+sub.getB()); //打印a=1 b=2
}
}
调用初始化方法并不代表会生成对象,你的java代码中出现new关键字加上构造方法的调用,只会生成一个对象,其父类对象不会生成,所以调用父类为抽象类的构造方法完全是合理的。而且初始化方法对于虚拟机来说只是一个名称叫做" <init>"的普通方法,区别只是生成对象以后调用而已
作者: 戴振良    时间: 2012-2-10 01:06
本帖最后由 戴振良 于 2012-2-10 01:08 编辑

子类是用来扩展父类的功能,或者是修改父类功能的,子类不能等同于父类,你要知道这个,如果不知道的话你就不知道子类是干嘛用的了。
比如Object类,这个是java的老祖宗(根类),这个大家都是知道的,而且所有的类都是继承或间接继承于Object类,你想想,如果创建子类就是创建父类的话,那要那么多类干嘛,大家都直接在Object类里写代码就行了。举个例子吧:
class test1
{
        String name="小强";
        int age=18;
        public void A()
        {
                System.out.println(name+(--age)+"岁");
        }
}
class test2 extends test1
{
        String sex="男";
        public void A()
        {
                System.out.println(name+":男,"+(++age)+"岁");
        }
}
class test3
{
        public static void main(String args[])
        {
                new test1().A();
                new test2().A();
        }        
}
输出结果为:   小强17岁
                      小强:男,19岁
这里我们创建了一个父类,一个子类,调用的都是A函数,但是输出的结果却大不相同,子类有成员属性sex,而父类没有,其它我就不多说了,现在你只要记住父类和子类不能混为一谈就行了,随着你学习的进度,你慢慢的就会有体会的了!
            

作者: 尹旗龙    时间: 2012-2-10 07:25
创建对象是需要new关键字的,子类创建对象时并没有创建父类对象,只是父类成员变量也都分配了内存空间,且直接将子类有权继承的一部分作为子类对象成员变量,其它部分子类可通过调用继承的父类方法来操作它们,这样访问父类任何成员就很合理了
作者: 孙汇川    时间: 2012-2-10 09:14
应该是没有创建父类对象的,只是对父类进行了初始化操作,因为子类对象可能会调用父类的成员变量或者方法。构造函数初始化对象前先执行父类的构造函数,因为子类继承父类,父类里面的成员变量和成员函数就相当于子类里面的。子类需要知道里面的具体内容,所以先执行父类的构造函数。
你说父类没有创建对象就操作父类里面的成员变量和成员函数是非法的,这句话是不对的。因为是通过子类对象来调用父类的成员变量和函数,子类已经继承了父类的成员变量和函数,相当于自己类中的成员。
super只是方便于区分调用子父类一些成员。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2