继承
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。当我们在定义若干个类的时候,发现某一些类中具有相同的属性和行为,那么我们就可以将这些相同的部分进行抽取,独立生成另外一个类,那么这个生成出来的类我们称之为是父类,其他的被抽取内容的类称之为子类。
类的继承格式:
在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:
class 父类 {
}
class 子类 extends 父类 {//子类继承父类
}
继承类型
1.
2.
3.
注意:Java中并不支持多继承,一个子类不能有多个父类!!!!
子类与父类之间的关系
子类与父类之间必须符合一种is-a的关系,父类更通用,子类更具体
通常类与类之间必须有从属关系
在Java继承体系当中,所有类的最终父类都是Object!Object就不存在父类了,如果我们在定义一个类的时候,没有显著声明父类的时候 那么该类的父类默认是Object
子父类中成员变量/静态变量的特点
- 如果只有子类有且非私有 那么就调用子类的
- 如果只有父类有且非私有 那么就调用父类的
- 如果子父类都有且非私有 那么就调用子类的
子类.属性 顺序:子类对象成员->子类静态->父类成员->父类静态
子类成员函数在内部调用变量时 局部变量->子类对象成员->子类静态->父类成员->父类静态
子父类中成员函数的特点
- 如果只有子类有且非私有 那么就调用子类的
- 如果只有父类有且非私有 那么就调用父类的
- 如果子父类都有且非私有 那么就调用子类的(函数重写)
子父类中构造函数的特点
子类是不继承父类的者构造函数,它只是调用(隐式或显式)。如果父类的构造函数带有参数,则必须在子类的构造函数中显式地通过 super 关键字调用父类的构造函数并配以适当的参数列表。
如果父类构造函数没有参数,则在子类的构造函数中不需要使用 super 关键字调用父类构造函数,系统会自动调用父类的无参构造函数(隐式)。
注意:super语句必须在子类第一行。因为在子类构造函数之中,必须先让父类把这些数据进行一些初始化才能继承给子类。
问题:那么当子类存在多个构造函数时,super到底放在哪个构造函数的第一行呢?
首先我们要区分开:
this(...)是当前类中 本类构造函数调用本类构造函数的方式
super(...)是本类构造函数调用父类构造函数的方式如果本类构造函数当中不存在调用关系 那么每一个本类构造函数第一句都是super(...)
如果本类构造函数当中存在调用关系,那么最后被调用的那个构造函数第一句绝对是super(...)
class ExtendsDemo02{
public static void main(String[] args){
Zi zi=new Zi();
System.out.println(zi.num1);//20
System.out.println(zi.num2);//30
System.out.println(zi.num3);//50
}
}
class Fu {
int num1=10;
static int num2=40;
static int num3=50;
Fu(){
super();//Object(){} 显示初始化父类空间中的成员变量
System.out.println("Fu constructor1......");
}
Fu(int num){
System.out.println("Fu constructor2......");
}
}
class Zi extends Fu{
int num1=20;
static int num2=30;
//第一种:本类构造函数之间不存在调用关系,注意super关键字的位置
Zi(){
super();//!!
System.out.println("Zi constructor1......");
}
Zi(int num1){
super();//!!
System.out.println("Zi constructor2......");
}
Zi(int num1,int num2){
super();//!!
System.out.println("Zi constructor3......");
}
//第二种:本类构造函数之间存在调用关系,注意super关键字的位置
Zi(){
this(0,0);
System.out.println("Zi constructor1......");
}
Zi(int num1){
this(0,0);
System.out.println("Zi constructor2......");
}
Zi(int num1,int num2){
super();//!!
System.out.println("Zi constructor3......");
}
}