对象的多态性
- 以代码为示例 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17- public class Animals { 
 public void speak(){
 System.out.println("i am animals");
 }
 }
 public class Cat extends Animals{
 public void speak(){
 System.out.println("i am cat");
 }
 }
 public class Test {
 public static void main(String[] args){
 //一个对象,两种形态
 Animals cat = new Cat();
 cat.speak();
 }
 }
- 运行后的结果为”i am cat” 
- 猫这类事物既具备猫的形态,又具备动物形态,这就是对象的多样性,简单说,一个对象对应着多种类型
- 多态在代码中的体现- 父类或者接口的引用指向了其子类的对象
 
多态的好处
- 提高了代码扩展性,前期定义的代码可以使用后期的内容。 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33- public abstract class Animals { 
 public abstract void eat();
 }
 public class Cat extends Animals{
 public void eat(){
 System.out.println("吃鱼");
 }
 public void catchMouse(){
 System.out.println("抓老鼠");
 }
 }
 public class Dog {
 public void eat(){
 System.out.println("啃骨头");
 }
 public void guardDoor(){
 System.out.println("看门");
 }
 }
 public class Test {
 public static void main(String[] args){
 Cat c1 = new Cat();
 Dog d1 = new Dog();
 Dog d2 = new Dog();
 method(c1);
 method(d1);
 method(d2);
 }
 public static void method(Animals a){
 a.eat();
 }
 }
- 如上图所示代码,如果很多只猫,很多只狗,为了代码复用性,需要在主类中定义一个方法,可是如果动物种类很多,是否要定义不同参数的许多方法那,答案是不用的,只需要定义个参数为Animals对象的即可 
多态的局限性及前提
- 前期定义的内容,不能调用后期子类定义的特有内容
- 多态的前提- 必须有关系,继承,实现
- 要有覆盖
 
多态转型
- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15- //自动类型提升,猫对象提升了动物类型,但特有功能无法访问 
 //作用就是限制对猫特有功能的访问
 //专业讲就是 向上转型,将子类型隐藏,就不用使用子类的特有方法
 Animals a = new Cat();
 a.eat();
 //如果还想访问具体动物的特有功能
 //可以进行向下转型
 Cat c = (Cat)a;//向下转型目的:为了使用子类中的特有方法
 c.eat();
 c.catchMouse();
 //错误示例
 Animals a1 = new Dog();
 Cat c1 = (Cat)a1; //ClassCastException类型转换异常
- 注意:对于转型来说,自始至终都是子类对象在做着类型的变化 
类型判断
- 还是以之前的代码为示例,如果method方法内想进行输出猫,狗的特有功能该怎么做那?1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12public void method(Animals a){ 
 a.eat();
 if(a instanceof Cat){
 //instanceof:用于判断对象的具体类型,只能用于引用数据类型判断
 //通常在向下转型前用于健壮性的判断
 Cat c = Cat(a);
 c.catchMouse();
 }else if(a instanceof dog){
 Dog d = Dog(a);
 d.guardDoor();
 }
 }
多态时成员特点
成员变量
- 编译时:参考引用型变量所属的类中是否有调用的成员变量,有则编译通过,没有则编译失败
- 运行时:参考引用型变量所属的类中是否有调用的成员变量,并运行该所属类中的成员变量
- 编译和运行都参考左边,如 animals a = new Cat();
成员函数(非静态)
- 编译时:参考引用型变量所属的类中是否有调用的函数,有则编译通过,没有则编译失败
- 运行时:参考对象所属的类中是否有调用的函数,
- 简单说:编译看左边,运行看右边 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14- public class Father { 
 public void show(){
 System.out.println("i am father");
 }
 }
 public class Son extends Father{
 public void show() {
 System.out.println("i am son");
 }
 }
 public class Test(){
 Father f = new Son();
 f.show();
 }
- 运行后的结果 i am son 
静态函数
- 编译时:参考引用型变量所属的类中是否有调用的静态方法,有则编译通过,没有则编译失败
- 运行时:参考对象所属的类中是否有调用的静态方法
- 简单说:编译和运行都看左边
- 其实对于静态方法,是不需要对象的,直接类名调用即可 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14- public class Father { 
 public static void show(){
 System.out.println("i am father");
 }
 }
 public class Son extends Father{
 public static void show() {
 System.out.println("i am son");
 }
 }
 public class Test(){
 Father f = new Son();
 f.show();
 }
- 运行结果为 i am father