Java 多态性
------------恢复内容开始------------
------------恢复内容开始------------
1.理解多态性:多态是一个事务的多种形态。
2.何为多态性?
对象的多态性:一个父类的引用指向子类的对象。
这句话太抽象了,用汉语结构拆分开就是 “引用 指向 对象”,这也还是很抽象
直接看个例子
先写一个Person类 ,定义方法eat & walk
package Poly; public class Person { String name; int id; public void eat(){ System.out.println("恰饭"); } public void walk(){ System.out.println("walking"); } }
再用继承一个Man类 和 Women类
package Poly; public class Man extends Person{ public void eat(){ System.out.println("man 恰饭"); } public void walk(){ System.out.println("man walking"); } public void EarnMoney(){ System.out.println("earning.."); } }
package Poly; public class Women extends Person{ public void eat(){ System.out.println("women 恰饭"); } public void walk(){ System.out.println("women walking"); } public void shop(){ System.out.println("shopping..."); } }
编写一个Test测试类,一般的我们引用 和 对象是相一致的就如下面example1一样,而多态就是example2
package Poly; public class PolyTest { public static void main(String[] args) { //example1 Person p1 = new Person(); p1.eat(); p1.walk(); //example2 Person p2 = new Man(); //1 p2.walk(); //2 p2.eat(); //3 // p2.EarnMoney(); } }
运行结果如下:

example1的结果不用解释
可以看到example2的结果是子类重写的方法的运行结果
并且3是无法编译通过的,原因是Person中并没有EarnMoney这个方法。
由此我们可以得出 多态必须基于继承 & 重写上,
并且编译时,方法是父类中定义的,而结果确是子类重写方法运行的。 即“编译时看左,执行时看右”。这便是虚拟方法调用
由此可以理解多态性的前提:①继承 ②方法重写
3.为什么要有多态性?
看了2之后还是很抽象,只是知道了多态性是怎么回事,它的意义在哪?
看下面这个例子
定义Animal类 , 子类为Dog & Cat
class Animal{ public void shout(){ System.out.println("aaaa"); } public void eat(){ System.out.println("eating..."); } } class Dog extends Animal{ public void shout(){ System.out.println("汪!汪!汪!"); } public void eat(){ System.out.println("吃骨头"); } } class Cat extends Animal{ public void shout(){ System.out.println("miao miao miao"); } public void eat(){ System.out.println("吃猫粮"); } }
很明显,这符合多态性的两个前提 : 继承 & 方法重写
我们写一个方法测试这两个子类的方法
public static void main(String[] args) { PolyTest test = new PolyTest(); test.func(new Dog()); test.func(new Cat()); } public void func(Animal animal){//Animal animal = new Dog(); //Animal animal = new Cat(); animal.eat(); animal.shout(); }
在调用func的时候 ,很自然的会这么写:
test.func(new Dog());
test.func(new Cat());
实质上 在背后,相当于执行了
Animal animal = new Dog(); Animal animal = new Cat();
这不就是多态吗?
如果没有多态,我们只能这样写
public void func1(Dog dog){ dog.eat(); dog.shout(); } public void func2(Cat cat){ cat.eat(); cat.shout(); }
明显的,多态减少了代码的冗余,实质上,我们在编写代码的过程中,无意中就使用了多态
例如: 在JDBC中 ,我们总是会 Connection conn = new MySQLConnection(); .. 这也是多态
值得指出的是属性是没有多态性的
4、多态性是运行时行为
经典的例子是在main方法中写一个随机数 随机选择子类对象,多次运行会得到不同的结果。
5、内存空间问题
有了对象的多态性以后,内存中(堆)实际上是加载了子类的所有属性和方法的,但是由于声明是父类类型,所以子类的特有的属性和方法是不能被调用的。
如何才能实现调用呢?
将父类强制类型转换为子类 也叫向下转型
相反的,子类转换为父类称为向上转型。 有点眼熟?。 一般地,我们直接称为“多态”
在同级子类中,强制类型转换有可能会出现问题。
6、instanceof关键字使用
a instanceof A 判断对象a是否为类A的实例,是返回true,否则否则返回false
使用此关键字可以判断,避免向下转型时出现ClassCastExecption异常。
------------恢复内容结束------------
浙公网安备 33010602011771号