目录
继承的由来:
当我们在定义若干个类的时候,发现某一些类中具有相同的属性和行为,那么我们就可以将这些相同的部分进行抽取,独立生成另外一个类,那么这个生成的类称之为父类,其他的被抽取内容的类称为子类。子类与父类之间就是所谓的继承关系,用extends表示。
那么在现实生活中,父与子之间的一对多 还是多对多的关系? 一对多。所以 在Java当中,继承是单继承(一个子类只能有一个父类,但是一个父类可以有若干个子类)。当然,在C++中,继承是多继承的,不太符合实际的社会问题,所以Java更加符合现实编程。但是不代表Java当中就没有多继承的时候!如果是类与类之间,必须是单继承;如果是接口与接口之间,可以是多继承。
既然有了继承,那么在Java当中就有了继承体系(既然有了父子关系,是不是就产生出了族谱这个东西)?
先说一点:我们常用的继承体系、异常体系、集合体系、IO体系、网络体系、多线程体系 C->B->A->?->?->龙的传人/炎黄子孙 C就是B的儿子,那么A就是C的爷爷。
注意一点:在分析设计继承的时候 一定要符合社会常识问题:子类和父类之间必须是 is a 关系;子类必须是父类的一种、同一系列的。she is a Girl ; he is a boy ; he is a ladyboy ; 旺财 is a Dog 所以,千万不要为了获取某一个类的功能而把这个类叫爸爸!
class ExtendsDemo01{
public static void main(String[] args){
}
}
class Bird extends Ainmal{
void fly(){}
}
class Ainmal{ // extends Object
String name;
int age;
void eat(){}
}
class Student extends Bird{
void study(){}
}
class Worker extends Ainmal{
void work(){}
}
子父类中成员变量/静态变量的特点:
- 如果只有子类有且非私有 那么就调用子类的
- 如果只有父类有且非私有 那么就调用父类的
- 如果子父类都有且非私有 那么就调用子类的(成员变量之间 是不存在重写关系的!!!)
子类.属性 顺序:子类对象成员->子类静态->父类成员->父类静态
子类成员函数在内部调用变量时 局部变量->子类对象成员->子类静态->父类成员->父类静态子父类中成员函数的特点:
- 如果只有子类有且非私有 那么就调用子类的
- 如果只有父类有且非私有 那么就调用父类的
- 如果子父类都有且非私有 那么就调用子类的(函数重写)
函数重写:在子父类中,同名函数
函数有什么组成:函数声明(权限 类型 返回值类型 函数名 参数列表)+函数体({}里面的内容)
重写的意义在于子类继承了父类的函数声明(功能),但是子类可以将该函数的具体实现进行优化或更改举个例子:郭德纲会说相声,郭麒麟也会说相声------子承父业!
1.保留父类的功能声明 子类可以进一步优化
2.保留父类的功能声明 子类可以重新定义
重写当中应该注意到的一些细节:
1.函数重名 但是参数列表不同 不构成重写关系
2.函数重名 参数列表相同 构成重写关系 返回值类型也必须是一样的
3.子类重写父类函数时,权限>=父类权限
4.当然 如果父类函数权限为private 子类压根就继承不到 何谈重写
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
zi.show();
zi.sing();
}
}
//子父类中成员变量的特点
/*
class Grandfather{
int num1=100;
int num4=200;
}
*/
class Fu {//extends Grandfather{
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......");
}
void sing(){
System.out.println("Fu sing......");
System.out.println("爸爸我会唱红歌");
}
}
class Zi extends Fu{
int num1=20;
static int num2=30;
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......");
}
void show(){
//局部变量和成员变量如果重名了 this区分
System.out.println(num1+","+num2+","+num3);
//局部变量/成员变量和父类变量重名了 super区别 super.xxx => 你爸爸的xxx
System.out.println(super.num1+","+super.num2+","+num3);
//System.out.println(super.super.num1);
//System.out.println(num4);
}
@Override
void sing(){
System.out.println("Zi sing......");
System.out.println("儿子我会唱摇滚、民谣、爵士、蓝调、电子");
}
}
图解: