1、多态概述
在同一个方法中,由于参数类型不同而导致执行效果各异的现象就是多态。在Java中为了实现多态,允许使用一个父类类型的变量来引用一个子类类型的对象,根据被引用子类对象的特征的不同,得到不同的运行结果。
例:
// 定义接口Anmal
interface Animal {
void shout(); // 定义抽象shout()方法
}
// 定义Cat类实现Animal接口
class Cat implements Animal {
// 实现shout()方法
public void shout() {
System.out.println("喵喵……");
}
}
// 定义Dog类实现Animal接口
class Dog implements Animal {
// 实现shout()方法
public void shout() {
System.out.println("汪汪……");
}
}
// 定义测试类
public class Example13 {
public static void main(String[] args) {
Animal an1 = new Cat(); // 创建Cat对象,使用Animal类型的变量an1引用
Animal an2 = new Dog(); // 创建Dog对象,使用Animal类型的变量an2引用
animalShout(an1); // 调用animalShout()方法,将an1作为参数传入
animalShout(an2); // 调用animalShout()方法,将an2作为参数传入
}
// 定义静态的animalShout()方法,接收一个Animal类型的参数
public static void animalShout(Animal an) {
an.shout(); // 调用实际参数的shout()方法
}
}
从运行结果可以看出,多态不仅解决了方法同名的问题,还使程序变得更加灵活,有效提高程序的可拓展性和可维护性。
2、对象的类型转换
将子类对象当作父类使用时不需要任何显式地声明,需要注意的是,此时不能通过父类变量去调用子类中的某些方法。
例:
// 定义Animal接口
interface Animal {
void shout(); // 定义抽象方法shout()
}
// 定义Cat类实现Animal接口
class Cat implements Animal {
// 实现抽象方法shout()
public void shout() {
System.out.println("喵喵……");
}
// 定义sleep()方法
void sleep() {
System.out.println("猫睡觉……");
}
}
// 定义测试类
public class Example14 {
public static void main(String[] args) {
Cat cat = new Cat(); // 创建Cat类的实例对象
animalShout(cat); // 调用animalShout()方法,将cat作为参数传入
}
// 定义静态方法animalShout(),接收一个Animal类型的参数
public static void animalShout(Animal animal) {
animal.shout(); // 调用传入参数animal的shout()方法
animal.sleep(); // 调用传入参数animal的sleep()方法
}
}
运行该代码就会报错,原因在于运行到 animal.sleep(); 这段代码时,发现Animal类中没有定义sleep()方法。由于传入的对象是Cat类型,在Cat类中定义了sleep()方法,通过Cat类型的对象调用sleep()方法是可行的。例如:
public static void animalShout(Animal animal) {
Cat cat = (Cat)animal; //将animal对象强制转换为Cat类型
cat.shout(); //调用cat的shout()方法
cat.sleep(); //调用cat的sleep()方法
}
如果调用animalShout()方法时传入一个Dog类型的对象,这时进行强制类型转换就会出错。
例:
// 定义测试类
public class Example14 {
public static void main(String[] args) {
Dog dogt = new Dog(); // 创建Dog类的实例对象
animalShout(dog); // 调用animalShout()方法,将dog作为参数传入
}
// 定义静态方法animalShout(),接收一个Animal类型的参数
public static void animalShout(Animal animal) {
Cat cat = (Cat)animal; //将animal对象强制转换为Cat类型
cat.shout(); //调用cat的shout()方法
cat.sleep(); //调用cat的sleep()方法
}}
为了防止这种情况,Java提供了一个关键字instanceof,它可以判断一个对象是否为某个类(或接口)的实例或者子类实例。语法:
对象(或者对象引用变量)instanceof类(或接口)
修改上述代码:
public static void animalShout(Animal animal) {
if(animal instanceof Cat){ //判断animal是否是Cat类的实例对象
Cat cat = (Cat)animal; //将animal对象强制转换为Cat类型
cat.shout(); //调用cat的shout()方法
cat.sleep(); //调用cat的sleep()方法
}else{
System.out.println("this aminal is not a cat");
}
}