1.什么是多态?
多态是同一个行为具有多个不同表现形式或形态的能力。或者说:多态就是同一个接口,通过调用不同的实例执行不同操作。
通俗的说:
多态就是“对于同一个消息的响应,不同对象响应结果不同”。
---->>为帮助你更好的理解“多态”概念,下面举几个例子,一定要仔细思考:
(1)举例1:
类1 ---->> Type1 :按 “年-月-日” 输出日期;
类2 ---->> Type2 :按 “月-日-年” 输出日期;
类3 ---->> Type3 :按 “日-月-年” 输出日期;
当传递参数给Type1、Type2、Type3时,传入年、月、日参数,则对应三种不同的输出格式。也就是说:“年、月、日”是同一种数据,但是 “不同的 类” 对这一数据的响应结果不同,也就是所谓的“多态”。
(2)举例2:
主函数中有以下语句:
int a = 123;
double d = (double)a;
byte b = (byte)a;//强制类型转换为byte
System.out.println("int强制类型转换为double后的值等于"+d);
System.out.println("int强制类型转换为byte后的值等于"+b);
在这个例子中,对于同一 int 型数据a,分别强制转换为double、byte类型数据,这也带有多态的身影,即不同的语句对传递来的参数 a 响应结果不同,输出不同的数据,得到不同结果。
(3)举例3:
打开电脑,不同情况下按下 F1 键:
如果当前在 Flash 界面下弹出的就是Falsh帮助;
如果当前在 Word 下弹出的就是 Word 帮助;
在 Windows 下弹出的就是 Windows 帮助和支持。
也就是说:同一个事件(按下F1键)发生在不同的对象上会产生不同的结果。
(4)举例4:
如下图片,打印机可以打印黑白的,也可以打印彩色的,这就是多态,命令传给“打印机”,但是“打印机对 命令的响应结果不同,从而 打印黑白或彩色样式”。
2.多态优点
消除类型之间的耦合关系、可替换性、可扩充性、接口性、灵活性、 简化性。
3.实现多态的必要条件
(1)继承:子类继承父类。
(2)重写:在子类中重写从父类继承来的方法。
(3)向上转型:即父类引用指向子类对象,如:Parent p = new Child()。
下面根据下图具体举例说明:
首先:
父类Shape中有draw()方法,分别创建Circle类、Triangle类、Square类作为子类继承(extends)父类Shape。Circle类、Triangle类、Square类 继承父类Shape 后,也分别含有了 从父类Shape中继承来的draw()方法。
之后:
分别在Circle类、Triangle类、Square类 中对继承来的“ draw() 方法” 进行重写,使得不同 子类 中的draw() 方法实现不同功能,如下所示:
Circle类 中 draw() 方法 ---->> 实现 绘制 “圆”;
Triangle类 中 draw() 方法 ---->> 实现 绘制 “三角形”;
Square类 中 draw() 方法 ---->> 实现 绘制 “正方形”;
当通过Shape s = new Circle() 或 Shape s = new Triangle() 、Shape s = new Square() 语句创建父类Shape对象 s 时,子类Circle、Triangle、Square 会自动“向上转型”到父类,之后父类引用会指向子类,从而调用不同子类中的draw()方法,实现不同功能,实现多态。
上述 同时满足了“继承、重写、向上转型”三个条件,从而实现了多态。
4.代码实例测试
//定义主类 Test,进行测试
public class Test {
public static void main(String[] args) {
show(new Cat()); //用Cat对象初始化父类Animal并调用定义的show方法
show(new Dog()); //用Dog对象初始化父类Animal并调用定义的show方法
Animal a = new Cat();//向上转型,Cat类对象初始化父类Animal
a.eat();//父类引用指向子类Cat,调用Cat类中的eat()方法
Cat c = (Cat)a;//新建Cat类对象c,将对象a强制转换为Cat类对象,即向下转型
c.work();//向下转型后c为Cat类对象,调用的是Cat类中的work()方法
}
//定义show函数
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { //是否是Cat类对象
Cat c = (Cat)a;//强制转换
c.work();
} else if (a instanceof Dog) { //是否是Dog类对象
Dog c = (Dog)a;//强制转换
c.work();
}
}
}
//定义抽象类 Animal
abstract class Animal {
abstract void eat();//抽象方法,无函数体
}
//定义子类Cat,并继承父类Animal
class Cat extends Animal {
//实现父类中的 eat()方法
public void eat() {
System.out.println("1.Cat eat()-->>>猫喜欢吃鱼");
}
//新增方法
public void work() {
System.out.println("2.Cat work()-->>>猫的工作是抓老鼠");
}
}
//定义子类Dog,并继承父类Animal
class Dog extends Animal {
//实现父类中的 eat()方法
public void eat() {
System.out.println("1.Dog eat()-->>>狗喜欢吃骨头");
}
//新增方法
public void work() {
System.out.println("2.Dog work()-->>>狗的工作是看家");
}
}
5.运行结果
写在最后:
如果仍有疑问可以留言哦。