黑马程序员技术交流社区

标题: 子类实例化 [打印本页]

作者: 高薇    时间: 2012-8-16 09:11
标题: 子类实例化
我想请教一下,为什么这个程序编译失败;
返回的错误提示是:对super的调用必须是构造器中的第一个语句super(name)
我知道这个程序该怎么改,只是不明白为什么,是因为子类只能调用一次父类的构造函数的关系吗?
还是因为对子类的初始化只能执行一次呢?

如果是这个原因的话,那为什么又提示只能是super(name)而不是super()呢?
求解答!*/
class Person
{
        Person()
        {
                System.out.println("Person");
        }
        String name;
        Person(String name)
        {
                this.name=name;
        }
}
class Student extends Person
{

        Student(String name)
        {
                super();
                super(name);
        }
}
class Jc6
{
        public static void main(String[] args)
        {
                Student s=new Student("gw");
                System.out.println(s.name);
               
        }
}
作者: 胡刚涛    时间: 2012-8-16 09:31
个人理解,在实例化对象时只能调用一个构造函数,你的代码就出现了两个构造函数的调用
class Person
{
         Person()
         {
                 System.out.println("Person");
         }
         String name;
         Person(String name)
         {
                 this.name=name;
         }
}
class Student extends Person
{

        Student(String name)
         {
                 super();
                 super(name);

         }
}
class Jc6
{
         public static void main(String[] args)
        {
                 Student s=new Student("gw");
                 System.out.println(s.name);
                 
        }
}
调用了两个构造函数!!!

作者: 官文昌    时间: 2012-8-16 09:31
class Person
{
        Person()
        {
                System.out.println("Person");
        }
        String name;
        Person(String name)
        {
                this.name=name;
        }
}
class Student extends Person
{

        Student(String name)
        {
                super();
                super(name);//super语句只能写在第一句,你这里两个super语句,请问怎么保证super在第一句呢???

        }
}
class Jc6
{
        public static void main(String[] args)
        {
                Student s=new Student("gw");
                System.out.println(s.name);
               
        }
}

作者: 黑马_许芸    时间: 2012-8-16 09:32
因为构造函数的作用就是为这个类构造一个对象。你在Student中调用了两次父类的构造函数显然就不对了。去掉super(); super(name);的任意一个都可以。
作者: 赵方明    时间: 2012-8-16 09:40
因为在子类Student的构造函数中,调用super();就表示你使用的是父类的不带参数的构造方法。你用super(name);就调用的是带参数的父类构造方法super(name);
这里你要用的是带参数的构造方法,所以只能是super(name);
super语句只能用在第一行,写两个不行
作者: 杨彪    时间: 2012-8-16 09:54
                     **子类的实例化过程
                                ***子类创建对象时,会先去创建父类的对象。
                                    默认是去调用父类的无参构造方法。
                                ***子类构造方法中,第一行默认是super()
                                ***为什么子类中第一行会默认有super()
                                        因为他继承父类的成员使用,使用前这些成员必须初始化,
                                        而他们是父类的成员,所以,必须通过父类进行初始化。
                                        所以,会先创建一个父类的对象。

作者: 杨健yj    时间: 2012-8-16 10:13
class Student extends Person
{

        Student(String name)
         {
                 super();
                 super(name);
         }
}

这里你调用了两次super的构造函数,显然不合适两点:1 supper语句必须放在第一行,两个supper无法都做到第一行冲突

                                                                                                 2        子类实例化父类的原因就是需要继承父类的成员,所以父类需要
                                                                                                        被实例化进而调用父类的构造函数,父类只实例化一次就可以了
                                                                                                        再者说两次实例化父类必然会有两个实例化的父类对象且两个实
                                                                                                        例对象的成员可能会不同,那么子类究竟继承那个呢?矛盾!!!
                                                                                                       
作者: 黄阔    时间: 2012-8-16 11:21
本帖最后由 黄阔 于 2012-8-16 11:23 编辑

在继承类构造法中 隐含有super关键字指向父类和this关键字指向自己  supper必须放在子类的第一行 如果没有显示调用子类会隐含调用super()父类没有参数的构造方法 显示调用只能唯一 还有你的最后问题 你可以换下位置

        class Person
        {
                Person()
                {
                        System.out.println("Person");
                }
                String name;
                Person(String name)
                {
                        this.name=name;
                }
        }
        class Student extends Person
        {
                /*Student()
        {
                          super();
                          super(name);
      
        }*/
               Student(String name)
                {
                  
                        super(name);
                        super();//Constructor call must be the first statement in a constructor
                }
        }
        
public class Test {


                public static void main(String[] args)
                {
                        Student s = new Student("nihao");
                        System.out.println(s.name);
                        
                }

}

作者: 童兴龙    时间: 2012-8-16 11:52
构造方法是在你new对象的时候就开始自动调用了。父类构造方法已经有一个带参数的就不会去找没有参数的构造方法了。因为你已经定义了自己的构造方法。没有构造才会创建不带参数的构造方法。

然后是构造方法就是为生成对象而存在的。
作者: 高薇    时间: 2012-8-16 14:51
黄阔 发表于 2012-8-16 11:21
在继承类构造法中 隐含有super关键字指向父类和this关键字指向自己  supper必须放在子类的第一行 如果没有 ...

是因为在主函数中调用的是有参构造函数的原因,另外super只能放在第一行
所以以上面只能调用super(name)吗?
可以这样理解吗?
作者: 黄阔    时间: 2012-8-16 16:28
因为你在父类里写了空参的构造方法(重载),而在子类里没有写空参的,因为你写了带参的构造方法在实例化的时会直接找你写的构造方法,所以在测试类中你调用是时只能调用有参的。不懂的话可以调代码,试。编译器会告诉你的。。你的理解我个人承认你是对的。
作者: 黄阔    时间: 2012-8-16 16:28
高薇 发表于 2012-8-16 14:51
是因为在主函数中调用的是有参构造函数的原因,另外super只能放在第一行
所以以上面只能调用super(name) ...

因为你在父类里写了空参的构造方法(重载),而在子类里没有写空参的,因为你写了带参的构造方法在实例化的时会直接找你写的构造方法,所以在测试类中你调用是时只能调用有参的。不懂的话可以调代码,试。编译器会告诉你的。。你的理解我个人承认你是对的。
作者: 高薇    时间: 2012-8-17 16:59
已经解决,谢谢你们!




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