一、多态的语法
关于java语言中的向上转型和向下转型
1、向上转型(upcasting):子 -->父
2、向下转型(downcasting)父-->子
注意:无论向下向上转型,两个类之间一定要有继承关系。
举个栗子:
父类Animal:
public class Animal {
public void eat() {
System.out.println("eat");
}
}
子类Dog:
public class Dog extends Animal{
public void eat() {
System.out.println("dog eat bone");
}
}
子类Cat:
public class Cat extends Animal{
public void eat() {
System.out.println("cat eat fish");
}
// cat 特有的方法
public void move() {
System.out.println("cat move");
}
}
测试类Test:
注意:好好看注释哦 >-<
public class Test{
public static void main(String[] args) {
// 向上转型,又被称作自动类型转换
// 父类型的引用指向子类型对象
// 程序分为两个阶段:编译阶段,运行阶段。
// 程序编译阶段只知道a1是一个Animal类型
// 程序运行阶段,堆中的实际对象是Cat
Animal a1 = new Cat();
// 程序在编译阶段a1被编译器看做Animal类型
// 所以程序在编译阶段a1引用绑定的是Animal类中的eat方法(静态绑定)
a1.eat(); // 输出:cat eat fish
// 程序在运行的时候堆中的对象实际上是Cat类型,而Cat已经重写了eat方法
// 所以程序在运行阶段,对象的绑定的方法是Cat中的eat方法(动态绑定)
// 向下转型:强制类型转换
Animal a2 = new Cat(); // 向上转型
//要执行move方法,怎么做?
// a2.move(); 编译不通过(因为在编译期时,系统认为Animal类中没有move方法)
// 所以要强制类型转换,需要加强制类型转换符
Cat c1 = (Cat)a2;
c1.move(); // 输出:cat move
// 判断一下程序运行时出现什么问题?
// Animal a3 = new Dog(); // 向上转型
//
// 强制类型转换
// Cat c2 = (Cat)a3; // java.lang.ClassCastException类型转换异常
//在做强制类型转换时,程序是存在风险的!
// 为了避免ClassCastException的发生,java引入了instanceof
/*
用法:
1、instanceof运算符的运算结果是boolean类型
2、(引用 instanceof 类型) --> true/false
例如: (a instanceof Cat)如果结果是true表示:a指向堆中的java对象是Cat类型
*/
Animal a3 = new Dog();
// 推荐:在向下转型的时候要使用instanceof运算符判断,避免ClassCastException
if(a3 instanceof Cat) { // false
Cat c2 = (Cat)a3; // 没执行哦
}
}
}
再次强调:
instanceof用法:
1、instanceof运算符的运算结果是boolean类型
2、(引用 instanceof 类型) --> true/false
例如: (a instanceof Cat)如果结果是true表示:a指向堆中的java对象是Cat类型
二、多态的好处
我们先举栗子:
模拟主人投喂宠物:
测试类Test
public class Test{
public static void main(String [] args) {
// 1、创建主人
Person hl = new Person();
// 2、创建宠物
Dragon d = new Dragon();
Fox f = new Fox();
// 3、喂养
hl.feed(d);
hl.feed(f);
// 我们发现:person类型的扩展能力太差
}
}
主人Person类:
public class Person {
// 喂养
public void feed(Dragon d) {
d.eat();
}
public void feed(Fox f) {
f.eat();
}
宠物Dragon类:
public class Dragon{
public void eat() {
System.out.println("Dragon eat");
}
}
宠物Fox类:
public class Fox extends Animal{
public void eat() {
System.out.println("fox eat");
}
}
输出:Dragon eat fox eat
评价:通过此例子,我们发现,主人person每增加一个宠物都会使用一次feed()并传递对象,使代码的耦合度提高,扩展能力差。
我们使用多态来解决这个问题:
测试类Test
public class Test{
public static void main(String [] args) {
// 1、创建主人
Person hl = new Person();
// 2、创建宠物
Dragon d = new Dragon();
Fox f = new Fox();
// 3、喂养
hl.feed(d);
hl.feed(f);
}
}
主人Person类:
public class Person {
public void feed(Animal a) { // Animal a = d or f 多态哦!
a.eat();
}
// 尽量不要面向具体编程,面向父类编程,面向抽象编程
}
父类Animal:
public class Animal {
public void eat() {
}
}
子类Dragon
public class Dragon extends Animal{
public void eat() {
System.out.println("Dragon eat");
}
}
子类Fox
public class Fox extends Animal{
public void eat() {
System.out.println("fox eat");
}
}
输出:Dragon eat
fox eat
总结多态的作用:
1、使用多态可以使代码之间的耦合度降低
2、项目的扩展能力增强
sky
网友评论