多态以及其优缺点

多态:可以理解为事物存在的多种体现形态,比如说人:男人、女人;动物:猫,狗。
多态:

多种形态。

这里要重点讲的就是对象的多态性。

狗 x = new 狗();

动物 y = new 狗();//对象的多态性,狗对象即是狗类型,又是动物形态。

必须要明确一点:狗是动物中的一种。
意味着狗是需要继承动物的才可以这样指向。

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

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

弊端:前期建立父类的引用虽然可以接收后期所有该类的子类对象。
   但是只能使用父类中的功能,不能使用子类中的特有功能,
   因为前期的程序无法知道后期的子类的特有内容的。
   但是前期的程序可以使用子类覆盖了父类的方法的内容。

前提:
 1,必须存在着继承关系。
 2,通常要有覆盖操作。


 

*/


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 DuoTaiDemo
{
 public static void main(String[] args)
 {

  


 

  
  Animal a = new Dog();//子类对象的类型提升。向上转型[类似于基本类型的类型提升,只不过这里是引用类型数据,]。
  a.eat();
  

  Dog d = (Dog)a;//向下转型。 转成子类型。  d.eat();
  d.lookHome();
  可以看出,向上转型为自动提升,向下转型必须强制

  
 }
 

public static void function(Ainimal a){
		a.eat();
		if (a instanceof Cat){		{
			Cat c=(Cat)a;
			c.catchMouse();
		}
		else if (a instanceof Dog)
		{
			Dog d=(Dog)a;
			d.lookHome();
		}
	}//the above method showed one point should be careful in using the 多态
 

 }

    多态中函数成员的特点:
在编译时期:参阅引用类型变量所属的类中是否有调用的方法,如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法:------编译看引用,运行得看对象

 

总的来说在多态中,成员函数在多态调用时,编译看左边,运行看右边。

                                成员变量的特点,无论编译和运行,都参考左边(引用型变量所属的类)。

 

    多态的出现在成员调用上的特点:

1,成员变量
 编译时期:参考的是引用型变量所属的类中是否有调用的成员变量,如果有,编译通过,如果没有编译失败。
 运行时期:调用的也是引用型变量所属类中的成员变量。
 
 简单说:编译和运行都看等号的左边。
 其实这种情况不多见。

2,成员函数。
 编译时期;参考的是引用型变量所属的类中是否有调用的方法。有,编译通过,没有编译失败。
 运行时期:参考的是对象所属的类中是否有调用的方法,如果有运行子类自己的方法,如果没有就父类的方法。

 简答说:编译时期看左边,运行时期看右边。
 因为函数有一个覆盖的特性。
 
 非静态方法需要和当期运行的对象进行动态绑定,哪个对象调用了这个方法,这个方法就所属于哪个对象。
 就会运行哪个对象的中的方法。

3,静态函数。
 编译时期:参考的是引用型变量所属的类中是否该方法。
 运行时期:参考的也是引用型变量所属的类中的方法。

 简单说:编译和运行都看左边。所谓的看左看右是指根据左边或右边的属性或者方法来完成调用

 因为静态方法是不所属于对象的,是所属于类的,
 它会类加载的时候,静态的绑定到所属的类上。

*/


class Fu
{
 int num = 4;
 public void show()// 因为覆盖的特性,
 {
  System.out.println("fu show run");
 }
 public static void staticMethod()
 {
  System.out.println("fu static method run");
 }
}

class Zi extends Fu
{
 int num = 5;

 public void show()// 因为覆盖的特性,
 {
  System.out.println("zi show run");
 }
 public static void staticMethod()
 {
  System.out.println("zi static method run");
 }
}

class DuoTaiTest
{
 public static void main(String[] args)
 {
  Fu f = new Zi();
//  System.out.println(f.num);//4
//  f.show();//zi show run  因为函数覆盖的特性,运行的子类对象在调用show方法,
       //覆盖了父类中的方法,运行的是子类自己的show方法。
  
  f.staticMethod();

  Zi z = new Zi();
  z.staticMethod();

  Fu.staticMethod();
  Zi.staticMethod();
 }
}


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章