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

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

  • 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.子类无论如何都会访问父类中的一个构造方法,因为要看父类如何去初始化的。

### Java 中继承构造方法的关系及用法 在 Java 编程语言中,继承是一种重要的面向对象特性,允许子类父类继承字段方法。当涉及到构造方法时,继承机制引入了一些特定的行为规则。 #### 子类构造器调用超类构造器 每当创建一个子类的对象时,Java 虁求该子类的构造函数必须显式或隐式地调用其直接父类的某个构造函数[^1]。如果未提供任何显式的 `super()` 或者 `this()` 调用,则编译器会自动插入一条默认的 `super()` 调用来初始化父类实例成员。这条语句总是位于子类构造函数的第一行[^4]。 ```java class Parent { public Parent(String message){ System.out.println(message); } } class Child extends Parent{ // 隐含 super("Child Constructor Called"); public Child(){ super("Parent Constructor Called First!"); } } ``` 上述代码展示了如何通过 `super` 关键字来指定要调用哪个父类构造函数。如果没有定义无参构造函数而只提供了带参数版本,在子类中就必须手动添加相应的 `super(...)` 呼叫以匹配合适的签名。 #### 默认情况下调用无参构造函数 假如父类有一个不接受任何参数的公共构造函数(即所谓的“无参构造函数”),那么即使你不写明 `super();`, 它也会被暗中执行作为第一步操作[^2]。然而一旦存在多个重载形式或者仅有有参构造可用的时候,你就得自己负责传递必要的实参给恰当的选择项了。 #### 注意事项 - 如果试图在一个类里面声明 final abstract 同时修饰的方法或者是整个类别本身的话,这将会违反逻辑因为final意味着不可改变/覆盖而abstract则正好相反它需要进一步实现细节所以两者互斥无法共存于单一实体之上. - 当设计包含抽象概念的数据结构体系时可以考虑构建层次型类型系统其中可能涉及最终版别的抽象基底依旧能够参与此类关系网路之中[^3]. 以下是综合以上要点的一个例子: ```java // 抽象父类 public abstract class Animal { private String name; protected Animal(String name) { this.name = name; } public void speak() { System.out.println(name + " makes a sound."); } public abstract void move(); } // 继承并具体化的子类 public class Dog extends Animal { public Dog(String name) { super(name); // 明确指定了父级构造器 } @Override public void move() { System.out.println(getName() + " walks on four legs."); } public static void main(String[] args) { Dog myDog = new Dog("Rex"); myDog.speak(); myDog.move(); } } ``` 在这个案例里我们看到dog类不仅实现了animal中的抽象方法move(),而且也利用constructor chain完成了name属性初始设定过程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

左绍骏

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

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

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

打赏作者

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

抵扣说明:

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

余额充值