之前学习了面向对象中的多态,现在对有关的知识点进行总结。
多态:
【体现】
父类的引用或者接口的引用指向了自己的子类对象。
【好处】
提高了程序的扩展性
【弊端】
通过父类引用操作子类对象时,只能使用父类中已有的方法,不能操作子类特有的方法。
【前提】
1,必须有关系:继承、实现、
2,通常都有重写操作。
多态技术的引出解决了程序扩展性的问题,那子类的特有方法如何调用呢?
Animal a = new Dog(); //Animal是父类型,newDog()是子对象。
但是父类型引用指向子类对象时,让子类对象进行了类型的提升(向上转型)
向上转型的好处:提高了扩展性,隐藏了子类型。弊端:不能使用子类型的特有方法。 如果要使用子类的特有方法,只有子类型可以用;可以向下转型,强制转换。
Animal a = new Dog();
a.eat();
Dog d = (Dog)a;//将a转型为Dog类型,向下转型。
d.lookHome();
当需要使用子类型特有的内容时,要用向下转型。注意:无论向上还是向下转型,最终都是子类对象做着类型的变化。
【向下转型的注意事项】
如:
Animal a = new Dog();
//Cat c = (Cat)a;向下转型因为不明确具体子类对象类型,所以容易引发ClassCastException异常
所以为了避免这个问题,需要在向下转型前,做类型的判断,判断类型用的关键字:instanceof
if(a instanceof Cat) //a指向的对象类型是Cat类型{
//将a转型Cat类型
Cat c = (Cat)a;
c.catchMouse();
}
else if(a instanceof Dog){
Dog d = (Dog)a;
d.lookHome();
}
【转型总结】
1,什么时候用向上转型?
提高程序的扩展性,不关心子类型(子类型被隐藏);不需要用子类的特有方法。
2,什么时候使用向下转型?
需要使用子类型的特有方法时,但是一定要用instanceof进行类型的判断,避免发生ClassCastException
描述狗与猫如何提高扩展性:
//描述Dog
class Dog extends Animal
{
public void eat()
{
System.out.println("骨头");
}
public void lookHome()
{
System.out.println("看家");
}
}
//描述猫
class Cat extends Animal
{
public void eat()
{
System.out.println("鱼");
}
public void catchMouse()
{
System.out.println("抓老鼠");
}
}
//进行抽取。将共性的功能抽取到父类Animal中。
abstract class Animal
{
public abstract void eat();
}
class DuoTaiDemo
{
public static void main(String[] args)
{
Dog d = new Dog();
// d.eat();
method(d);
Cat c = new Cat();
method(c);
}
/*
发现,每多一个动物,都需要为这个动物单独定义一个功能,
让这个动物的对象去做事。
这个程序扩展性就很差。
如何提高这个扩展性呢?
发现既然是让动作去eat,无论是dog,还是cat,
eat是它们共性,干脆,将eat进行抽取。抽取到父类Animal中。
Dog是Animal中的一种。
Dog d = new Dog();
Animal a = new Dog();
Cat c = new Cat();
Animal aa = new Cat();
*/
//只要建立animal的引用就可以接收所有的dog cat对象进来。让它们去eat。
//提高了程序的扩展性。
public static void method(Animal a)
{
a.eat();
}
/*
//接收Dog,让dog做事。
public static void method(Dog d)
{
d.eat();
}
//接收Cat,让cat做事。
public static void method(Cat c)
{
c.eat();
}
*/
}