多态:可以理解为事物存在的多种体现形态,比如说人:男人、女人;动物:猫,狗。
多态:
多种形态。
这里要重点讲的就是对象的多态性。
狗 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();
}
}