向上向下转型
定义一个父类Animals
包含eat()
方法、age
初始值为0
然后再定义两个子类:Dog
和Cat
,都重写了eat()
方法和age
,然后再分别有自己的特有方法狗咆叫bark()
,猫睡觉sleep()
向上转型:Animals a = new Cat()
向下转型:Cat cat = (Cat) a
,必须要先经过向上转型的变量–再向下转型,此时cat
就拥有子类自己定义的特有方法cat.sleep()
instanceof
用法:a instanceof Cat
这里a
必须是经过向上转型后的父类对象,而Cat
是继承父类的子类
// 父类
public class Animals {
public int age = 0;
public void eat(){
System.out.println("Eat...");
}
}
// 子类 继承 父类 Animals
public class Dog extends Animals {
public int age = 10;
@Override
public void eat(){
System.out.println("eat bone...");
}
public void bark(){
System.out.println("dog bark...");
}
}
public class Cat extends Animals{
public int age = 2;
@Override
public void eat(){
System.out.println("eat fish...");
}
public void sleep(){
System.out.println("cat sleep...");
}
}
有一个宠物店AnimalsShop
将宠物放入后,统计个数,以及可以取出该宠物
public class AnimalsShop {
// 注意这里用的Animals泛型,加入宠物时,不关心宠物的具体类型
private List<Animals> list = new ArrayList<Animals>();
// 当加入一个宠物时,相当于进行了向上转型
public void add(Animals a){
list.add(a);
}
public int getSize(){
return list.size();
}
// 取出的宠物也是经过向上转型的,此时类型为Animals
public Animals getAnimal(int position){
return list.get(position);
}
}
public static final int DOG = 0;
public static final int CAT = 1;
@Test
public void test4(){
// 通过泛型进行向上转型将不同类型的动物加入集合,此时不需要动物的不同特性,只需要知道个数即可
AnimalsShop as = new AnimalsShop();
as.add(new Dog());
as.add(new Cat());
// 获取动物个数
System.out.println(as.getSize());
// 查看所有的宠物
Dog dog = (Dog) as.getAnimal(DOG); // 直接向下转型,并不安全,因为可以编译通过但运行出错
dog.eat();
dog.bark();
Animals a = as.getAnimal(CAT); // 获取已经向上转型Cat
System.out.println(a instanceof Dog); // false,向上转型的Cat和Dog不构成子类关系
// ((已经经过向上转型的)父类对象 instanceof 子类 ) 来判断是否可以向下转型更安全,防止ClassCastException转换异常
if(a instanceof Cat){
Cat cat = (Cat) as.getAnimal(CAT);
cat.eat();
cat.sleep();
}
}
向下转型的最大好处是:java的泛型编程,用处很大,Java的集合类都是这样的。
参考博客
多态的特点
多态的前提:
- 存在继承或实现接口
extend
或implement
- 重写方法
@Override
- 父类引用指向子类对象
Animals a = new Cat()
多态的特点:
- 相同变量看父类
a.age = 0
- 重写方法看子类
eat()看子类
- 子类特有方法不可用
a.sleep()不可用
public static void animalEat(Animals a){
a.eat();
}
@Test
public void test3(){
Animals a1 = new Dog();
System.out.println(a1.age); // 1. 变量看父类
a1.eat(); // 2. 方法看子类
// a1.bark(); 3. 子类特有不可用
Animals a2 = new Cat();
a2.eat();
// 当向上转型后,通过一个通用方法调用不同的子类,即可实现子类的方法
animalEat(new Dog());
animalEat(new Cat());
}