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());
	}
}
原文地址:https://www.cnblogs.com/cj5785/p/10664863.html