子类构造中有使用父类属性
public class Animal {
int a;
Animal (int a){ //看到这里要想到,此时有参构造已经代替了默认的无参构造,并且该构造方法只能在本包中的类类名创建对象
this.a = a;
System.out.println("Animal类的有参构造");
}
}
class Bird extends Animal{
int b;
Bird(int b,int a){
super(a);
this.b = b;
System.out.println("Bird extends Animal类 , Bird 是有参构造");
}
/**
* 编译阶段,程序会去先调用父类当中的构造器,如果此时父类的无参构造被有参覆盖,
* 因为程序它只知道它要调用的是无参构造,没有告知程序无参已经被我们改为了有参
* 所以,子类在写构造方法时候会报错
* 所以,可以在子类构造这里告诉程序,说让它执行父类当中的有参构造,也就是在子类构造中引入父类当中属性
* 让它执行父类当中的有参构造肯定是: super(属性) 现在假如这个属性是a
* 但是,这个super(属性)中这个属性的值,怎么来
* (不要忘记此时,这个super是放在了子类当中的)
* a/属性肯定是父类当中的属性a,父类当中的属性是int类型,所以子类构造要传入一个int类型的a
*
*/
}
class Cat extends Bird{
int c;
Cat(int c,int a,int b){
super(a,b);
this.c =c;
System.out.println("Cat extends Bird类 , Cat 是有参构造");
}
}
再比如
public class A {
int x;
A(int inf){
x = inf;
}
void method(){
System.out.println("A类当中的方法,值是"+x);
}
}
class B extends A{
double x; //子类与父类存在相同的属性名
B(int a,double b){
super(a); //调用A类的构造方法
x = b;
}
}
/**
* B(int a,double b){
* super(a);
* x = b;
*
* 把super(a) ,int a 带入变成super(int a)这个就有点类似于构造方法,
* 只不过构造方法的名字是类名,这里是在子类中调用了父类的构造方法,把名字改为了super而已
*/
如果父类没有无参的构造函数,需要子类在自己的构造函数中显示的调用父类的构造函数,即不能使用系统默认的“super()”,而需要显性写出super(xxx)