一、引言
Java中的多态是一种非常重要的特性,它允许我们使用父类类型的变量来引用子类类型的对象。这种灵活性使得我们可以编写出更加通用的代码,使得代码的可扩展性和可维护性更强。
二、多态
(1)概念
父类引用指向子类对象
(2)语法
父类引用=子类对象;
父类类名 引用名=new 子类类名();
Animal a1 = new Dog();//狗对象是一个动物
Animal a2 = new Cat();//猫对象是一个动物
(3)使用
-
实际创建的是子类对象
-
优先执行子类内容
-
父类引用无法访问子类独有内容
编译器关注的是引用类型
解释器关注的是实际对象类型
-
右侧类型决定了是什么,左侧类型决定了能做什么
(4)引用类型间的相互转换
父类-大类型
子类-小类型
1.自动类型转换
父类引用=子类对象|子类引用
2.强制类型转换
子类类名 引用名=(子类类名)父类引用名;
//利用多态创建一个子类对象
Animal a = new Dog();
a.eat();
a.sleep();
//调用看门方法 Dog类的引用.lookDoor()
//将a引用类型强转为Dog类型
Dog dog = (Dog) a;
dog.lookDoor();
在多态的前提下,必须先将父类引用强转为子类类型才能访问子类独有内容
-
只能转向父类引用原本指向的子类类型. 编译不报错,运行报错
Animal a=new Dog(); Cat cat=(Cat)a; //会报出ClassCastException异常:类型转换出错
-
同级子类之间不可进行强转. 编译报错
Dog d=new Dog(); Cat c=(Cat)d;//错误!
3.强制类型转换案例
//有Animal,Dog,Cat,JinMao四个类。
//Dog和Cat类是Animal类的子类,JinMao类是Dog类的子类。
//有一个测试类Test。
public class Test{
public static void main(String[] args){
Animal a = new JinMao();//正确,子类可以为间接子类
Animal a = new Dog();
JinMao jm = (JinMao)a;//解释器报错,a为Dog类,无法赋给他的子类JinMao
Animal a = new JinMao ();
Dog d = (Dog)a; //正确,相当于改变了多态的引用(间接引用->直接引用)
}
}
三、多态的使用场景
1. 用于容器. 将容器类型声明为大类型, 则内部可以存放不同的小类型对象
//创建数组存放若干个狗对象和猫对象
Dog d1 = new Dog();
Dog d2 = new Dog();
Dog d3 = new Dog();
Cat c1 = new Cat();
Cat c2 = new Cat();
Cat c3 = new Cat();
Animal[] as = {d1, d2, d3, c1, c2, c3};
//Animal as[0]=new Dog();
//Animal as[3]=new Cat();
//遍历数组
for (int i = 0; i < as.length; i++) {
as[i].eat();
}
2. 用于参数: 将形参类型声明为大类型, 则实参可以为不同的小类型对象
public static void main(String[] args) {
Dog d1 = new Dog();
Cat c1 = new Cat();
method(d1);//狗吃大骨头
method(c1);//猫吃小鱼干
}
//定义一个函数, 传入参数,要求可以执行出"狗吃大骨头"或者"猫吃小鱼干"
public static void method(Animal a) {//Animal a=new Dog(); Animal a=new Cat();
a.eat();
}
3. 用于返回值: 将返回值类型声明为大类型, 则可以return返回不同的子类对象
public static void main(String[] args) {
Animal a= method3(11);//a=new Dog()
a.eat();
}
//定义一个函数, 传入一个整型参数n,要求n为偶数返回Dog对象,否则返回Cat对象
public static Animal method3(int n) {
if (n % 2 == 0) {
return new Dog();
}
return new Cat();
}
四、instanceof关键字
- 作用为判断引用是否与指定类型兼容
引用名 instanceof 类名
注:执行结果为boolean类型
Animal a= method3(12);
//如果返回的是狗对象,则调用看门方法,如果是猫对象,则调用吃饭方法
//判断a是否与Dog兼容
if (a instanceof Dog) {
//将a引用强转为Dog类型引用
Dog d = (Dog) a;
//调用看门方法
d.lookDoor();
} else {
//调用吃饭
a.eat();
}
使用
-
大类型可以兼容小类型,但是小类型无法兼容大类型
-
同级子类之间不可兼容
Dog jm = new JinMao();
System.out.println(jm instanceof JinMao);//t
System.out.println(jm instanceof Dog);//t
System.out.println(jm instanceof Animal);//t
//System.out.println(jm instanceof Cat);
Animal a = new Dog();
System.out.println(a instanceof Dog);//t
System.out.println(a instanceof Animal);//t
System.out.println(a instanceof JinMao);//f
System.out.println(a instanceof Cat);//f
五、结语
Java中的多态是一种非常强大的特性,它可以使我们的代码更加灵活和可扩展。通过使用instanceof关键字,我们可以判断对象的类型,从而编写出更加健壮的代码。当我们在编写Java程序时,应该充分利用多态的优势,并注意使用instanceof关键字来确保代码的正确性。