定义:某一类事物的多种存在形态。
l例:动物中猫,狗。
l猫这个对象对应的类型是猫类型
•猫 x = new 猫();
l同时猫也是动物中的一种,也可以把猫称为动物。
•动物 y = new 猫();
•动物是猫和狗具体事物中抽取出来的父类型。
•父类型引用指向了子类对象。
l程序中体现:
父类或者接口的引用指向或者接收自己的子类对象。
l好处和作用:
多态的存在提高了程序的扩展性和后期可维护性
l前提:
•需要存在继承或者实现关系
•要有覆盖操作
l
多态的特点
l成员函数:
•编译时:要查看引用变量所属的类中是否有所调用的成员。
•在运行时:要查看对象所属的类中是否有所调用的成员。
l成员变量:
•只看引用变量所属的类。
/*
多态:多种形态。
对象的多态性。
class 动物{}
class 猫 extends 动物{}
猫 x = new 猫();
动物 y = new 猫();//猫这个实体具备着两种形态,一个是猫另一个是动物。这就是多态性。
多态在程序中的体现:父类或者接口的引用指向了自己的子类对象。
多态的前提:
1,必须有继承或者实现的关系。
2,通常都有覆盖的操作。
多态的好处:
提高了程序的扩展性,在思想上也有不同,以前是面对一个对象调用,对象多了调用麻烦。
相当于指挥一批对象做事情,将复杂事情简单化。
多态的弊端:
多态的出现,虽然可以让前期的程序使用后期的内容。
不可以使用子类的特有内容。
*/
//动物:吃。
abstract class Animal
{
abstract void eat();
}
class Cat extends Animal
{
void eat()
{
System.out.println("吃鱼");
}
void catchMouse()
{
System.out.println("抓老鼠");
}
}
class Dog extends Animal
{
void eat()
{
System.out.println("啃骨头");
}
void lookHome()
{
System.out.println("看家");
}
}
class AnimalDemo
{
public static void main(String[] args)
{
// Cat c = new Cat();
// c.eat();
// c.catchMouse();
// Animal a = new Cat();//多态体现。
// a.eat();
// a.catchMouse();//不可以的。
//--------多态的好处---------
Cat c = new Cat();
// c.eat();
Dog d1 = new Dog();
Dog d2 = new Dog();
Dog d3 = new Dog();
// d.eat();
method(c);
method(d1);
}
public static void method(Animal a)//Animal a = new Cat(); 或者 Animal a = new Dog();
{
a.eat();
}
/*
public static void method(Dog d)
{
d.eat();
}
public static void method(Cat d)
{
d.eat();
}
*/
}
/*
多态:
*/
abstract class Animal
{
abstract void eat();
}
class Cat extends Animal
{
void eat()
{
System.out.println("吃鱼");
}
void catchMouse()
{
System.out.println("抓老鼠");
}
}
class Dog extends Animal
{
void eat()
{
System.out.println("啃骨头");
}
void lookHome()
{
System.out.println("看家");
}
}
class AnimalDemo2
{
public static void main(String[] args)
{
// Cat c = new Cat();
Animal a = new Cat();//向上转型(类型提升)。子类对象提升为了父类型。
/*
提升的好处:就是提高了扩展性。隐藏了子类型。
提升的局限性:只能使用父类中的方法。 如果子类有覆盖的话,运行的是子类的内容。
*/
a.eat();
//如何使用抓老鼠行为。
Cat c = (Cat)a;//向下转型(强制类型转换)。好处:可以使用具体子类型的特有方法。
c.catchMouse();
// 向下转型需要注意:父类型向下转成子类型,因为子类型不唯一,所以,需要进行判断。
Animal an = new Cat();
// 如何判断对象类型呢? 用到一个关键字完成,instanceof 对象 instanceof 类or接口
// 记住:一旦向下转型,必须先instanceof判断
if(an instanceof Dog){
Dog d = (Dog)an;//ClassCastException
d.lookHome();
}else if(an instanceof Cat)
{
Cat c = (Cat)an;
c.catchMouse();
}
// 记住:对于子父类转型动作,自始自终都是子类对象在做着类型的转换而已。
/*
毕姥爷 x = new 毕老师();
x.钓鱼();
x.讲课();
// x.看电影();
毕老师 y = (毕老师)x;
y.看电影();
*/
}
}
class 毕姥爷
{
void 讲课()
{
System.out.println("管理");
}
void 钓鱼()
{
}
}
class 毕老师 extends 毕姥爷
{
void 讲课()
{
System.out.println("JAVA");
}
void 看电影()
{
}
}
/*
1,成员变量。
多态调用时,对于成员变量,无论是编译还是运行,结果只参考引用型变量所属的类中的成员变量。
参考等号左边。
2,成员函数。
多态调用时,对于成员函数,
编译时,参考引用型变量所属的类中是否有被调用的方法。有,编译通过,没有编译失败。
运行时,参考的是对象所属的类中是否有调用的方法。
简单说:
编译看左边,运行看右边。
3,静态函数。
简单说:
编译和运行都看左边。
*/
class Fu
{
// int num = 2;
void show()
{
System.out.println("fu show run");
}
static void method()
{
System.out.println("fu static method run");
}
}
class Zi extends Fu
{
// int num = 8;
void show()
{
System.out.println("Zi show run");
}
static void method()
{
System.out.println("zi static method run");
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
/*
演示静态方法。
*/
Fu f = new Zi();
f.method();
Zi z = (Zi)f;
z.method();
Fu.method();
Zi.method();
/*
//演示成员方法。
Fu f = new Zi();
f.show();
*/
/*
//演示成员变量。
Fu f = new Zi();
System.out.println(f.num);//2
Zi z = (Zi)f;
System.out.println(z.num);//8
*/
}
}