• Java学习笔记-多态


    面向对象三大特征之一,编译类型和运行类型不一致,这种现象叫做多态

    定义

    某一类事物的多种存在形态

    • 例:动物中猫,狗
    • 猫这个对象对应的类型是猫类型
      • 猫x = new 猫();
    • 同时猫也是动物中的一种,也可以把猫称为动物
      • 动物 y = new 猫();
      • 动物是猫和狗具体事物中抽取出来的父类型
      • 父类型引用指向了子类对象

    理解

    体现:父类或者接口的引用指向或者接收自己的子类对象

    作用:多态的存在提高了程序的扩展性和后期可维护性

    前提:

    • 需要存在继承或者实现关系
    • 要有覆盖操作

    好处:多态的出现大大的提高程序的扩展性

    弊端:提高了扩展性,但是只能使用父类的引用访问父类中的成员

    特点

    非静态成员函数:

    • 编译时:要查看引用变量所属的类中是否有所调用的成员
    • 在运行时:要查看对象所属的类中是否有所调用的成员

    成员函数在多态调用时,编译看左边,运行看右边

    成员变量:

    • 只看引用变量所属的类

    静态成员:

    • 只看引用变量所属的类

    多态

    class BaseClass{···}
    class SubClass extends BaseClass{···}
    ···
    BaseClass bc = new SubClass();
    ···
    
    • 在上述示例中,将子类的对象赋值给父类,这叫做向上转型,由系统自动完成。bc在编译时候属于BaseClass类型,而运行时候则为SubClass类型,这就出现了多态。当bc调用实例变量时,将调用父类的实例变量,这是由于对象的实例变量不具备多态性,bc只可以调用父类中存在的方法,但是是在子类中调用,若子类重写了父类的方法,那么调用的就是被重写后的方法,如果没被重写,那么就直接调用继承到的方法,对于仅仅存在于子类中的方法,若使用bc去调用,那么则会编译报错

    • 多态:相同类型的变量、调用同一个方法时呈现出多种不同的行为特征,这就是多态

    • 引用类型之间的转换只能在具有继承关系的两个类型之间,如果试图把一个父类实例转化成子类类型,则这个对象必须实际上是子类类型才可以(即编译类型为父类类型,而运行类型为子类类型)

    • instanceof:为了避免ClassCastException异常,使用instanceof先进行判断在进行类型转换。instanceof前一个操作数通常为一个引用类型变量,后一个操作数通常是一个类(也可以是接口),用于判断前面的对象是否是后面的类或者其子类、实现的实例。如果是则返回true,否则返回false。如果instanceof运算符前面的操作数的编译类型与后面的类不同,或者与后面的类不具备父子继承关系,则会引起编译错误

    if ( objPri instanceof String )
    {
    	String str = (String) objPri;
    }
    

    转型

    能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换
    多态自始至终都是子类对象在做着变化

    在多态中存在着转型操作,通常称为向上转型和向下转型
    例如存在Cat继承自Animal
    那么,将一个Cat对象赋值给Animal就属于向上转型

    Animal animal = new Cat(); //向上转型
    

    如果将父类引用转化为子类类型,这种现象称之为向下转型

    Cat cat = (Cat)animal; //向下转型
    

    instanceof关键字

    用于判断对象的类型

    格式:
    对象 intanceof 类型(类类型 接口类型)

    public static void func(Animal a) {
        if(a instanceof Cat){
            Cat c = (Cat)a;
            ···
        }
    }
    

    多态实例

    interface PCI {
    	public void open();
    	public void close();
    }
    
    class MainBoard{
    
    	public void run() {
    		System.out.println("mainboard run ");
    	}
    
    	public void usePCI(PCI p) {
    		if(p != null){
    			p.open();
    			p.close();
    		}
    	}
    }
    
    class NetCard implements PCI {
    
    	public void open() {
    		System.out.println("netcard open");
    	}
    
    	public void close(){
    		System.out.println("netcard close");
    		method();
    	}
    }
    
    class SoundCard implements PCI {
    
    	public void open() {
    		System.out.println("SoundCard open");
    	}
    
    	public void close() {
    		System.out.println("SoundCard close");
    	}
    }
    
    class Test 
    {
    	public static void main(String[] args) {
    		MainBoard mb = new MainBoard();
    		mb.run();
    		mb.usePCI(null);
    		mb.usePCI(new NetCard());
    		mb.usePCI(new SoundCard());
    	}
    }
    
  • 相关阅读:
    如何使用git提交代码
    Eclipse升级ADT
    android学习:android开发常见技巧设置,提高开发效率
    Apache -Common-lang包使用
    最全的常用正则表达式大全——包括校验数字、字符、一些特殊的需求等等
    Asp.Net MVC entity framework模型验证
    Activity启动模式
    http服务器交互get,put,post,delete等说明
    js模块化插件开发
    Android Asynchronous Http Client异步网络请求使用
  • 原文地址:https://www.cnblogs.com/cj5785/p/10664863.html
Copyright © 2020-2023  润新知