1继承
1.1继承的概念:
用来表达概念上具体化延续的具体概念。
看图:红箭头是继承,蓝色是共有的属性和方法
是生物就会有新城代谢,动物是生物的的一种所以动物继承于生物,动物有分很多种(哺乳动物,爬行动物等),所以哺乳动物继承动物,哺乳动物又有很多种(狗啦,灵长类啦等),所以灵长类和狗又继承于哺乳动物,灵长类动物又很多种.............这里就不多说。
所以说,像“生物”就是一种概念,“动物“就比生物要生物更具体,是生物一种延续的具体概念。
1.2继承的特点
- 子类拥有父类的属性和方法,但父类不会有子类的属性和方法
- 构造器不能继承
- 实例化子类,会递归分配多有父类的空间
- 子类构造器一定调用父类构造器(都没写时,编译器会默认提供)
- 类一定有构造器
如何来声明一个类继承呢
例:
/*动物类*/
class Animal{
String type; //动物有的属性
public void call(){ //动物都有的行为(叫)
System.out.println(type+"在叫");
}
}
dog类继承Animal
/*狗类*/
class Dog extends Animal{ //狗是动物的一种,所以狗继承动物,在类名后用extends关键字,后面接要继承的类的类名
}
main:
public static void main(String[] args) {
Dog dog = new Dog();
//可以调用父类的属性和方法
dog.type = "小狗";
dog.call(); //输出:小狗在叫
}
在dog实例化化后,就可以调用父类的属性和方法了
但是父类不会有子类的方法和属性
例:在Dog中增加一些属性和函数
/*狗类*/
class Dog extends Animal{ //狗是动物的一种,所以狗继承动物,在类名后用extends关键字,后面接要继承的类的类名
//dog自己的一些属性
String color;
String hair;
//dog自己的一些行为
public void eat(){
System.out.println(color+hair+"的狗正在咬骨头");
}
}
main:
public static void main(String[] args) {
Dog dog = new Dog();
//可以调用父类的属性和方法
dog.type = "小狗";
dog.call(); //输出:小狗在叫
Animal animal = new Dog();
animal.color = "黄色";//这里会编译报错
animal.eat();
}
在编译到animal.color=“黄色”,时就会编译报错
内存模型:
1.3继承的初始化
- 先创建父类,在创建子类
- 默认不带参数构造器
- 当父类仅有带参数的构造器时,需要在子类构造器第一行添加supe,表示调用父类构造器
例:在Animal添加了一个带参数的构造器
/*动物类*/
class Animal{
//动物有的属性
String type;
//带参数的构造器
public Animal(String type){
this.type = type;
}
//动物都有的行为(叫)
public void call(){
System.out.println(type+"在叫");
}
}
dog类:
/*狗类*/
class Dog extends Animal{
//dog自己的一些属性
String color;
String hair;
//添加构造器
public Dog(){
super("小狗"); //一定要是在构造函数的第一行添加super
this.color = "黑色";
this.hair = "短毛";
}
}
1.4super
- super是指向父类的指针
- super(参数) 调用父类构造函数
- super.xxx 后面加点就是调用父类属性和方法
例:
//添加构造器
public Dog(){
super("小狗"); //调用父类构造函数
super.call(); //调用方法
super.type = "黑色"; //调用属性
}
在来看下内存图:
除了this指向子类,还有一个super指向父类