[javaSE笔记3] JAVA的继承---多态 抽象

  • 关键字 : extends
  • extends表明正在构造的新类派生于一个已经存在的类, 这个已经存在的类称为 超类 基类父类 ; 新类称为子类孩子类
  • 从某个特定的类到其祖先的路径称为该类的继承链

在java中, 继承有三个特征 :

  1. JAVA是单继承的, 一个类的直接父类只能有一个
class A extends B{}  // 正确
class A extends B,C{} // 错误
  1. JAVA语言可以多级继承 ( java.lang.Object类是继承链的顶端 )

[javaSE笔记3] JAVA的继承---多态 抽象

class A extends B{} // 正确
class B extends C{} // 正确
  1. 一个子类的直接父类是唯一的, 但是一个父类可以拥有很多个子类

[javaSE笔记3] JAVA的继承---多态 抽象

多态

在java中, 对象变量是多态的, 子类的每个对象也是超类的对象 e.g. 一个Employee类型的变量既可以引用一个Employee类型的对象, 也可以引用Employee类的任何一个子类的对象 ( 例如, Manager, Executive, Secretary等 )

关于多态中的成员变量

  1. 直接访问成员变量 : 看等号左边是谁, 则优先用谁, 如果没有就向上查找, 不会向下查找 : e.g.
public class Father { // 父类
    int x = 10;
}

public class Son extends Father { // 子类
    int x = 20;
}
public class MainFunc {
    public static void main(String[] args) {
        Father obj = new Son(); // 多态
        System.out.println(obj.x);
    }
}

输出为10, 也就是父类的x属性

" 编译看左边, 运行也看左边 "

  1. 如果用成员方法间接访问成员变量, 则方法属于谁就优先用谁, 如果没有就向上查找.

关于多态中的成员方法

成员方法的访问原则 :

看new的是谁, 就优先用谁, 如果没有就向上查找

Father obj = new Son();
obj.method; // 父类子类都有, 优先使用子类的
obj.method_of_father; // 子类没有, 向上查找使用父类
obj.method_of_son; // 父类没有, 报错 ! (编译不通过)

" 编译看左边, 运行看右边 "

使用多态的好处

比如一个学校里有很多不同的工种 教授, 副教授, 导员, 讲师, 助教.... 他们都是为学校工作

他们在学校都是工作, 那么不使用多态的写法为 :

teacher a = new teacher();
assistant b = new assistant();
professor c = new professor();

a.work(); 
b.work();
c.work();
....

使用多态则为 :

Employee a = new teacher();
Employee b = new assistant();
Employee c = new professor();

...

无论右边是什么, 左边对于学校来说都是Employee的身份...

  • 关于强制类型转换 ( 向下转型 ) :
    • 只能在继承层次内进行强制类型转换
    • 在将超类强制转换成子类之前, 应该用instanceof进行检查
if ( a instanceof b) { 
	c = (b) a;
}

super关键字

  1. 在子类的成员方法中, 访问父类的成员变量
  2. 在子类的成员方法中, 访问父类的成员方法
  3. 在子类的构造方法中, 访问父类的构造方法
public son extends father{
    int num = 20;
    
    public son() {
     	super(); // 父类的构造方法
    }
    
    public void methodson() {
        sout(super.num); // 父类的num
    }
    
    public void method() {
        super.method(); // 父类的method
    }
}

抽象类

如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类

抽象类和抽象方法用abstract关键字表示

public abstract class Animal {

    // 抽象方法
    public abstract void eat();

    // 普通的成员方法
    public void normalMethod() {

    }
}

[javaSE笔记3] JAVA的继承---多态 抽象

子类必须覆盖重写抽象类的所有抽象方法 : ( idea中在子类 alt + enter -- implement -- @Override)

  • 一个继承的案例 : 发红包

User父类 :

package Red_Beg;

public class USer {
    private String name;
    private  int money;

    // alt + insert自动生成
    public USer() {
    }

    public USer(String name, int money) {
        this.name = name;
        this.money = money;
    }

    public void show() {
        System.out.println("我叫, " + name + ", 我有多少钱? : " + money);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}

Manager发红包 :

package Red_Beg;

import java.util.ArrayList;

public class Manager extends USer {

    public Manager() {
    }

    public Manager(String name, int money) {
        super(name, money);
    }

    public ArrayList<Integer> send(int totalMoney, int count) {
        // 集合, 存储若干个红包的金额
        ArrayList<Integer> redList = new ArrayList<>();

        int leftMoney = super.getMoney();
        if (totalMoney > leftMoney) {
            System.out.println("余额不足");
            return redList;
        } else // 扣钱
        {
            super.setMoney(leftMoney - totalMoney);
            // 发红包平均拆分成count段
            int avg = totalMoney / count;
            int mod = totalMoney % count;

            // 放进集合
            for (int i = 0; i < count - 1; i++) {
                redList.add(avg);
            }

            int last = avg + mod;
            redList.add(last);

            return redList;
        }
    }
}

Member收红包 :

package Red_Beg;

import java.util.ArrayList;
import java.util.Random;

public class Member extends USer {
    public Member() {
    }

    public Member(String name, int money) {
        super(name, money);
    }

    public void receive(ArrayList<Integer> list) {
        // 随机抽取一个红包
        int index = new Random().nextInt(list.size());
        // 以上为生成一个0-list.size()的随机int

        // 根据索引从集合中删除
        int delta = list.remove(index);
        int money = super.getMoney();

        super.setMoney(money + delta);
    }
}