java构造器与继承

​ 目前看书正在学习java,怕好记性比不过烂笔头,遇到的一些东西还是记录一下比较好,方便日后查阅。

  • 谁能有构造器

    ​ 抽象类,普通类都可以用构造器,如果用户没有自定义一个构造器,那么编译器就会自动创建个啥也不做的构造器。如果用户定义了构造器,编译器就会把定义构造器的任务交给你,不会创建默认构造器。

  • 构造器重载

    ​ 编译器默认创建的构造器是无参数的,用户可以自己定义重载构造器。一个类不能有两个或以上相同的构造器,即参数列表不能够相同。

  • 构造器调用

    在类的声明时候就可以调用构造器,在方法内也可以调用构造器。抽象类不能够单独实例化,构造函数必须要跟在new关键字的后面才可以成功编译,但是特殊情况在于可以在构造函数里调用构造函数。比如以下代码

public class Duck{
	int size;
	public Duck(){
		this(0);
	}
	public Duck(int newSize){
		if (newSize == 0){
			size = 27;
		} else {
			size = newSize;
		}
	}
	

	public static void main(String[] args){
		Duck duck = new Duck();

		System.out.println(duck.size);
	}
}

构造器里调用构造器需要使用this关键字

  • 当有继承关系的子类开始实例化

    • 构造器调用顺序

      如果有父类,那么先调用父类的构造器,如果父类还有父类,那么调用父类的父类的构造器,以此类推。必须触底然后再一层一层的返回,也就是说最先完成的构造函数是最遥远的祖宗。

    • 如果父类是一个抽象类

      没错,抽象类也可以调用构造器为其分配空间,但要记住,抽象类的构造函数主要是给派生类实例化时使用,不能单独实例化。

      abstract class A{
      	int a;
      	void show(){
      		System.out.println(a);
      	}
      	abstract void doSuff();
      }
      class B extends A{
      	@Override
      	void doSuff(){
      		System.out.println("I will show the value of A");
      		show();
      	}
      
      	public static void main(String[] args){
      		B b = new B();
      		b.doSuff();
      	}
      }
      
      

      因为抽象类也需要空间去储存变量,所以需要构造函数去分配空间,在这里A所分配的空间在堆上属于B的一部分。

    • 如果父类有封装

      如果父类的某个变量用比如private修饰,当子类继承父类时,这个变量的开销还是得要子类承担,只不过子类无法访问这个变量,但这个变量是真实存在的。

    • 指定父类的构造函数

      如果想要在实例化一个类时指定父类怎么实例化(默认情况下是调用父类的无参数构造函数),使用super(参数列表)就行了

      abstract class A{
      	public A(int x){
      		a = x;
      	}
      
      	int a;
      	void show(){
      		System.out.println(a);
      	}
      	abstract void doSuff();
      }
      class B extends A{
      	public B(){
      		super(1);
      	}
      
      	@Override
      	void doSuff(){
      		System.out.println("I will show the value of A");
      		show();
      	}
      
      	public static void main(String[] args){
      		B b = new B();
      		b.doSuff();
      	}
      }
      
      

      如果把B的构造函数去掉,那么就会报错,报错的原因是因为编译器创建的默认的B构造函数是啥也不做的,不会去指定调用父类的构造函数,而是尝试调用父类的无参数构造函数,但是A并没有无参数构造函数。

posted @ 2022-05-19 15:15  可可苦力  阅读(90)  评论(1)    收藏  举报