传智播客旗下技术交流社区北京校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 高薇 中级黑马   /  2012-8-16 09:11  /  1808 人查看  /  12 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

我想请教一下,为什么这个程序编译失败;
返回的错误提示是:对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);
               
        }
}

评分

参与人数 1技术分 +1 收起 理由
张立江 + 1 赞一个!

查看全部评分

分享至 : QQ空间
收藏

12 个回复

倒序浏览
个人理解,在实例化对象时只能调用一个构造函数,你的代码就出现了两个构造函数的调用
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);
                 
        }
}
调用了两个构造函数!!!
回复 使用道具 举报
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);
               
        }
}
回复 使用道具 举报
因为构造函数的作用就是为这个类构造一个对象。你在Student中调用了两次父类的构造函数显然就不对了。去掉super(); super(name);的任意一个都可以。
回复 使用道具 举报
因为在子类Student的构造函数中,调用super();就表示你使用的是父类的不带参数的构造方法。你用super(name);就调用的是带参数的父类构造方法super(name);
这里你要用的是带参数的构造方法,所以只能是super(name);
super语句只能用在第一行,写两个不行
回复 使用道具 举报
                     **子类的实例化过程
                                ***子类创建对象时,会先去创建父类的对象。
                                    默认是去调用父类的无参构造方法。
                                ***子类构造方法中,第一行默认是super()
                                ***为什么子类中第一行会默认有super()
                                        因为他继承父类的成员使用,使用前这些成员必须初始化,
                                        而他们是父类的成员,所以,必须通过父类进行初始化。
                                        所以,会先创建一个父类的对象。
回复 使用道具 举报
class Student extends Person
{

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

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

                                                                                                 2        子类实例化父类的原因就是需要继承父类的成员,所以父类需要
                                                                                                        被实例化进而调用父类的构造函数,父类只实例化一次就可以了
                                                                                                        再者说两次实例化父类必然会有两个实例化的父类对象且两个实
                                                                                                        例对象的成员可能会不同,那么子类究竟继承那个呢?矛盾!!!
                                                                                                       
回复 使用道具 举报
本帖最后由 黄阔 于 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);
                        
                }

}

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

回复 使用道具 举报
构造方法是在你new对象的时候就开始自动调用了。父类构造方法已经有一个带参数的就不会去找没有参数的构造方法了。因为你已经定义了自己的构造方法。没有构造才会创建不带参数的构造方法。

然后是构造方法就是为生成对象而存在的。
回复 使用道具 举报
黄阔 发表于 2012-8-16 11:21
在继承类构造法中 隐含有super关键字指向父类和this关键字指向自己  supper必须放在子类的第一行 如果没有 ...

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

因为你在父类里写了空参的构造方法(重载),而在子类里没有写空参的,因为你写了带参的构造方法在实例化的时会直接找你写的构造方法,所以在测试类中你调用是时只能调用有参的。不懂的话可以调代码,试。编译器会告诉你的。。你的理解我个人承认你是对的。
回复 使用道具 举报
已经解决,谢谢你们!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马