【 继承、super、this、抽象类 】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Sugar_i/article/details/81137379

面向对象三大特征:封装继承多态
继承多态的前提,没有继承,就没有多态。

继承

  • 继承主要是为了达到:共性抽取

定义一个父类,父类就是一个普普通通的类,格式没有特殊之处。
定义子类的格式:

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

父类定义:(基类、超类)
public class Employee {} // 员工
子类定义:(派生类)
public class Teacher extends Employee {} // 讲师
称谓:
Teacher讲师类,是Employee员工类的子类。
Employee是Teacher的父类。

这里写图片描述
父子类继承关系当中,成员变量、成员方法的访问特点

直接通过对象名称访问成员变量等号左边是谁,优先用谁;如果没有,向上找父类。
间接通过成员方法访问成员变量该方法属于谁,优先用谁;如果没有,向上找父类。

继承关系当中可能出现下面三种重名

1. 访问局部变量         直接写
2. 访问本类成员变量     this.成员变量
3. 访问父类成员变量     super.成员变量

super关键字代表访问父类的内容。

重载(Overload):方法的名称相同,参数列表不同
重写(Override):方法的名称相同,参数列表【也相同】。也叫做覆写、覆盖。
这里写图片描述

访问特点:创建的是子类对象,就优先调用子类方法。

@Override是一种注解,可以帮助我们检测方法是不是正确的覆盖重写。如果报错,就不是正确的覆盖重写。
但是要注意:就算没有注解,只要符合要求,也照样是方法的覆盖重写。注解只是一种可选的检测手段而已。

在方法覆盖重写的时候,注意事项

  1. 方法名称完全一样,参数列表也是完全一样。
  2. 子类方法的返回值范围,必须【小于等于】父类方法的返回值范围。
  3. 子类方法的访问权限,必须【大于等于】父类方法的访问权限。
    四种访问权限的大小规则:
    public > protected > (default) > private

【注意】不能继承的东西
1. private私有
2. 构造方法

继承的构造方法:
在继承关系当中,父类构造方法,在子类构造方法之前完成。
子类对象在创建的时候,必须调用父类的构造方法。

子类构造方法的第一行,默认会赠送一个:super();代表调用父类的无参构造方法。
这里写图片描述

Super关键字

super关键字有下面三种典型用法:

  1. 在子类的成员方法中,访问父类的成员变量super.父类成员变量名
  2. 在子类的成员方法中,访问父类的成员方法super.父类成员方法名(参数)
  3. 在子类的构造方法中,访问父类的构造方法super(参数)

注意事项:
1. 只有子类构造方法,才可以super调用父类构造方法
2. super的构造调用必须是子类构造方法的第一行,注释不算。
3. 正因如此,所以super调用只能调用一次。

public void methodZi() {
//   super(); // 错误!只有构造方法才能super调用构造方法
     System.out.println(super.numFu);
     super.methodFu();
 }

这里写图片描述

this关键字

this关键字也有下面的三种用法:

  1. 在本类的成员方法中,访问本类的成员变量this.本类成员变量名
  2. 在本类的成员方法中,访问本类的另一个成员方法this.本类另一个成员方法名(参数)
  3. 在本类的构造方法中,调用本类的重载构造方法this(参数)

注意事项:
1. 只有构造方法才能this调用另一个构造方法。
2. this构造调用,必须是构造方法当中的第一行。
3. 正因如此,this构造调用只能调用一次。
4. this和super二者不能并存,这并不想影响“子类必须调用父类构造”的要求。
5. 不能出现“僵持循环调用”。

抽象(abstract)

抽象方法定义格式:

public abstract 返回值类型 方法名称(参数类型 参数名称);

抽象类定义格式:

public abstract class 类名称 {
    // ...
}

注意:抽象方法所在的类,必须是抽象类

使用步骤
1. 抽象类不能直接new对象
2. 必须用一个子类来继承抽象类。
3. 子类必须覆盖重写所有的抽象方法。
4. 创建子类对象,使用。

子类必须覆盖重写抽象父类当中所有的抽象方法,除非子类也是一个抽象类。

抽象的概念:
这里写图片描述
抽象方法存在的意义:
这里写图片描述

群主发红包,成员收红包案例分析:
这里写图片描述
定义一个抽象的用户类:

private String name; // 姓名
private int money; // 余额

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;
}

定义普通群主类继承用户类:

public class Manager extends User {

    public Manager() {
    }

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

    public ArrayList<Integer> send(int totalMoney, int totalCount) {
        // 首先准备一个集合,用来存储拆分之后的好几份红包
        ArrayList<Integer> redList = new ArrayList<>();

        // 首先看看群主有没有那么多钱,够不够
        int leftMoney = super.getMoney(); // 先拿到群主本来的钱
        if (totalMoney > leftMoney) { // 如果钱不够
            System.out.println("余额不足");
            return redList;
        }

        // 如果够,余额减去红包金额
        int money = leftMoney - totalMoney;
        super.setMoney(money);

        int avg = totalMoney / totalCount; // 平均数
        int mod = totalMoney % totalCount; // 余数

        // 前n-1个红包,都是平均数
        for (int i = 0; i < totalCount - 1; i++) {
            redList.add(avg);
        }

        redList.add(avg + mod); // 最后一个红包包含平均数+余额

        return redList;
    }
}

定义一个普通成员类继承用户类:

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());
        // 根据索引值“取出”一个红包
        // 取出:拿走一个,就应该少一个。
        int money = list.remove(index);

        // 我看看自己当前余额是多少钱
        int leftMoney = super.getMoney();
        super.setMoney(leftMoney + money);
    }
}

调用测试类:

public static void main(String[] args) {
        Manager manager = new Manager("群主", 100);
        Member one = new Member("成员A", 0);
        Member two = new Member("成员B", 0);
        Member three = new Member("成员C", 0);

        manager.show();
        one.show();
        two.show();
        three.show();
        System.out.println("===============");

        ArrayList<Integer> list = manager.send(80, 3);

        one.receive(list);
        two.receive(list);
        three.receive(list);

        manager.show();
        one.show();
        two.show();
        three.show();
  }

猜你喜欢

转载自blog.csdn.net/Sugar_i/article/details/81137379