大家好,我是大鹅
最近有一些小伙伴问我,Java的多态到底是个啥玩意,写了几年代码,但感觉还是理解的不透彻。
借此机会,今天就来聊一聊多态吧。
说一说我理解的多态
多态就是同一类型,理论上可以有无数种不同的实现。
Java提供了非常方便的,允许子类对象直接赋给父类变量,虽然看起来变量是父类型,但实际执行的是子类重写后的方法逻辑。
多态是怎么实现的
Java的父类型,有3种形式,普通类、抽象类、接口。
如果是普通类和抽象类,得先继承,然后根据自身特性,重写对应方法,最后还得是父类的引用,指向子类的对象,这样就实现了多态。
如果是接口,那就是接口类的引用,指向实现接口类的对象,基本一样的。
多态的好处是什么
消除类型之间的耦合关系,比如订单类,可能有多种类型的订单,每种多少有些差异,如果都耦合在订单类中,那么可能会非常臃肿,可以利用多态,把订单抽象出一个父类或接口,各个类型的订单继承订单类,各自互不干扰。
拓展性好,新增订单类型,增加对应子订单实现类即可。
维护性好,每一个子业务都有自己的实现,阅读起来逻辑清晰,代码不臃肿。
工作中有什么场景会用到多态
比如订单的场景,业务上可能分商品订单和充值订单等等多种
如果在订单类里,对商品订单和充值订单分两个方法来创建订单,之后再新增订单类型,就又得在订单类里加一个方法,随着业务的增加,这个类会非常臃肿。
可以创建一个订单接口,里面定义一个创建订单的方法,商品订单和充值订单都去实现这个接口类,在创建订单的时候,根据订单类型,映射对应的订单接口实例,然后执行创建方法即可。
以后新增订单类型,就增加对应订单接口的实现类,各个业务实现之间互不干涉,也不会在订单类新增代码,更简洁优雅一些;
参考知识
多态是Java提供的,同一个类型的行为具有多个不同表现形式或形态的能力,Java允许把一个子类对象直接赋给一个父类引用变量,无须任何类型转换,或者被称为向上转型,向上转型由系统自动完成;
多态可以实现同一个类型的对象,表现出不同的行为操作
例如【无线充电】和【有线充电】都继承于【充电】这个父类
继承后,它们都有【给手机充电】这个能力
但 无线充电 和 有线充电 是两种完全不同的实现方式
这就是它们在【给手机充电】这个能力上表现出的多态性;
代码的实现示例
继承的方式
定义个充电类,可以是普通类,也可以是抽象类,这里定义的是个普通类
public class Charge{
public void charge(){
system.out.print("这是充电");
}
}
有线充电
public class WiredCharge extends Charge{
public void charge(){
system.out.print("这是有线充电");
}
}
无线充电
public class WirelessCharge extends Charge{
public void charge(){
system.out.print("这是无线充电");
}
}
测试
public static void main(String[] args) {
Charge c1 = new Charge();
c1.charge(); // print输出【这是充电】
Charge c2 = new WiredCharge();
c2.charge(); // print输出【这是有线充电】
Charge c3 = new WirelessCharge();
c3.charge(); // print输出【这是无线充电】
}
接口的方式
和继承的代码差不多,把充电类改成接口类,然后实现接口类即可
定义个充电接口类
public interface Charge{
void charge();
}
有线充电
public class WiredCharge implements Charge{
public void charge(){
system.out.print("这是有线充电");
}
}
无线充电
public class WirelessCharge implements Charge{
public void charge(){
system.out.print("这是无线充电");
}
}
测试
public static void main(String[] args) {
Charge c1 = new WiredCharge();
c2.charge(); // print输出【这是有线充电】
Charge c2 = new WirelessCharge();
c3.charge(); // print输出【这是无线充电】
}
多态的好处
- 消除类型之间的耦合关系
- 可替换、可拓展,设计程序时让代码更加简洁而优雅
- 接口性
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象:Parent p = new Child();
多态的实现方式
- 继承后,重写父类方法
- 实现接口