zoukankan      html  css  js  c++  java
  • 多态&instanceof关键字

    1.什么是多态?

      extends继承或者implements实现,是多态性的前提。

    注意:多态指的是对象的多态性,形态指的是类

     

    代码中体现多态性,其实就是一句话:父类引用指向子类对象

    格式:

    父类名称 对象名 = new 子类名称();

    或者:

    接口名称 对象名 = new  实现类名称();

     

     

     

     运行结果:

    栗子:

      动物 x=new 猫();//一个对象,两种形态

      new 猫()是子类对象x是父类的引用,这样父类的引用就指向了子类的对象,猫这类事物就既具备了猫的形态,又具备了动物的形态--多态性,就是一个对象对应着不同类型。

    2.多态中成员变量的使用特点

    成员变量是不能进行覆盖重写的

    如果在父子类的继承关系当中,如果成员变量重名,则创建子类对象时,访问有两种方式:

    (1)直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上找(即找它的父类中有没有成员变量)

     运行结果:

     下面来看一下怎么向上找

     当Fu中没有age这个变量,就向上找,找Fu的父类Object,发现也没有age,这样就报错,可以看到Fu并没有向下找其子类Zi。

     (2)间接通过成员方法访问,即访问成员方法,由于成员方法中有成员变量,这样就间接的访问到了成员变量。看该方法属于谁,优先使用谁,没有则向上找。

     运行结果:

     如果子类覆盖重写了成员方法,就是子

     运行结果:

     3.多态中成员方法的使用特点

    在多态的代码中,成员方法的访问规则是:看new的是谁,就优先用谁,没有则向上找

     

     

     口诀:编译看左边,运行看右边

    obj.method();  首先编译看左边,左边Fu里面有method,但是真正运行的时候,看的是右边,右边是Zi,当然是运行Zi了

    obj.methodFu();   首先编译看左边,左边Fu里面有methodFu,运行看右,右边的子类Zi中没有methodFu,当然是向上找。

     对比一下:

    成员变量:编译看左边,运行还看左边

    成员方法:编译看左边,运行看右边

    4.多态的作用

      消除类型之间的耦合关系。

      比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。

    5.多态存在的三个必要条件(必须是类与类之间的关系)

      要有继承;
      要有重写;
      父类引用指向子类对象。

    6.多态的好处与弊端

      (1)好处:可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。

     

     这样的好处就是:无论右边new的时候换成哪个子类对象,等号左边调用方法都不会改变

      (2)弊端:只能使用父类的引用访问父类中的成员。

    7.对象的多态性主要分为两种:

      (1)向上转型:子类对象——>父类对象(类型提升,自动完成,因为是低级向高级转变)其实就是多态的写法

        格式:父类  父类对象=子类实例

          如:A a=new B();(A-父类,B-子类)

      生活中的栗子:情景:一家父子,都是老师,都能讲课

             父亲 x=new 儿子();

             x.讲课();

      这个就是向上转型

      又如:Animal a=new Cat();//这是自动类型提升,猫对象提升到动物类型,就要按照动物的方式操作,而不能访问猫的特有功能catchMouse()

      作用:限制对特有功能的访问

    含义:右侧创建一个子类对象,把它当作父类来看待使用。

    Animal animal = new Cat();      创建了一只猫,当作动物看待,没问题

    注意事项:向上转型一定是安全的。从小范围转向了大范围。从小范围的猫,向上转型成为大范围的动物。

    类似于:

    double num = 100;   // 正确,int --->double,自动类型转换

    多态自始至终都是子类对象在做着变化,相当于子类去实例化父类对象,即父类知道有这么一个子类

    编译看左,就是看左边的有没有这个方法;运行看右,就是看右边的对象有没有这个方法,运行这个子类对象的方法。

      (2)向下转型:父类对象——>子类对象(强制转换,因为是高级向低级转换

      针对,向上转型中,Cat特有的catchMouse这个方法,由于向上转型成Animal,无法调用的问题。

    对象的向下转型,其实就是一个【还原】的动作

    格式:

    子类名称 对象名 = (子类名称) 父类对象;

    含义:将父类对象,【还原】成为本来的子类对象。

     Animal animal  = new Cat();  // 本来是猫,向上转型成为动物

    Cat cat = (Cat) animal;   // 本来是猫,已经被当作动物了,还原回来成为本来的猫

    注意事项:

    (1)必须保证对象本来创建的时候,就是猫,才能向下转型成为猫。

    (2)如果对象创建的时候本来不是猫,现在非要向下转型成为猫,就会报错。

     运行结果:

     类似于:

    int num = (int) 10.0;   // 可以

    int num = (int);   // 不可以,精度损失

    生活中的栗子:情景:一家父子,父亲都一把岁数了不可能还去看电影

              儿子 y=new 父亲();

              y.看电影();

      这个就是向下转型

        Cat c=(Cat) a;//向下转型,这样的目的是为了使用子类的特有功能

    8.instanceof关键字

    怎么知道父类的引用指向的对象【本来】是猫还是狗呢?

    向下转型一定要进行instanceof类型判断

    格式:

    对象名称 instanceof 类名称

    这将会得到一个boolean值结果,也就是判断前面的对象能不能当做后面类型的实例。

    9.Java中多态的实现方式:

      接口实现,继承父类进行方法重写,同一个类中进行方法重载。

    栗子1:(抽象类并不能直接用来产生对象,必须通过对象的多态性进行实例化操作

    abstract class Animal{
    	abstract void eat();
    }
    class Cat extends Animal{
    	public void eat(){
    		System.out.println("吃鱼");
    	}
    	public void catchMouse(){
    		System.out.println("抓老鼠");
    	}
    }
    class Dog extends Animal{
    	public void eat(){
    		System.out.println("吃骨头");
    	}
    	public void kanJia(){
    		System.out.println("看家");
    	}
    }
    class DuoTaiDemo{
    	public static void main(String[] args){
    		function(new Cat());
    		function(new Dog());//若以后还有什么动物加进来,可以直接function(new xxx()),与Animal a配合使用,就提高了扩展性。
    	}
    		public static void function(Animal a){//Animal a=new Cat()和Animal a=new Dog()
    			a.eat();//子类覆盖父类Animail类,只能使用父类的引用访问父类中的成员eat()方法
    			//a.catchMouse();这样就不对了,因为父类Animal中没有,不能覆盖
    		}
    }
    

    栗子2:向下转型

    class Base{}
    class Agg extends Base{
    	public String  getFeilds(){
    		String name="Agg";
    		return name;
    	}
    }
    public class Avf{
    	public static void main(String[] args){
    		Base a=new Agg();
    		System.out.println( ((Agg) a).getFeilds());//因为Base里面没有getFeilds方法,子类Agg中有,父类要利用子类的方法,就要进行强制转换,(Agg) a。
    	}
    }
  • 相关阅读:
    ehcache 详解 实例
    oscache ehcache oscache与ehcache的区别
    Nginx_lua
    Java程序员的发展前景
    JAVA MemCache 史无前例的详细讲解!看完包精通MEMCACHE!
    java ssl https 连接详解 生成证书
    使用django的ImageField和from制作上传图片页面
    1.python中的列表及其操作
    django分页
    django和javaweb的比较
  • 原文地址:https://www.cnblogs.com/GumpYan/p/5738609.html
Copyright © 2011-2022 走看看