本文讲的是有继承关系的两个类之间,使用构造器的细节。在看之前,请确定你已经了解了“构造器”和“继承”基础的语法知识。
如果你对构造器和继承比较了解,可以直接跳过前面的基本介绍,直接看后面的继承中构造器的使用即可。
先简单介绍一下构造器基础:构造器是一个类在实例化(创建)一个对象的时候,给对象初始化的一个特殊方法。打个比方:
public class temp {
public static void main(String[] args) {
//创建一个person对象,并初始化对象的name 和 age
Persjson person = new Person("jack",18);
}
}
class Person {
String name;
int age;
//带有两个参数的构造器
public Person(String name , int age){
this.name = name;
this.age =age;
}
}
这里就是运用两个参SEVhdCskc数的构造器初始化了一个对象,当然你可能会想,如果我写Person(String name , int age)构造器,那么在创建方法的时候是不是就不会使用构造器了?
答案是:当然不会,如果我们不定义构造器,那么类里面默认有一个无参构造器,顾名思义就算没有参数的构造器,在创建对象的时候不对其进行初始化。但是这个构造器是存在的,只是没什么用。
而且这个无参构造器在我们定义了一个有参数的构造器之后就被覆盖了(直接无了),此时如果我们再直接 进行无参创建,就会报错。

如果我们还想使用无参构造器,那么就需要在类中显式声明一下即可
class Person {
String name;
int age;
//显式声明无参构造器
public Person(){
}
//带有两个参数的构造器
public Person(String name , int age){
this.name = name;
this.age =age;
}
}
当然说这么多,你只需要知道一条:在创建对象的时候一定会调用一次构造器,不管是无参的还是有参的。
然后是关于继承的,这里也简单说一下:继承就是一个类(子类)通过 extend 来使其具备所继承类(父类)的属性与成员方法。
打个比方,我有两个类:Person,Doctor。其中Person有属性name,age。Doctor里面也有name和age。我们就可以让Doctor继承Perosn来获得其属性。
再或者Pupil(小学生)和Gratuation(大学生)有很多共同属性,我们可以创建一个父类Student让二者继承父类,来提高代码复用性。
//父类 Student
class Student {
编程客栈 public String name;
public int age;
public double score;
}
//子类 Pupil
class Pupil extends Student {
//其拥有父类Student里面的所有属性
}
//子类Gratuate
class Gratuate extends Student{
//其拥有父类Student里面的所有属性
}
OK,现在www.devze.com进入正题,现在我们有一个子类Son,一个父类Base。Son继承了Base里面的属性和成员方法
//父类
class Base {
//显式声明一下无参构造器
public Base() {
System.out.println("父类Base中的构造器Base()被调用");
}
}
//子类
class Son extends Base {
public Son() {
//显式声明一下无参构造器
System.out.println("子类Son的构造php器Son()被调用");
}
}
//主程序
public class Run {
public static void main(String[] args) {
Son son = new Son();
}
}Public
现在我们创建了一个Son类,这时候程序会有以下输出

我们就可以得到第一个特点:子类对象必须调用父类的构造器,完成初始化。
即在new Son()的时候,在Son的构造器初始化之前需要先调用父类的构造器。当父类中的无参构造器存在的时候,这个过程可以自动进行,不需要我们手动调用。
那么如果父类的无参构造器被覆盖了,会发生什么?如果父类没有无参构造器,我们就会发现我们还按照上面的写代码,编译是不通过的。
class Son extends Base {
public Son() {
//编译不通过
System.out.println("子类Son的构造器Son()被调用");
}
}
class Base {
public Base(int n1) {
System.out.println("父类Base中的构造器Base(int n1)被调用");
}
}
因为此时系统不知道要调用父类中的那个构造器,所以此时需要我们手动填写调用父类中的那个构造器即:
如果父类中的无参构造器被覆盖了,而我们也没有显式无参构造器。那么在子类调用构造器的时候,必须要使用 super() ;方法指明要使用父类中的那个构造器进行初始化。
class Son extends Base {
public Son() {
super(2);//使用 Base(int n)构造器,传入一个int
System.out.println("子类Son的构造器Son()被调用");
}
class Base {
public Base(int n1) {
System.out.println("父类Base中的构造器Base(int n1)被调用");
}
需要特别注意的是:super方法只能放在构造器的第一行。
总结一下就是:
1.子类对象必须调用父类的构造器,完成初始化。
2.如果父类中的无参构造器被覆盖了,而我们也没有显式无参构造器。那么在子类调用构造器的时候,必须要使用 super() ;方法指明要使用父类中的那个构造器进行初始化。
到此这篇关于Java继承关系中构造器的使用详解的文章就介绍到这了,更多相关java构造器使用内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
加载中,请稍侯......
精彩评论