zoukankan      html  css  js  c++  java
  • 面向对象的三大特征之三——多态

    多态,简单来说就是一种类型表现出多种状态。在Java中多态分为两类。

    一、方法多态性——方法的重载和重写。

    关于这部分内容已经在前面的内容有过详细的记录,即重复调用的代码块—方法面向对象的特性之二—继承

    二、对象的多态性——引用类型转换。

    1.向上转型(自动转型)——子类对象自动转换为父类对象。

     1 class Father
     2 {
     3     public void speak()
     4     {
     5         System.out.println("我来自父类Father。");
     6     }
     7 }
     8 class Son extends Father
     9 {
    10     public void speak()
    11     {
    12         System.out.println("我来自子类Son。");
    13     }
    14 }
    15 class Daughter extends Father
    16 {
    17     public void speak()
    18     {
    19         System.out.println("我来自子类Daughter。");
    20     }
    21 }
    22 public class T02
    23 {
    24     public static void main(String[] args)
    25     {
    26         Father p;
    27         Son s = new Son();
    28         Daughter d = new Daughter();
    29         p=s;//子类对象向上类型转换为Father类型
    30         p.speak();
    31         p=d;
    32         p.speak();
    33     }
    34 }

    输出结果如下:

    我来自子类Son。
    我来自子类Daughter。

    可以看出,第26行声明了一个父类对象p,但没有实例化;第27、28行分别声明子类对象s、d并实例化;经过赋值操作,将子类对象向上转型为Father类型。通过p调用其speak方法,实际输出的是子类对象的speak方法。这里就体现了多态性思想。

    需要注意的是:上述父类对象只能调用被子类重写的方法,对于子类自己独有的方法,父类对象是无法访问的。

     1 class Father
     2 {
     3     public void speak()
     4     {
     5         System.out.println("我来自父类Father。");
     6     }
     7 }
     8 class Son extends Father
     9 {
    10     public void speak()
    11     {
    12         System.out.println("我来自子类Son。");
    13     }
    14     public void print()
    15     {
    16         System.out.println("我是Tom。");
    17     }
    18 }
    19 public class T02
    20 {
    21     public static void main(String[] args)
    22     {
    23         Father p;
    24         Son s = new Son();
    25         p=s;//子类对象向上类型转换为Father类型
    26         p.speak();
    27         p.print();//错误的,无法访问
    28     }
    29 }

    那么如果非要调用子类的print()方法,那么就要用到下面的向下强制转型,将父类对象赋值给子类对象。

    2.向下转型(强制转型)——父类对象强制转换为子类对象。

     1 class Father
     2 {
     3     public void speak()
     4     {
     5         System.out.println("我来自父类Father。");
     6     }
     7 }
     8 class Son extends Father
     9 {
    10     public void speak()
    11     {
    12         System.out.println("我来自子类Son。");
    13     }
    14     public void print()
    15     {
    16         System.out.println("我是Tom。");
    17     }
    18 }
    19 public class T02
    20 {
    21     public static void main(String[] args)
    22     {
    23         Father p = new Son();
    24         p.speak();//自动类型转换
    25         ((Son) p).print();//强制类型转换
    26     }
    27 }

    如果同时存在多个子类,就需要使用instanceof关键字来检测转换的安全性,即在每次转换之前都加上一个if判断语句:

    if(p instanceof Son)
    {
         Son s1 = (Son)p();
    }else
    {
         System.out.println("无法转换!");
    }

    3.隐藏——static无法被重写的特性。

    当我们不想调用子类中重写的方法,而希望调用父类中原来的方法时,就可以使用隐藏来实现。

     1 class Father
     2 {
     3     public static void speak()
     4     {
     5         System.out.println("我来自父类Father。");
     6     }
     7 }
     8 class Son extends Father
     9 {
    10     public static void speak()
    11     {
    12         System.out.println("我来自子类Son。");
    13     }
    14 }
    15 public class T02
    16 {
    17 
    18     public static void main(String[] args)
    19     {
    20         Father p = new Son();
    21         p.speak();//调用的是父类中的speak()方法
    22     }
    23 }

    输出结果:我来自父类Father。

    看似简单的知识背后,承载的是收获和成长!
  • 相关阅读:
    分享:liblfds 6.1.0 发布,C 数据结构库
    strchr C++ Reference
    爱上MVC3系列~PartialView中的页面重定向
    基础才是重中之重~Conditional特性使代码根据条件在debug或者release模式中执行
    爱上MVC3系列~Html.BeginForm与Ajax.BeginForm
    爱上MVC3系列~Razor页面中的共享namespace不起作用了(解决自定义扩展方法不能识别的问题)
    爱上MVC3系列~RenderAction与RenderPartial及一个页面多个表单提交
    NHibernate Criteria中的And, Or
    poj 2528 Mayor's posters(线段树区点)
    探索iptables BPF模块的悲惨历程
  • 原文地址:https://www.cnblogs.com/wxywxy/p/6714614.html
Copyright © 2011-2022 走看看