继承

1.面向对象三大特征:封装性、继承性、多态性

继承是多态的前提,如果没有继承就没有多态

2.继承主要解决的问题是:共性抽取

被继承的叫:父类,或者叫基类、超类

继承的叫:子类,或者叫派生类

3.继承关系当中的特点:子类可以拥有父类的内容,还可以拥有自己特有的内容

4.在继承关系中,“子类就是一个父类”,也就是说子类可以被当做父类看待

例如:父类是员工(包括讲师和助教),子类是讲师,那么“讲师就是一个员工”

继承定义的格式:

//父类
public class 父类名称{

}
//子类
public class 子类名称 extends 父类名称{

}

5.子类可以继承父类的成员变量或者成员方法

若父类与子类存在相同的成员变量,则:

①若是直接通过子类对象访问成员变量:
等号左边是谁,就优先用谁,没有则向上找。
②若是间接通过成员方法访问成员变量:
该方法属于谁,就优先用谁,没有则向上找。

若父类当中的成员变量,子类当中的成员变量,子类方法中的局部变量三者重名:

引入super关键字访问父类,其余同之前。

class Fu {
        int num = 5;// Fu中的成员变量。
} 
class Zi extends Fu {
        int num = 6;// Zi中的成员变量
        public void show() {
                int num=4;
                System.out.println("方法 num=" + num);//该方法的局部num
                System.out.println("Fu num=" + super.num);//访问父类中的num
                System.out.println("Zi num=" + this.num);//访问子类中的num
}
} 
/*
演示结果:
方法 num = 4
Fu num = 5
Zi num = 6
*/ 
class ExtendsDemo03 {
        public static void main(String[] args) {
// 创建子类对象
                Zi z = new Zi();
// 调用子类中的show方法
                z.show();
}
} 

若父类与子类存在相同的成员方法,则:

​ 创建的是谁,就优先用谁,没有则向上找

注意事项:

​ 无论是成员变量还是成员方法,如果没有都是向上找父类的,绝对不会向下找子类的

6.继承中方法的覆盖重写

重写的定义:Override,在继承关系中,方法的名称一样,参数列表也一样,也叫方法的覆盖,覆写。

重写与重载:

​ 重写(Override):方法的名称一样,参数列表也一样

​ 重载(Overload):方法的名称一样,参数列表不一样

方法覆盖重写的特点:创建的是子类对象,就优先用子类的方法

@Override:写在方法前面,用来检测是不是有效的正确覆盖重写

@Override//一种注解,可以起到检测作用
class Fu{
    public void show(){
        System.out.println("Fushow");
}
}
class Zi extendsFu{
//子类重写了父类的show方法
    public void show(){
        System.out.println("Zishow");
}
}
public class ExtendsDemo05{
    public static void main(String[]args){
        Ziz= new Zi();
//子类中有show方法,只执行重写后的show方法                    z.show();//Zishow
}
}

子类方法的返回值必须小于等于父类方法的返回值范围

​ java. lang. Object类是所有类的公共最高父类(祖宗类),java. lang. String就是object的子类。

子类方法的权限必须大于等于父类方法的权限修饰符

        小扩展提示: public > protected > (default) > private

​ 备注:(default)不是关键字default, 而是什么都不写,留空。

覆盖重写的应用

​ 子类可以根据需要,定义特定于自己的行为。既沿袭了父类的功能名称,又根据子类的需要重新实现父类方法,从而进行扩展增强。比如新的手机增加来电显示头像的功能,代码如下:

class Phone{
    public void sendMessage(){
        System.out.println("发短信");
}
    public void call(){
        System.out.println("打电话");
}
    public void showNum(){
        System.out.println("来电显示号码");
}
}
//智能手机类
class NewPhone extends Phone{
//重写父类的来电显示号码功能,并增加自己的显示姓名和图片功能
    @Override
    public void showNum(){
//调用父类已经存在的功能使用super
        super.showNum();
//增加自己特有显示姓名和图片功能
        System.out.println("显示来电姓名");
        System.out.println("显示头像");
}
}
public class ExtendsDemo01{
    public static void main(String[]args){
//创建子类对象
        NewPhone np =new NewPhone();
//调用父类继承而来的方法
        np.call();
//调用子类重写的方法
        np.showNum();
}
}

7.继承方法中父子类构造方法的访问特点

构造方法与类名一致,正常情况下子类是无法继承父类的构造方法的

但子类必须调用父类的构造方法,子类构造方法中有一个默认隐含的"super()"调用,所以是先调用父类的构造方法再执行子类的构造方法,可以通过super关键字来子类构造调用父类重载构造

super的父类构造调用,必须是子类构造方法的第一个语句,一个子类构造也只能使用super调用一次父类构造

class Fu{
    private int n;
    Fu(){
        System.out.println("Fu()");
        }
    Fu(int a){
        System.out.println("Fu(有参)");
        }
}
class Zi extends Fu{
    Zi(){
        super();//调用无参父类构造函数这句可以不写,调用有参的父类重载构造函数需要使用super(10);
        System.out.println("Zi()");
}
}
public class ExtendsDemo01{
    public static void main(String args[]){
        Zi zi= new Zi();
}
}
输出结果:
Fu()
Zi()

8.super关键字

super关键字的三种用法:

①在子类的成员方法中,访问父类的成员变量(子父类变量有重名,不想用自己的,就想用父类的)

②在子类的成员方法中,访问父类的成员方法(子父类变方法有重名,不想用自己的,就想用父类的)

③在子类的构造方法中,访问父类的构造方法(上面提到的)

9.this关键字

super关键字用来访问父类内容,this关键字用来访问本类内容。

用法也有三种:

①在本类方法中访问本类的成员变量(典型用法,就是当该方法的局部变量与本类成员变量重名时,要使用本类的成员变量)

②在本类的成员方法中,访问本类的另一个成员方法(主要起强调作用,强调调用的方法来自本类而非父类)

③在本类的构造方法中,调用另外一个构造方法,此时this(...)必须是该构造方法第一个语句,且是本构造的唯一的this构造调用,所以这种情况和super调用也有冲突,所以在一个子类的构造方法中只能二选一调用其他构造方法

10.super与this关键字的内存图

file

11.java继承的三个特点

1.Java只支持单继承,不支持多继承

//一个类只能有一个父类,不可以有多个父类。
class C extends A{}//ok
class C extends A,B...//error

2.Java支持多层继承(继承体系)

class A{}
class B extends A{}
class C extends B{}//C也叫做A的父类,但不能叫直接父类

顶层父类是Object类,所有的类默认继承Object。Object作为所有类的父类。
3.子类和父类是一种相对的概念