• Java 多态


    多态是同一个行为具有多个不同表现形式或形态的能力。

    多态性是对象多种表现形式的体现。

    比如我们说"宠物"这个对象,它就有很多不同的表达或实现,比如有小猫、小狗、蜥蜴等等。那么我到宠物店说"请给我一只宠物",服务员给我小猫、小狗或者蜥蜴都可以,我们就说"宠物"这个对象就具备多态性

    在Java中,所有的对象都具有多态性,因为任何对象都能通过IS-A测试的类型和Object类。

    多态存在的三个必要条件
    一、要有继承;
    二、要有重写;
    三、父类引用指向子类对象。

     多态的好处

    1.可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
    2.可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
    3.接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。
    4.灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。
    5.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。

    多态的概念

      不要把函数重载理解为多态。

      因为多态是一种运行期的行为,不是编译期的行为。

      多态:父类型的引用可以指向子类型的对象。

      比如 Parent p = new Child();

        当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;

        如果有,再去调用子类的该同名方法。

        (注意此处,静态static方法属于特殊情况,静态方法只能继承,不能重写Override,如果子类中定义了同名同形式的静态方法,它对父类方法只起到隐藏的作用。调用的时候用谁的引用,则调用谁的版本。)

      如果想要调用子类中有而父类中没有的方法,需要进行强制类型转换,如上面的例子中,将p转换为子类Child类型的引用。

      因为当用父类的引用指向子类的对象,用父类引用调用方法时,找不到父类中不存在的方法。这时候需要进行向下的类型转换,将父类引用转换为子类引用。   

    class Animal{
        public void sing() {
            System.out.println("Animal is singing!");
        }
    }
    
    class Dog extends Animal{
        public void sing(){
            System.out.println("Dog is singing!");
        }
    }
    
    class Cat extends Animal{
        public void sing(){
            System.out.println("Cat is singing!");
        }
        public void eat(){
            System.out.println("Cat is eating!");
        }
    }
     1 多态示例代码
     2 
     3 public class PolyTest{
     4 
     5     public static void main(String[] args){
     6         
     7         //向上类型转换
     8         Cat cat = new Cat();
     9         Animal animal = cat;
    10         animal.sing();
    11 
    12                 
    13         //向下类型转换
    14         Animal a = new Cat();
    15         Cat c = (Cat)a;
    16         c.sing();
    17         c.eat();
    18 
    19 
    20         //编译错误
    21         //用父类引用调用父类不存在的方法
    22         //Animal a1 = new Cat();
    23         //a1.eat();
    24         
    25         //编译错误
    26         //向下类型转换时只能转向指向的对象类型        
    27         //Animal a2 = new Cat();
    28         //Cat c2 = (Dog)a2;
    29 
    30     }
    31 }

    例子的执行结果:

    两种类型的类型转换

      (1)向上类型转换(Upcast):将子类型转换为父类型。

      对于向上的类型转换,不需要显示指定,即不需要加上前面的小括号和父类类型名。

      

      (2)向下类型转换(Downcast):将父类型转换为子类型。

      对于向下的类型转换,必须要显式指定,即必须要使用强制类型转换。

      

      并且父类型的引用必须指向子类的对象,即指向谁才能转换成谁。

      不然也会编译出错:

      因为父类引用指向的是Cat类的对象,而要强制转换成Dog类,这是不可能的。

      多态学习的第二部分,抽象类和接口:http://www.cnblogs.com/mengdd/archive/2012/12/25/2832656.html

      

    转自:http://www.cnblogs.com/mengdd/archive/2012/12/25/2832288.html

  • 相关阅读:
    Yslow-23条规则
    ASP.Net MVC多语言
    Java笔记--反射机制
    Java笔记--常用类
    Java笔记--多线程
    Java--IO流
    Java笔记--枚举&注解
    Java笔记--泛型
    Java笔记--异常
    Java笔记--集合
  • 原文地址:https://www.cnblogs.com/jkguo/p/5083285.html
Copyright © 2020-2023  润新知