类与类之间的关系

  • 属性关系
  • 参数关系
  • 继承关系

1.1基类 subclass

Person、Cat、Animal可以叫做Biology类的子类
Animal叫做Biology类的直接子类
Person、Cat叫做Biology类的间接子类,Person、CatAnimal直接子类

1.2超类 superclass

Person、Cat直接父类是Animal,写在extends关键字后面的类
Person、Cat间接父类是Biology

Biology 类

public class Biology {
    Integer age;
    public Biology() { }
    public Biology(Integer age) {
        this.age = age;
        System.out.println("生物类的构造器...");
    }
}

Animal类

public class Animal extends Biology {
    public Animal() { }
    public Animal(Integer age) {
        super(age);
        System.out.println("动物类的构造器...");
    }
    public void drank(String water) {
        System.out.println("动物在喝" + water);
    }
    public String show() {
        return "我们很优秀";
    }
}

Person类

public class Person extends Animal {
    public Person() { }
    public Person(Integer age) {
        super(age);
        System.out.println("人类的构造器...");
    }
    public void drank(String water){
        System.out.println("Person在喝" + water);
    }
    public String show(){
        return super.show() + "我们很直溜";
    }
}

Cat类

public class Cat extends Animal {

    public Cat(Integer age) {
        super(age);
    }
}

运用

Biology biology = new Biology();
biology.age = 20;

Animal animal = new Animal(30);
animal.age = 30;

Person person = new Person();
person.age = 35;
person.drank("江小白");

// 运行结果
// 生物类的构造器...
// 动物类的构造器...
// Person在喝江小白

extends 继承

在Java中,继承是单继承,一个子类只能有一个直接父类,但是可以有多个间接父类
注意:extends后面只能写一个类

2.1继承能干什么?

继承了父类的属性,继承了父类的方法
访问权限修饰符

public 公开的
protected 受保护的,不同包的子类可以访问
default 默认的
private 私有的

2.2继承流程

创建子类对象时,父类先被实例化,再去实例化子类
当一个类被实例化时,一定会先实例化它的直接和间接父类
子类的构造器可以有多个,但是必须和父类的构造器形式上统一

2.3super关键字:

代表调用父类的结构(属性、方法、构造器)

2.4this和super的区别?

在子类中当使用super调用父类的构造器时,super(age)必须是第一句话
在当前类中使用this调用本类的构造器时,this(name)必须是第一句话
在构造器中,如果需要使用super或this调用其他构造器,只能二选一,而且还必须是第一句话

super指向的父类,不代表任何对象。
this指向的本类,代表当前类的对象,方法的调用者。

区别点this()super()
访问属性访问类中的属性,如果本类没有此属性则从父类中继续查找从父类开始查找属性
调用方法访问本类中的方法,如果本类没有此方法则从父类继续查找从父类开始查找方法
调用构造器调用本类构造器,必须放在构造器的首行调用父类构造器,必须放在子类构造器的首行
对象表示当前对象子类中访问父类对象

方法的重写

也可以说成覆写,覆盖,override

3.1什么是重写

子类可以重写父类的方法
我们可以利用到父类中方法已经运算过的结果,在结果的基础上进行扩展
体现的就是继承的核心,就是为了扩展父类的功能。

3.2方法的重写的规则

需要满足一个前提:继承与被继承的关系

  • 访问权限:重写的方法的权限不能低于被重写的方法。开发中一般都是等于
  • 返回值类型:重写的方法的返回值可以和被重写的方法不同,但是必须是被重写方法的返回值的子类。开发中,一般就是一样
  • 方法名:必须相同
  • 参数列表:参数类型,参数个数必须相同
  • 抛出异常:重写的方法不能抛出比被重写的方法更大的异常

重写需要注意的地方

开发中,如果要重写,基本就是一模一样,我们只变方法体


银行卡取款存款实例

运用到继承,CreditCard继承父类Card,并且多一个属性credits用来存储信誉额度
信用卡有额外的功能,即使当前的balance没有钱,也可以类似贷款一样,从credits取钱
还钱的时候要先判断是否使用了信誉额度,如果使用了要先还钱
如果没有的话,直接利用父类使用super.in(money)
以下是代码

Card类

public class Card {

    private String cardId;
    private String password;
    private Double balance;

    public Card in(Double money) {
        balance += money;
        return this;
    }
    public Card out(Double money) {
        balance -= money;
        return this;
    }
    public Card() {
    }
    public Card(String cardId, String password, Double balance) {
        this.cardId = cardId;
        this.password = password;
        this.balance = balance;
    }
    public String getCardId() {
        return cardId;
    }
    public void setCardId(String cardId) {
        this.cardId = cardId;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Double getBalance() {
        return balance;
    }
    public void setBalance(Double balance) {
        this.balance = balance;
    }
}


CreditCard类

public class CreditCard extends Card {
    private Double credits;
    public CreditCard() {
    }
    public Double getBalance() {
        return super.getBalance();
    }
    public Double getCredits () {
        return credits;
    }
    public CreditCard(String cardId, String password, Double balance, Double credits) {
        super(cardId, password, balance);
        this.credits = credits;
    }
    public CreditCard in(Double money) {
        // 信用卡的存款,首先要还额度,其次此时存款
        if (credits == 50000.0) {
            super.in(money);
            return this;
        }
        double tempMoney=0.0;
        if (credits < 50000.0) {
            tempMoney = 50000.0 - credits;
            if (money > tempMoney) {
                credits = 50000.0;
                money -= tempMoney;
                super.in(money);
            } else {
                credits+=money;
            }
        }
        return this;
    }


    public CreditCard out(Double money) {
        // 取款先走余额,再走信用额度
        if (getBalance() <=0 ){
            if (credits >= money) {
                credits -= money;
            } else {
                System.out.print("没有足够的信用余额!");
                return this;
            }
        }else {
            if (getBalance() >=money) {
                super.out(money);
            } else {
                if (getBalance()+getCredits() < money) {
                    System.out.print("没有足够的信用余额!");
                    return this;
                }
                credits=credits-(money-getBalance());
                setBalance(0.0);
            }
        }
        return this;
    }

    public void broadcastInfo () {
        System.out.println("账户:"+this.getCardId()+","+"密码:"+this.getPassword()+",普通余额:"+this.getBalance()+",信用余额:"+this.getCredits());
    }

}


Demo类

CreditCard creditCard = new CreditCard("testUser","testPassword",0.0,50000.0);
creditCard.out(80000.0).broadcastInfo();
creditCard.out(40000.0).broadcastInfo();
creditCard.in(20000.0).broadcastInfo();
creditCard.in(50000.0).broadcastInfo();
creditCard.out(90000.0).broadcastInfo();
creditCard.out(70000.0).broadcastInfo();
creditCard.in(90000.0).broadcastInfo();

// 输出
// 没有足够的信用余额!账户:testUser,密码:testPassword,普通余额:0.0,信用余额:50000.0
// 账户:testUser,密码:testPassword,普通余额:0.0,信用余额:10000.0
// 账户:testUser,密码:testPassword,普通余额:0.0,信用余额:30000.0
// 账户:testUser,密码:testPassword,普通余额:30000.0,信用余额:50000.0
// 没有足够的信用余额!账户:testUser,密码:testPassword,普通余额:30000.0,信用余额:50000.0
// 账户:testUser,密码:testPassword,普通余额:0.0,信用余额:10000.0
// 账户:testUser,密码:testPassword,普通余额:50000.0,信用余额:50000.0

最后修改:2023 年 01 月 09 日
如果觉得我的文章对你有用,请随意赞赏