类与类之间的关系
- 属性关系
- 参数关系
- 继承关系
1.1基类 subclass
Person、Cat、Animal
可以叫做Biology
类的子类Animal
叫做Biology
类的直接子类Person、Cat
叫做Biology
类的间接子类,Person、Cat
是Animal
的直接子类
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