继承中构造方法的注意事项

继承中构造方法的注意事项

  • A:案例演示
    • 父类没有无参构造方法,子类怎么办?
    • super解决
    • this解决
  • B:注意事项
    • super(…)或者this(….)必须出现在构造方法的第一条语句上

代码1:

class Demo06_Extends{
    public static void main(String[] args){
        Son s1 = new Son();
        System.out.println("----------");
        Son s2 = new Son("张三", 23);
    }
}

class Father{
    private String name;        //姓名
    private int age;            //年龄

    public Father(){            //空参构造
        System.out.println("Father 空参构造");  
    }

    public Father(String name, int age){    //有参构造
        this.name = name;
        this.age = age;
        System.out.println("Father 有参构造");
    }

    public void setName(String name){       //设置姓名
        this.name = name;
    }

    public String getName(){                //获取姓名
        return name;
    }

    public void setAge(int age){            //设置年龄
        this.age = age;
    }

    public int getAge(){                    //获取年龄
        return age;
    }
}

class Son extends Father{
    public Son(){
        super();                            //隐藏一个super(),系统默认自带
        System.out.println("Son 空参构造");
    }

    public Son(String name, int age){
        //隐藏一个super(),系统默认自带。
        //不会隐藏一个super(name, age);因为系统不知道他的属性是什么
        super();
        System.out.println("Son 有参构造");
    }
}

输出结果

代码2:

class Demo06_Extends{
    public static void main(String[] args){
        Son s1 = new Son();
        System.out.println("----------");
        Son s2 = new Son("张三", 23);
    }
}

class Father{
    private String name;        //姓名
    private int age;            //年龄

    //如果不写任何的构造,系统默认给一个无参构造
    //如果写了任何一个构造,系统就不会给构造方法
    /*public Father(){          //空参构造
        System.out.println("Father 空参构造");  
    }*/

    public Father(String name, int age){    //有参构造
        this.name = name;
        this.age = age;
        System.out.println("Father 有参构造");
    }

    private void setName(String name){      //设置姓名
        this.name = name;
    }

    private String getName(){               //获取姓名
        return name;
    }

    private void setAge(int age){           //设置年龄
        this.age = age;
    }

    private int getAge(){                   //获取年龄
        return age;
    }
}

class Son extends Father{
    public Son(){
        super();                            //隐藏一个super(),系统默认自带
        System.out.println("Son 空参构造");
    }

    public Son(String name, int age){
        //隐藏一个super(),系统默认自带。
        //不会隐藏一个super(name, age);因为系统不知道他的属性是什么
        super();
        System.out.println("Son 有参构造");
    }
}

输出结果

注意事项

父类中没有无参构造,只有有参构造如何处理?把父类的有参构造也注释?
注意事项
解决办法:用super(name, age);来解决

代码3:

class Demo06_Extends{
    public static void main(String[] args){
        Son s1 = new Son();
        System.out.println(s1.getName() + "---" + s1.getAge());
        System.out.println("----------");
        Son s2 = new Son("张三", 23);
        System.out.println(s2.getName() + "---" + s2.getAge());
    }
}

class Father{
    private String name;        //姓名
    private int age;            //年龄

    //这样做不好,别人的类都写完了,没有加无参构造,只有一个有参构造
    //如果别人不是提供的源码,而是字节码文件,那样就不能修改了,只能修改自己的类

    /*public Father(){          //空参构造
        System.out.println("Father 空参构造");  
    }*/

    public Father(String name, int age){    //有参构造
        this.name = name;
        this.age = age;
        System.out.println("Father 有参构造");
    }

    public void setName(String name){       //设置姓名
        this.name = name;
    }

    public String getName(){                //获取姓名
        return name;
    }

    public void setAge(int age){            //设置年龄
        this.age = age;
    }

    public int getAge(){                    //获取年龄
        return age;
    }
}

class Son extends Father{
    public Son(){
        super("李四", 24);                    //隐藏一个super(),系统默认自带
        System.out.println("Son 空参构造");
    }

    public Son(String name, int age){
        //隐藏一个super(),系统默认自带。
        //不会隐藏一个super(name, age);因为系统不知道他的属性是什么
        super(name, age);
        System.out.println("Son 有参构造");
    }
}

输出结果

代码4:

class Son extends Father{
    public Son(){
        //隐藏一个super(),系统默认自带
        //super("李四", 24);              //调用父类中的构造方法
        //this与super为平行关系,只能存在一个
        this("李四", 24);             //调用本类中的构造方法
        System.out.println("Son 空参构造");
    }

    public Son(String name, int age){
        //隐藏一个super(),系统默认自带。
        //不会隐藏一个super(name, age);因为系统不知道他的属性是什么
        super(name, age);
        System.out.println("Son 有参构造");
    }
}

输出结果

注意事项:子类无论如何都会访问父类中的一个构造方法

class Son extends Father{
    public Son(){
        this("李四", 24);
        System.out.println("Son 空参构造");
    }
    public Son(String name, int age){
        this();
        System.out.println("Son 有参构造");
    }
}

输出结果

注意事项:

1.父类无无参构造,子类可以用super(xxx)来解决。

2.this与super为平行关系,只能存在一个。

3.子类无论如何都会访问父类中的一个构造方法,因为要看父类如何去初始化的。

<think> 我们正在讨论构造方法注意事项,根据引用内容,我们可以总结如下: 引用[1]提到: 1. 构造方法名称必须类名完全相同(包括大小写) 2. 不写返回值类型(连void也不写) 3. 不能return一个具体的返回值 4. 如果没有编写构造方法,编译器会默认提供一个无参构造方法(方法体为空) 5. 如果编写了至少一个构造方法,编译器将不再提供默认的无参构造方法 引用[2]补充: 1. 如果没有定义构造方法,系统会提供默认的无参构造方法;如果定义了,则不再提供,因此通常建议手动写上无参数构造方法 2. 构造方法可以重载(即多个构造方法,参数列表不同) 3. 推荐无论是否使用,都手写无参数构造方法带全部参数的构造方法 引用[3]虽然讲的是JavaScript,但Java中构造方法也有类似特点:构造方法用于创建对象并初始化属性,使用this关键字给属性赋值。 引用[4]提到了继承中的构造方法注意事项: 1. 子类构造方法默认调用父类的无参构造方法 2. 如果父类没有无参构造方法,则需要在子类构造方法中显式用super调用父类的有参构造方法,否则会出错 引用[5]强调了: 1. 构造方法只能通过new关键字调用,不能通过对象调用 2. 构造方法没有返回值,也不能使用void(否则就变成了普通方法) 3. 构造方法名称与类名相同,一个类可以有多个构造方法(重载) 4. 重载:方法名相同,参数列表不同(类型、个数、顺序) 5. 使用this区分成员变量局部变量 综合以上引用,我们可以将构造方法注意事项归纳为以下几个方面: 1. **命名规范**:构造方法名称必须与类名完全相同(包括大小写)[^1][^5]。 2. **返回值**:不能声明返回值类型(包括void),也不能用return返回具体值[^1][^5]。 3. **默认构造方法**: - 当类中没有显式定义任何构造方法时,编译器会自动提供一个默认的无参构造方法(方法体为空)[^1][^2]。 - 一旦显式定义了至少一个构造方法,编译器不再提供默认构造方法,因此需要时需手动添加无参构造方法[^1][^2]。 4. **构造方法重载**: - 一个类可以有多个构造方法,通过参数列表不同(类型、个数、顺序)实现重载[^5]。 - 推荐同时提供无参构造方法全参构造方法,以增加灵活性[^2]。 5. **继承中的构造方法**: - 子类构造方法默认调用父类无参构造方法(即隐式调用`super()`)[^4]。 - 若父类没有无参构造方法,必须在子类构造方法中显式调用父类的有参构造方法(使用`super(参数)`)[^4]。 6. **调用方式**:构造方法只能通过`new`关键字调用,不能通过对象实例调用[^5]。 7. **this关键字的使用**: - 在构造方法中,可以使用`this()`调用本类的其他构造方法(注意避免循环调用)[^5]。 - 当成员变量与局部变量同名时,用`this.成员变量`区分[^5]。 下面用代码示例说明一些注意事项: **示例1:无参构造方法全参构造方法** ```java public class Person { private String name; private int age; // 无参构造方法(推荐显式写出) public Person() { } // 全参构造方法(推荐) public Person(String name, int age) { this.name = name; this.age = age; } // 还可以有其他重载的构造方法,比如只初始化name public Person(String name) { this.name = name; } } ``` **示例2:继承中的构造方法调用** ```java public class Animal { private String type; // 如果只有带参构造方法,没有无参构造方法 public Animal(String type) { this.type = type; } } public class Dog extends Animal { private String name; // 父类没有无参构造方法子类必须显式调用父类的有参构造方法 public Dog(String type, String name) { super(type); // 必须放在第一行 this.name = name; } } ``` **示例3:使用this调用本类其他构造方法** ```java public class Rectangle { private int width; private int height; // 无参构造方法调用有参构造方法,提供默认值 public Rectangle() { this(10, 10); // 调用下面的有参构造方法 } public Rectangle(int width, int height) { this.width = width; this.height = height; } } ``` 注意事项: - 使用`this()`调用本类其他构造方法时,必须放在构造方法的第一行[^5]。 - 避免递归调用(如:在一个构造方法调用自身,会导致无限递归)。 总结:构造方法是创建对象并初始化对象状态的特殊方法,正确使用构造方法需要遵循上述规则,尤其在继承关系中要特别注意父类构造方法调用方式。 §§相关问题§§ 1. 构造方法中为什么不能有返回值类型? 2. 在继承中,如果子类没有显式调用父类构造方法会发生什么? 3. 构造方法与普通方法的主要区别是什么? 4. 如何在构造方法中避免代码重复? </think> ### 构造方法注意事项总结 根据引用内容,构造方法注意事项可归纳为以下核心要点: #### 1. **命名与格式规范** - 构造方法名称**必须与类名完全一致**(包括大小写)[^1][^2][^5] - 不能声明返回值类型(包括`void`),也不允许使用`return`返回值[^1][^5] - 使用`this`关键字区分成员变量与局部变量(如`this.name = name`)[^3][^5] #### 2. **默认构造方法规则** - 未显式定义构造方法时,编译器**自动提供默认无参构造方法**(方法体为空)[^1][^2][^5] - 显式定义任何构造方法后,编译器**不再提供默认构造方法**[^1][^2][^5] - 推荐始终手动添加无参构造方法,即使已有带参构造方法[^2] #### 3. **调用限制** - 只能通过`new`关键字调用,**禁止通过对象实例调用**[^5] ```java // 正确用法 Person p = new Person(); // 错误用法(编译报错) p.Person(); ``` #### 4. **重载要求** - 支持构造方法重载(相同方法名,不同参数列表)[^2][^5] - 参数差异需体现在类型、数量或顺序上[^5] ```java public class Student { // 无参构造 public Student() {} // 带参构造(重载) public Student(String name) { this.name = name; } } ``` #### 5. **继承中的特殊规则** - 子类构造方法默认调用父类**无参构造方法**[^4] - 父类无无参构造时,子类必须显式用`super`调用父类有参构造[^4] ```java public class Parent { public Parent(int id) {...} // 只有带参构造 } public class Child extends Parent { public Child() { super(1001); // 必须显式调用父类构造 } } ``` #### 6. **初始化顺序** - 构造方法用于**对象初始化**,应先于普通方法调用[^5] - 可通过`this()`调用本类其他构造方法(需放在方法首行)[^5] ```java public class Rectangle { private int width, height; public Rectangle() { this(10, 10); // 调用带参构造 } public Rectangle(int w, int h) { this.width = w; this.height = h; } } ``` #### 7. **访问控制** - 可设置访问修饰符(如`public`/`protected`/`private`) - 私有构造方法常用于单例模式: ```java public class Singleton { private static Singleton instance; private Singleton() {} // 禁止外部实例化 public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } } ``` > 关键原则:构造方法的核心作用是**创建对象实例并初始化状态**,通过严格规范保证对象创建的合法性安全性[^1][^4][^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

左绍骏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值