javaSE学习Day1之多态及向下转型
向下转型的使用
Java的多态性:
父类指向子类的声明
Animal animal = new Dog()//Dog()重写了父类Animal
- 有了对象的多态性以后,内存实际上加载的是子类的属性和方法,但是由于变量声明为父类类型,导致编译时只能调用父类的属性和方法,子类特有的属性方法不能调用。
- 调用子类特有的属性和方法:向下转型,使用强制类型转换符。
- 向下转型有风险,使用强转可能出现ClassCastException异常。为了避免出现异常,此时应该使用instanceof关键字。
向下转型在开发中使用较少,一般只会用父类中存在的属性方法。
因为多态性是运行时行为,但是在编译的时候就已经加载了子类的属性和方法,但是用不了子类的特有方法,例如Dog子类类特有的方法liugou(),编译就会报错。
//父类Animal:
class Animal{
public void eat(){
System.out.println("吃吃吃");
}
public void shout(){
System.out.println("叫叫叫");
}
}
//子类Dog
class Dog extends Animal{
@Override
public void shout() {
System.out.println("汪汪汪");
}
public void eat(){
System.out.println("吃狗粮");
}
//子类特有方法lugou()
public void liugou(){
System.out.println("遛狗");
}
}
class Cat extends Animal{
@Override
public void shout(){
System.out.println("喵喵喵");
}
public void eat(){
System.out.println("吃鱼");
}
public void hand(){
System.out.println("手贱");
}
}
调用子类特有方法报错
public class AnimalTest {
public static void main(String[] args){
AnimalTest test = new AnimalTest();
test.func(new Dog());
}
public void func(Animal animal){
animal.eat();
animal.liugou();//子类特有方法报错
}
}
向下转型(强制类型转换):
public void func(Animal animal){
animal.eat();
Dog dog = (Dog) animal;//使用强制类型转换,不报错
dog.liugou();
}
向下转型的风险(编译时可以通过,运行时出现ClassCastException异常):
public void func(Animal animal){
animal.eat();
Dog dog = (Dog) animal;
Cat cat = (Cat) animal;
cat.hand();//animal并没有加载cat的属性和方法,编译正常但是运行时错误
dog.liugou();
}
instanceof关键字的使用方法:
a instanceof A:判断对象a是否是A的实例,如果是返回true,否则返回flase。
if(animal instanceof Cat){
Cat cat = (Cat) animal;
cat.hand();//animal不是Cat的实例,因此hand()不执行
}