Java初学者 -- 继承中的构造方法

Java的每个类都必须有自己的构造方法,若是没有显式的用代码写出来,则系统会默认一个空的构造方法。在继承中,子类同样要有自己的构造方法,但必须遵循如下规则:

  1. 子类的构造过程中必须调用其父类的构造方法;
  2. 子类可以在自己的构造方法中使用super(argument_list)调用其父类的构造方法;
  3. 子类可以在自己的构造方法中使用this(argument_list)调用自己的其它构造方法;
  4. 如果调用super(argument_list),this(argument_list),必须写在子类构造方法的第一行; 
  5. 如果子类构造方法中没有显式地调用父类构造方法,则系统默认调用基类无参数构造方法;
  6. 如果子类构造方法中既没有显式地调用父类构造方法,而父类中又没有无参构造方法,则编译出错;
  7. 并不是每个子类的构造方法都必须显式地调用父类构造方法,可以通过this(argument_list)调用自己的有调用父类构造方法的其它构造方法。

我们先来看看一段未调用父类构造方法的错误的代码:

// 未调用父类构造方法的错误代码
class Person{
	
	Person(String n){
		System.out.println("Person: String n");
	}
}

class Student extends Person {
		
	Student(String n){
		System.out.println("Student: String n");
	}
}

public class SuperClassTestErr1 {
	public static void main(String[] args){
		Person p1 = new Person("p1");
		Student s1 = new Student("s1");
		
	}
}

编译,系统报错:

在子类构造方法中调用父类构造方法即可修正:

//修正错误的代码
class Person{
	
	Person(String n){
		System.out.println("Person: String n");
	}
}

class Student extends Person {
		
	Student(String n){
		super(n); //调用父类构造方法
		System.out.println("Student: String n");
	}
}

public class SuperClassTestErr1 {
	public static void main(String[] args){
		Person p1 = new Person("p1");
		Student s1 = new Student("s1");
		
	}
}

在学习的过程中,网上一般都只说前面几个规则,说得最多的是第5,6两个规则,一个简单的理解就是:子类构造函数一定要调用父类构造函数,否则会编译出错。但在学习过程中,出现了疑惑,见如下代码:

代码 一(通过其它构造函数调用父类构造函数):

public class TestSuperSub {
	public static void main(String[] args){
		Person p1 = new Person("P1");
		Person p2 = new Person("P2","ShangHai");
		Student s1 = new Student("s1","school1");
		Student s2 = new Student("s2","Shanghai","school2");
	
		System.out.println(p1.info());
		System.out.println(p2.info());
		System.out.println(s1.info());
		System.out.println(s2.info());
	}
	
}

class Person {
	private String name; 
	private String location;
	
	Person(String name) {
		this.name = name;
		location = "beijing";
	}
	
	Person(String name, String location) {
		this.name = name; 
		this.location = location;
	}
	
	public String info(){
		return "name: "+name+ "  location: "+location;
	}
}

class Student extends Person {
	private String school;
	
	Student(String name, String school) {
		this(name,"beijing",school);
	}
	
	Student(String n, String l, String School){
		super(n,l);
		this.school = school;
	}
	
	public String info(){
		return super.info()+"  school: "+school;
	}
}

该代码能编译成功,也能正确运行,但其中Student的构造方法并未显式地调用父类构造方法,为何没错呢:

Student(String name, String school) {
		this(name,"beijing",school);
	}

再看看另一段代码:

代码 二(通过其它构造函数调用父类构造函数)
public class SuperClassTest {
    public static void main(String args[]){
        B aB = new B("3");
    }
}
 
class A{
	private String a1;
	
	// A(){
		// System.out.println("A");
	// } 
    
	A(String s) {
		a1 = s;
        System.out.println(a1);
    }
	
	A(String s1, String s2){
		System.out.println(s1+s2);
	}
}
 
class B extends A{
	private String b1;
	private String b2;
	private String b3;
	
	B(String b1){
		super(b1);
		System.out.println(b1);
	}
    // B(int i) {
		// super("i");
		// System.out.println("B");
        // System.out.println(i);
    // }
	
	B(String b1,String b2){
		//super(b1,b2);
		this(b1);
		b2 = b2;
	}
	
	B(String b1, String b2, String b3){
		this(b1,b2);
		b3 = b3;
	}
}

这段代码中的子类B共有三个构造函数,后两个函数也没有调用父类构造函数,并且父类也没有定义空构造函数。但这段代码同样通过编译。

其原因是:

B(String b1, String b2, String b3)第1行调用了子类本身构造函数this(b1,b2)

B(String b1, String b2)第1行调用了子类本身构造函数this(b1)

而B(String b1)第1行调用了父类构造函数super(b1)

由上可知:

并不是每个子类的构造方法都必须显式地调用父类构造方法,可以通过this(argument_list)调用自己的有调用父类构造方法的其它构造方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值