9.12 概述
多态:多种形态。
重点说的是:对象的多态性。
class 动物{
}
class 狗 extends 动物{
}
//狗 x = new 狗(); 狗有两种形态:狗和动物
动物 x = new 狗();//狗实例即是狗类型,又是动物类型。多态性
多态在程序中的体现:父类的引用或者接口的引用指向了子类的对象。
9.13 代码体现&好处
多态的好处:提高代码的扩展性
举例说明:
abstract class Animal{
abstract void eat();
}
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("抓老鼠");
}
}
class Test{
public static void main(String[] args){
//Dog d = new Dog();
// d.eat();
Animal a = new Dog();//多态形式
a.eat();
Animal c = new Cat();
c.eat();
}
}
定义了狗和猫的调用方式。但是如果再出现子类比如猪,那么还要定义一个调用猪的方法。不利于拓展。
既然调用的都是eat方法,而eat是动物共性行为,为什么不面对动物呢?
直接定义共性类型的参数更合适。
abstract class Animal{
abstract void eat();
}
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("抓老鼠");
}
}
class Pig extends Animal{
public void eat(){
System.out.println("饲料");
}
public void gongDi(){
System.out.println("拱地");
}
}
class Test{
public static void main(String[] args){
//Dog d = new Dog();
// d.eat();
/* Animal a = new Dog();//多态形式
a.eat();
Animal c = new Cat();
c.eat();*/
method(new Dog());
method(new Cat());
method(new Pig());
}
/*
当面对共性类型时,所有子类对象都可以接收。
说明提高了代码的扩展性
*/
public static void method(Animal a){ //a有可能是猫、狗、猪
a.eat();
}
}
9.14 代码弊端&前提
多态的弊端:不能使用子类的特有方法
前提:
- 必须要有关系,继承,实现。
- 通常有覆盖。
public static void method(Animal a){ //a有可能是猫、狗、猪
a.eat();
a.lookhome(); //error
}
9.15 向上向下转型
向上转型:
好处:隐藏了子类型,提高了代码扩展性
弊端:只能使用父类中的功能,不能使用子类的特有功能
如果不需要面向子类型,通过体改扩展性,或者使用父类的功能即可完成操作,就可以使用向上转型。
public static void main(String[] args){
Animal a = new Dog(); //向上转型,狗被提升为了动物
a.eat();
}
如果想要使用子类的特有功能,比如看家,这时就需要使用子类型。
向下转型:
好处:可以使用子类型的特有功能
弊端:面对具体的子类型,向下转型有风险。容易发生ClassCastException。只要转型类型和对象不匹配就会发生。
public static void main(String[] args){
Animal a = new Dog(); //向上转型,狗被提升为了动物
a.eat();
Dog d = (Dog)a; //向下转型
d.eat();
d.lookhome();
}
向下转型有风险:
public static void main(String[] args){
Animal a = new Cat();
a.eat();
Dog d = (Dog)a; //ClassCastException
d.eat();
d.lookhome();
}
想要安全,必须进行判断,判断一个对象是否匹配某一个类型,需要使用一个关键字instanceof
对象 instanceof 类型
public static void main(String[] args){
//Dog d = new Dog();
// d.eat();
Animal a = new Cat();//多态形式
a.eat();
if(a instanceof Dog) {
Dog d = (Dog) a; //向下转型
d.eat();
}
}
什么时候用向下转型:
需要实用子类的特有方法的时候,但是一定判断。