多态概述
在同一个方法中,这种由于参数类型不同,而导致执行效果各异的现象就是多态。继承是多态得以实现的基础。
在Java中,为了实现多态,允许使用一个父类类型的变量来引用一个子类的对象,根据被引用子类对象的特征的不同,得到不同的运行结果。
**定义Animal接口**
```java
public interface Animal {
void shot();
}
Cat类继承Animal接口
public class Cat implements Animal {
@Override
public void shot() {
// TODO Auto-generated method stub
System.out.println("喵喵");
}
void sleep() {
System.out.println("猫睡觉");
}
}
Dog类基础Animal接口
public class Dog implements Animal {
@Override
public void shot() {
// TODO Auto-generated method stub
System.out.println("汪汪");
}
public static void sleep() {
System.out.println("狗睡觉");
}
}
测试类**
```java
public class AnimalTest {
public static void main(String[] args) {
Animal dog = new Dog();
Animal cat = new Cat();
dog.shot();
cat.shot();
}
}//OutPut:
汪汪
喵喵
对象的类型转换
在多态的学习中,涉及到将子类对象当作父类类型使用的情况,此种情况在Java的语言环境中成为“向上转型’,例如:
Animal an1 = new Cat();
Animal an2 = new Dog();
将子类对象当作父类使用时不需要任何显示的声明,需要注意的是,此时不能通过父类去调用子类的特有方法。
修改上面的测试类
public class AnimalTest {
public static void main(String[] args) {
Cat cat = new Cat();
animalShout(cat);
}
public static void animalShout(Animal animal){
animal.shout();
animal.sleep();
}
}
调用animalShout方法的同时传入了Cat类型的对象,而方法的参数类型为Animal类型,这便将Cat对象当作父类Animal类型使用。
在animalShout传入的对象是Cat类型的,在Animal中没有定义sleep方法,编译器就会报错,提示找不到sleep方法。但是通过Cat类型的对象调用sleep方法是可行的,因此可以在animalShout()方法中将Animal类型强转为Cat类型。
现将animalShout()方法进行修改:
public static void animalShout(Animal animal){
Cat cat = (Cat) animal;
cat.shout();
cat.sleep();
}
经过再次编译,程序没有报错。
这种将父类型当作子类型使用的情况,在Java的语言环境中被称为"向下转型"。
现将测试类修改如下:
public class AnimalTest {
public static void main(String[] args) {
Dog dog = new Dog();
animalShout(dog);
}
public static void animalShout(Animal animal){
Cat cat = (Cat) animal;
animal.shout();
animal.sleep();
}
}
此时会出错,出错的原因是,在animalShout()方法中,传入一个Dog对象,在强制类型转换时,Animal类型的变量无法强制转换为Cat类型。
这时候就需要引出Java的一个关键字 “instanceof”,它可以判断一个对象是否为某个类(或接口)的实列或者子类实例。
现再将animalShout()方法进行修改:
public static void animalShout(){
if(animal instanceof Cat){
Cat cat = (Cat) animal;
cat.sleep();
cat.shout();
}else{
System.out.println("This animal is not a Cat");
}
}//OutPut:this animal is not a cat