面向对象 -- 继承和Java中的构造器

1.构造器实际上和类与对象是分不开的,当然和继承也有很大的关系。构造器在我看来就是将类实例化的过程

构造器最大的用处就是在创建对象时执行初始化,当创建一个对象时,系统会为这 个对象的实例进行默认的初始化。如果想改变这种默认的初始化,就可以通过自定义构造器来实现。 –百度百科

2.构造器分为两种,缺省构造器和非缺省构造器。当你创建一个类时,如果没有自己去写构造器,编译器会自动生成一个默认的构造器。但是如果你自己创建了构造器,编译器就不会再生成默认的构造器了。一个类可以有多个构造器,一个类的构造器的名称必须与该类的名称一致。要退出构造,可以使用返回语句“return;”。

3.缺省构造器:生成的是无参构造器

4.在具有继承关系的类中,如果父类只有有参构造器,子类也必须生成对应的有参构造器,且必须强制在该构造器中调用父类的构造器(看下面的代码就知道了)

但是实际应用中,可能最坑的就是在继承关系中的构造器使用了

上代码

import java.util.Date;

public class Father {

    private String name;

    private Date birth;

    public Father(String name, Date birth) {
        this.name = name;
        this.birth = birth;
        System.out.println("father's constructor");
    }
}

import java.util.Date;

public class Son extends Father {

    private String name;

    private Date birth;

    public Son(String name, Date birth) {
        super(name, birth);
        this.name = name;
        this.birth = birth;
        System.out.println("son's constructor");
    }
}

之后是第一次的测试代码

import java.util.Date;

public class Run {

    public static void main(String[] args) {

        Date d = new Date();

        Son son = new Son("jack", d);

        Father father = new Son("eric", d);

        System.out.println(father.getName());
    }
}

控制台输出

father’s constructor
son’s constructor
father’s constructor
son’s constructor
eric

其实不管是第一种生成对象的方式还是第二种向下转型生成对象的方式,结果都会调用父类的构造器

但是如果反过来使用向上造型

Son son = (Son)new Father("jack", d);

是会报错的,因为实际上Father类的构造器并没有调用Son类的构造器。即使强制转换类型,Son的构造器没有被调用,所以是一定会报错的。换句话说——

在创建对象的时候,其父类的构造器也一定会被调用

但是因为这个例子里子类在构造器中已经调用了父类的构造器,所以不够直观。继续看下面的例子

上代码2

import java.util.Date;

public class Mother {

    private String name;

    private Date birth;

    private int num = 1;

    public Mother() {
        System.out.println("mother's constructor");
        num++;
    }

    public Mother(String name, Date birth) {
        this.name = name;
        this.birth = birth;
        System.out.println("mother's constructor with parameter");
    }

    public int getNum() {
        return num;
    }

}


import java.util.Date;

public class Girl extends Mother {

    private String name;

    private Date birth;


    public Girl() {
        System.out.println("girl's constructor");
    }

    public Girl(String name, Date birth) {
        this.name = name;
        this.birth = birth;
        System.out.println("girl's constructor with parameter");
    }

    public int getNum() {
        return super.getNum();
    }
}

如果在父类中创建了无参构造器,那么在子类中就不再强制要求生成构造器了,因为即使没有构造器编译时也会加上无参构造器,实际上仍然符合规范,父类中有的构造器子类中也有其中一个或多个

测试代码:

import java.util.Date;

public class Run {

    public static void main(String[] args) {

        Date d = new Date();     

        Girl girl = new Girl();                //step1

        Mother mother = new Girl();            //step2

        Girl girl2 = new Girl("lily", d);      //step3

        Mother mother2 = new Girl("amy", d);   //step4

        System.out.println(girl2.getNum());    //step5

    }
}

step1和step2的结果其实是可以根据上一个例子猜出来的,虽然子类的无参构造器中没有调用父类的无参构造器,

但是


结果确实是这样

mother’s constructor
girl’s constructor
mother’s constructor
girl’s constructor

在创建Girl的对象的时候,Mother类的构造器依然被调用了

所以其实子类如果没有调用父类中的某一个构造器,在被编译的时候会在构造器内的第一句加上

super();

这样就会默认调用父类的无参构造器了。
所以其实step345的答案也可以很容易就想到了

mother’s constructor
girl’s constructor with parameter
mother’s constructor
girl’s constructor with parameter
2

Girl的有参构造器也一样调用了Mother的无参构造器。

以上就是继承和构造器

ok~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值