本系列为笔者学习Javase的课堂笔记,视频资源为B站黑马程序员出品的《黑马程序员Java+AI智能辅助编程全套视频教程,java零基础入门到大牛一套通关》,章节分布参考视频教程,为同样学习Javase系列课程的同学们提供参考。
01 什么是多态?
多态是在继承或实现情况下的一种现象,表现为对象多态和行为多态。
Animal.java
动物类
package Poly;
public class Animal {
String name = "动物";
public void run(){
System.out.println("动物会跑~");
}
}
Tortoise.java
乌龟类
package Poly;
public class Tortoise extends Animal{
String name = "乌龟";
@Override
public void run(){
System.out.println("乌龟跑得快~");
}
}
Wolf.java
狼类
package Poly;
public class Wolf extends Animal{
String name = "狼";
@Override
public void run(){
System.out.println("狼跑得快~");
}
}
Test.java
测试
package Poly;
import javax.lang.model.element.AnnotationMirror;
public class Test {
public static void main(String[] args) {
//对象多态
Animal a1 = new Wolf();
Animal a2 = new Tortoise();
//行为多态
a1.run(); //成员方法:编译看左边,运行看右边
a2.run();
System.out.println(a1.name); //成员变量:编译看左边,运行看左边
System.out.println(a2.name);
//多态是对象、行为的多态,和成员变量没啥关系
}
}
02 多态的前提
- 继承或实现
- 父亲引用子类对象
- 方法重写
03 多态的好处
- 右边对象解耦合
- 父类类型的形参可以接收一切子类对象
- 没法调用子类独有功能
public class Test {
public static void main(String[] args) {
//好处1:右边对象解耦合
Animal a = new Tortoise();
//Animal a = new Wolf();
a.run();
//好处2:父类类型的形参,可以接收一切子类对象
Tortoise t = new Tortoise();
go(t);
Wolf w = new Wolf();
go(w);
//坏处1:没法调用子类独有功能
//a.shrinkhead();
Tortoise t0 = (Tortoise) a;
t0.shrinkhead();
}
public static void go(Animal a){
a.run(); //对象回调
}
}
04 多态的类型转换
自动类型转换:父类 变量名 = new 子类();
Animal a = new Tortoise();
强制类型转换:子类 变量名 = (子类) 父类变量;
Tortoise t0 = (Tortoise) a;
注:编译阶段,存在继承或实现关系,可以进行强制类型转换;运行阶段,如果发现对象的真实类型与强转之后不同,会报类型转换异常(ClassCastExpception)
的错。因此,建议在强转之前,使用instanceof
查询对象的真实类型。
if(a1 instanceof Wolf){
Wolf w1 = (Wolf) a;
w1.eatSheep();
}else if(a1 instanceof Tortoise){
Tortoise t1 = (Tortoise) a;
t1.shrinkHead();
}
05 案例:加油站支付小模块
Card.java
package fire;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Card {
private String carId;
private String name;
private String tel;
private double money;
public void deposit(double money){
this.money += money;
}
public void consume(double money){
this.money -= money;
}
}
GoldCard.java
package fire;
public class GoldCard extends Card{
public GoldCard(String carId, String name, String tel, double money){
super(carId, name, tel, money);
}
@Override
public void consume(double money){
System.out.println("您当前金卡消费:" + money);
System.out.println("优惠后的金额为:" + money * 0.8);
if(getMoney() < money * 0.8){
System.out.println("余额不足");
return;
}
setMoney(getMoney() - money * 0.8);
System.out.println("您当前金卡余额:" + getMoney());
if(money * 0.8 >= 200){
printTicket();
}else{
System.out.println("不满200元不打印洗车券");;
}
}
public void printTicket(){
System.out.println("满200元打印洗车券");
}
}
SilverCard.java
package fire;
public class SilverCard extends Card{
public SilverCard(String carId, String name, String tel, double money){
super(carId, name, tel, money);
}
@Override
public void consume(double money){
System.out.println("您当前银卡消费:" + money);
System.out.println("优惠后的金额为:" + money * 0.9);
if(getMoney() < money * 0.9){
System.out.println("余额不足");
return;
}
setMoney(getMoney() - money * 0.9);
System.out.println("您当前银卡余额:" + getMoney());
}
}
Test.java
package fire;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
GoldCard g = new GoldCard("京A66666","张三", "18899997777", 100000);
pay(g);
SilverCard s = new SilverCard("粤A00000","李四", "18652997987", 50000);
pay(s);
}
public static void pay(Card c) { //对象多态
System.out.println("输入消费金额:");
Scanner sc = new Scanner(System.in);
double num = sc.nextDouble();
c.consume(num);
}
}