Java规定:一个父类可以有多个子类,但是一个子类只有一个父类。子类通关键字extends继承父类。
//父类:
public class FatherClass {
int a=3;
FatherClass(){
System.out.println("父类无参构造函数");
}
FatherClass(int i){
System.out.println("有一个形参i");
}
FatherClass(int i, int j){
System.out.println("有两个形参i,j");
}
}
//子类:
class SonClass extends FatherClass{
int a;
int b;
public SonClass(){
System.out.println("123一起上");
}
public SonClass(int a){
this.a= a;
System.out.println("456一起上");
}
public SonClass( ){
super.(3,4);
}
public show(){
System.out.println("show 中!");
}
public static void main(String[] args) {
SonClass sc1 = new Sonclass (); //创建一个子类对象
FatherClass sc2 = new SonClass (); //父类引用指向子类对象
FatherClass sc3= new SonClass(3,4); //父类引用指向子类对象,调用含指定参数的子类构造方法
}
}
1.如果父类没有定义构造函数,系统会默认定义一个无参无返回值的构造函数,子类继承时无需(即可写可不写)在子类构造函数中显式调用super( );如果父类定义了有参构造函数,子类想调用父类的有参构造函数的话,必须在第一行必须显式调用。即,显式调用对应的参数个数、对应参数类型与此super( [arg0][,arg1]…. )的父类构造函数。
SonClass( ) 该子类构造函数实际上在函数类第一行隐式调用了父类无参构造函数super()
public SonClass(){
System.out.println("123一起上");
}
若子类的构造函数要调用父类的某个有参构造函数必须在第一行显示调用
如下:正确
public SonClass(){
super(5);
this.a = a;
System.out.println("456一起上");
}
如下:错误
public SonClass(){
this.a = a;
super(5); // 此父类构造函数调用应放在第一行
System.out.println("456一起上");
}
2.关于父类引用指向子类对象:
定义一个父类类型的引用指向一个子类的对象后,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,是无法调用的;
FatherClass sc2 = new SonClass( );
sc2.show( ) //会报错
子类对象可以向上转换,因为子类是父类的延伸,猫是动物的子类,猫是动物 。即:
SonClass sc4 = new SonClass();
FatherClass fc1 = (FatherClass) sc4;
也可以这样,fc1由子类对象向上转换成父类对象,再转换成子类对象sc5
SonClass sc4 = new SonClass();
FatherClass fc1 = (FatherClass) sc4;
SonClass sc5 = (SonClass) fc1;
从对象的内存角度来理解
假设父类FatherClass它的变量需要占用1M内存,它的子类对象SonClass的变量需要占用0.5M内存.
FatherClass f = new FatherClass(); //系统将分配1M内存.
SonClass s = new SonClass(); //系统将分配1.5M内存!因为子类中有一个隐藏的引用super会指向父类实例,所以在实例化子类之前会先实例化一个父类,也就是说会先执行父类的构造函数.由于s中包含了父类的实例,所以s可以调用父类的方法