day09 继承、super、this、抽象类

# day09 继承、super、this、抽象类

2020年2月18日

1 继承

1.1 概述

多个类中存在相同属性和行为时,将这些内容抽取到单独的类中,那么多个类不需要再定义这些属性和行为,只要继承那个类即可。

多个类可称为子类,单独的一个类可称为父类、超类(superclass)、基类

  • 继承:就是子类继承父类的属性行为,使得子类具有与父类相同的属性、行为,子类可以直接访问父类中非私有的属性和行为。

继承的好处:

  1. 提高代码的复用性
  2. 多态的前提

1.2 继承的格式

通过extends关键字声明一个子类继承另外一个父类

//定义一个父类:员工
public class Employee {
    public void method(){
        System.out.println("方法执行");
    }
}

//定义了一个员工的子类:讲师
public class Teacher extends Employee {
}

1.3 继承后的特点——成员变量

  • 成员变量不重名,无影响
  • 成员变量重名,子类中需要访问父类中非私有成员变量时,需要使用super关键字修饰父类成员变量
/*
在父子类的继承关系中,如果成员变量重名,则创建子类对象时,访问有两种方式:
直接通过子类对象访问成员变量:
    等号左边是谁,就优先用谁,没有则向上找
间接通过成员方法访问成员变量:
    该方法属于谁,就优先用谁,没有则向上找
 */
public class Demo01ExtendsField {
    public static void main(String[] args) {
        Fu fu=new Fu();
        System.out.println(fu.numFu);//只能使用父类的东西,没有任何子类内存
        Zi zi=new Zi();
        System.out.println(zi.numFu);
        System.out.println(zi.numZi);

        //等号左边是谁,就优先用谁
        System.out.println(zi.num);

        //这个方法是子类的,优先用子类的,没有再向上找
        zi.methodZi();//200

        //这个方法是在父类当中,属于父类,输出的是父类的100
        zi.methodFu();//100

    }

}

父类中成员变量私有后,子类不能直接访问。通常在编码的时候,我们遵循封装的原则,用private修饰成员变量,在父类中提供公共的getXxx和setXxx方法。

1.4 继承后的特点——成员方法

  • 成员变量不重名:对象调用方法时,首先会在子类查找有没有对应的方法,若子类中存在就会执行子类中的方法,若不存在就会执行父类的方法
  • 成员变量重名——重写(override)
  • 方法重写:子类中出现与父类一模一样的方法时(返回值类型、参数列表、方法名都相同),会出现覆盖效果,也称为重写或复写,声明不变,重新实现
  • 重写的应用:子类可以根据需要,定义特定于自己的行为,既沿袭了父类的功能名称,又根据子类的需要重新实现了父类方法,从而进行扩展增强。

重写时用到super.父类方法,表示调用父类的成员方法

/*
在父子类的继承关系中,创建子类对象,访问成员方法的规则:
    创建的对象是谁,则优先用谁,如果没有则向上找
注意事项:
无论是成员方法还是成员变量,如果没有都是向上找父类,绝对不会向下找子类的

重写(override)
概念:在继承关系中,方法的名称一样,参数列表也一样
重写(override):方法的名称一样,参数列表【也一样】。覆盖、覆写
重载(overload):方法的名称一样,参数列表【不一样】

方法的覆盖重写特点:创建的是子类对象,则优先用子类方法
 */
public class Fu {
    public void methodFu(){
        System.out.println("父类方法执行");
    }
    public void method(){
        System.out.println("父类重名方法执行");
    }
}

public class Zi extends Fu {
    public void methodZi(){
        System.out.println("子类方法执行");
    }
    public void method(){
        super.method();
        System.out.println("子类重名方法执行");
    }
}

注意事项

  1. 子类方法覆盖父类方法,必须保证权限大于父类权限
  2. 子类方法覆盖父类方法,返回值类型、函数名、参数列表都要一模一样

1.5 继承后的特点——构造方法

关于构造方法:

  1. 构造方法的名字与类名一致,所以子类无法继承父类的构造方法
  2. 构造方法的作用是初始化成员变量,所以子类初始化的过程中,必须先执行父类的初始化动作。子类的构造方法中默认有一个super(),表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。
/*
继承关系中,父子类构造方法的访问特点:
1.子类构造方法中有一个默认隐含的“super()”调用,所以一定是先调用父类构造,后执行子类构造。
2.子类构造可以通过super关键字来调用父类重载构造
3.super的父类构造调用,必须是子类构造方法的第一个语句,不能一个子类构造调用多次super构造
总结:
子类必须调用父类构造方法,不写则赠送super();写了则用指定的super调用,super只能有一个,还必须是第一个
 */
public class Fu {
    public Fu(int num){
        System.out.println("父类构造方法");
    }
}

public class Zi extends Fu {
    public Zi(){
        super(20);
//        super();
        System.out.println("子类构造方法");
    }
    public void method(){
//        super();//错误写法!只有子类构造方法,才能调用父类构造方法
    }
}

1.6 super和this

父类空间优于子类对象产生

每次创建子类对象时,先初始化父类空间,再创造子类对象本身,目的在于子类对象中包含了其对应的父类空间,便可以包含其父类的成员。如果父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类构造方法调用时,一定要先调用父类的构造方法

super和this的含义

  • super:代表父类的存储空间标识(可理解为父类的引用)
  • this:代表当前对象的引用(谁调用就代表谁)

super和this的用法

  1. 访问成员
  2. 访问构造方法

子类的每个构造方法中均有默认的super(),调用父类的空参构造。手动调用父类构造会覆盖掉默认的super()。super()和this()都必须在构造方法的第一行,所以不能同时出现

2 抽象类

2.1 概述

没有方法主体的方法称为抽象方法,包含抽象方法的类就是抽象类

2.2 abstract使用格式

abstract关键字修饰方法,抽象方法只包含一个方法名,没有方法体

抽象的使用

继承抽象类的子类必须重写父类所有的抽象方法,否则该子类也必须声明为抽象类。

此时的方法重写,是子类对父类抽象方法的实现,这种将方法重写的操作,也叫做实现方法

2.3 注意事项

  1. 抽象类不能创建对象
  2. 抽象类可以有构造方法,是供子类创建对象时,初始化父类成员使用的
  3. 抽象类中不一定包含抽象方法,但是有抽象方法的类必然是抽象类
  4. 抽象类的子类必须重写抽象父类中的抽象方法

猜你喜欢

转载自www.cnblogs.com/ningdeblog/p/12327544.html