JAVA基础(7)--多态

多态 

多态在程序中的体现:父类的引用或者接口的引用指向了子类的对象。

多态的好处:提高了代码的扩展性。

多态的弊端:不能使用子类的特有方法。

多态的前提

  1. 必须有关系,继承,实现。
  2. 通常有覆盖。

多态--向上转型 

//Animal 抽象类
package demo;
abstract class Animal {
	abstract void eat();
}

//Dog子类
package demo;
public class Dog extends Animal{
	@Override
	void eat() {
		System.out.print("骨头");	
	}
    void sleep() {
		System.out.print("sleep");
	}
}

//向上转型
Animal a=new Dog();
a.eat();
//注意a面对的是父类型,不能调用子类特有的sleep方法

向上转型的好处:隐藏了子类型,提高了扩展性。

向上转型的弊端:只能使用父类中的功能,不能使用子类特有功能。功能被限定了。

如果不需要面对子类型,同时提高扩展性或者使用父类的功能即可完成操作,就使用向上转型。

如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法

多态--向下转型

//Animal 抽象类
package demo;
abstract class Animal {
	abstract void eat();
}

//Dog子类
package demo;
public class Dog extends Animal{
	@Override
	void eat() {
		System.out.print("骨头");	
	}
    void sleep() {
		System.out.print("sleep");
	}
}

//先向上转型
Animal a=new Dog();
//再向下转型
//判断一个对象是否匹配某一个类型,简单说就是一个对象是否是特定类的一个实例
if(a instanceof Dog){
   Dog d=(Dog)a;
   d.eat();
   d.sleep();
}else{
  System.out.print("类型不匹配");
}

向下转型的好处:可以使用子类型的特有功能。

向下转型的弊端:面对具体的子类型,向下转型有风险。容易发生ClassCastException,只要转换类型和对象类型不匹配就会发生。想要安全,必须要进行判断。判断一个对象是否匹配某一个类型,需要使用一个关键字instanceof

什么时候用向下转型:需要子类型的特有方法时。但一定要判断。

多态中成员变量的调用

当子父类中出现同名成员变量时,多态调用时,只看调用该成员变量的引用所属的类中的成员变量。

简单说:无论编译或者运行,都看等号的左边。

//父类
class Fu{
  int num=4;
}

//子类
class Zi extends Fu{
  int num=6;
}


//
Fu f=new Zi();
System.out.print(f.num);

//输出结果为父类的4

多态中成员函数的调用

出现一模一样函数时多态调用,编译时,看的是引用变量所属的类中的方法,运行时,看的是对象所属的类中的方法。

简单说就是编译看左边,运行右边。

成员方法动态绑定到当前对象上。

下面多态调用函数代码中:编译看左边,运行看右边。运行时如果子类有和父类一模一样的函数时,调用的是子类(覆盖),如果子类没有,则调用父类函数。如何父类没有,编译会报错。

//父类
class Fu{
   void show(){
       System.out.print("父show");
   }
}

//子类
class Zi extends Fu{
  void show(){
       System.out.print("子show");
   }
}


//
Fu f=new Zi();
f.show();

//输出结果为子show

多态中静态函数

出现一模一样函数时,多态调用,编译和运行是看引用变量所属的类中的方法。

简单说就是:编译和运行看左边。

其实真正调用静态方法是不需要对象的。直接类名调用。因为静态方法绑定到类上。所以下面情况,更多用于面试。

//父类
class Fu{
   static void show(){
       System.out.print("父show");
   }
}

//子类
class Zi extends Fu{
  static void show(){
       System.out.print("子show");
   }
}


//
Fu f=new Fu();	
f.show();
Zi b=(Zi)f;
b.show();

//输出结果为第一个父show,第二个子show

猜你喜欢

转载自my.oschina.net/u/3112095/blog/1784995