0001_为什么使用多态
Posted 史前蓝熊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了0001_为什么使用多态相关的知识,希望对你有一定的参考价值。
为什么使用多态
让我们用一点代码来说明问题,假设代码中有三个class: 自行车(Bicycle)、汽车(Car)和卡车(Truck),这三个class分别有这样三个实现:Ride()、Run()、Launch(),实际上都是让它们发动起来,如果没有多态的话我们该怎样开动它们呢?(注意这里没有采用特定语言,因为多态是一个通用的概念)
// 实现
Bicycle bicyle = new Bicycle();
Car car = new Car();
Truck truck = new Truck();
// 使用部分
bicyle.Ride();
car.Run();
truck.Launch();
注意,以上代码包含了两部分:
一部分是类的实现;
另一部分是类的使用,意识到这一点对于理解多态非常关键。
现在我们已经知道了使用类的代码包含两部分,在这样的代码实现中如果Bicyle的接口修改了,那么使用部分的代码同样需要修改,这是程序员所不想看到的。如果有多态会怎样呢?
实际上自行车(Bicycle)、汽车(Car)和卡车(Truck)都是交通工具(Vehicle),把它们发动起来都是让它们Run起来,因此,如果有多态的话我们可以这样写代码:
// 实现部分
List<Vehicle> vehicles = new Bicycle(),
new Car(),
new Truck() ;
// 使用部分
for (v : vechicles)
v.Run();
怎么样,代码是不是一下就简洁多了,最棒的是不管实现部分代码怎么改动都不会影响到使用部分的代码,实际上你可以往vehicles中增加任意多对象都不会影响到使用部分,这就是设计模式当中所谓的"只针对抽象编程,而不是针对实现编程"。
因此我们可以看到,尽管自行车、汽车、卡车是不同的东西,但是当我们将其抽象为交通工具后就可以一视同仁的对待它们,这就是多态。
现在你应该理解什么是多态以及为什么需要多态了吧。
当然为了实现多态,类的定义要稍稍改动一下:
class Vehicle // 新增抽象类
void Run()
class Bicycle: Vehicle
void Run() ...... // Ride修改为Run
class Car: Vehicle
voie Run() ...... // 无需改动
class Truck: Vehicle
void Run() ...... // Launch修改为Run
实际上如果你仔细想想的话整数和浮点数就是一种多态,因为你可以把一个整数和一个浮点数相加,也就是以相同的方式使用它们,尽管整数和浮点数是两个不同的数据类型。
总结:
多态可以让程序员针对抽象而不是具体实现来编程,这样的代码会有更好的可扩展性。
当然为了使用多态你需要进行抽象,也就是定义一个接口让不同的对象去实现,这样从这个接口的角度看各个对象就一样了,因此可以以一致的方式来使用这些不同类型的对象,这就是多态的威力。
Java oop第05章_多态接口
一、 为什么需要接口? Java中当一个类继承父类时,最多也只能继承一个父类,扩展性会受到一定的限制,为了弥补这一缺陷,Java又提供了一种新的引用数据类型分类,叫接口。 一个类只能继承一个父类,但可以实现多个接口。
二、 接口的定义和使用: 1. 定义接口:使用interface关键字。 2. 实现接口:在一个抽象类或实现类中可以通过implements关键字。
三、 接口的注意事项: 1. 接口是比抽象类更加抽象的“类”,接口中所有的方法都是抽象方法(不管是否使用abstract关键字修饰)。 2. 一个类若继承了一个抽象类或实现接口,该类有两种选择,要么将自己声明为抽象类(可以不用实现父类或接口中的抽象方法),
要么实现父类中或接口中的所有抽象方法。 3. 抽象类和接口都是不能被实例化的,即不能创建抽象类和接口的对象。 4. 接口当中的成员变量(属性、字段)必须是静态常量,且要使用public修饰,同时要赋值。 public static final String name = ""; 5. 接口不能再去实现(implements)其他接口,但可以使用extends关键字去继承接口,且可以继承多个接口 6. 抽象类中可以写构造方法,但接口中不能编写构造方法
四、 使用接口的好处:
1、 可以达到多“继承”的效果,针对Java是单继承的缺陷进行补充,让Java代码的扩展性更好。
2、 使用接口后可以达到设计(在接口中定义属性和方法)和实现(实现接口中的方法)分离,更利于团队协同开发;
设计可能是一个公司或组织在完成,而实现是其他更多的公司或组织来完成。
3、 JDBC、Java web都是先在接口中定义属性和方法,各个数据库厂商实现jdbc的接口、抽象类中定义的抽象方法;
Java web的实现接口(如:tomcat)实现Java web接口、抽象类中定义的抽象方法。
4、 更自然的实现多态。
5、 调用者可以不用关心方法实现的细节,只需要知道调用方法时注意的问题即可
(a、是否需要传递参数,若需要是什么类型的参数;b、方法执行完是否有返回值,若有是什么类型的值;c、观察该方法是在哪个接口、抽象类、实现类定义的)
五、 什么是多态?
一个父类型(接口、抽象类、实现类)的引用可以指向多个子类的对象(实例、引用),称为多态。
/** * 定义了一个接口:接口会提供一些属性和方法 * */ public interface Usb{ public static final String name = ""; /** * 接口中的方法都是抽象方法,加不加abstract关键字都可以 * 使用的方法 */ public void use(); /** * 显示信息的方法 * @param name:显示的名称 */ public void view(String name); /** * 打印输出的方法。 */ public void print(); }
/** * 定义一个类:去实现Usb接口 * 一个类若继承了一个抽象类或实现接口,该类有两种选择,要么将自己声明为抽象类(可以不用实现父类或接口中的抽象方法), * 要么实现父类中或接口中的所有抽象方法。 */ public class UsbMouse implements Usb { @Override public void use() { System.out.println("USB Mouse的use()方法中输出的内容"); } @Override public void view(String name) { System.out.println("USB Mouse的view()方法中输出的内容"); } @Override public void print() { System.out.println("USB Mouse的print()方法中输出的内容"); } }
/** * 定义一个类:去实现Usb接口 */
public class UsbFan implements Usb { @Override public void use() { System.out.println("USB Fan的use()方法中输出的内容"); } @Override public void view(String name) { System.out.println("USB Fan的view()方法中输出的内容"); } @Override public void print() { System.out.println("USB Fan的print()方法中输出的内容"); } }
public class UsbTest { public static void main(String[] args) { //一个父类型的引用可以指向多个子类的对象(实例、引用),称为多态。 Usb usb = new UsbMouse(); Usb usbfan = new UsbFan(); usb.use(); usbfan.use(); } }
以上是关于0001_为什么使用多态的主要内容,如果未能解决你的问题,请参考以下文章