多态的定义:
同一种事物,由于条件不同展现不同的状态,在java中表现为同一个引用,指向的实例不同,最终展现不同的执行效果。
动物 x = new 猫 (); 猫这类事物既具备了猫的形态又具备了动物的形态,这就是对象的多态性,简单说就是一个对象对应着不同类型。
多态在代码中的体现:
父类或者接口的引用指向子类对象。
多态的好处:
提高了代码的扩展性,前期定义的代码可以使用后期的内容。
多态的弊端:
前期定义的内容不能使用(调用)后期子类特有的功能。
多态的前提:
1、要在继承关系下。
2、要有重写。
3、父类引用指向子类对象。
多态的两种形式:
1、使用父类作为方法形参实现多态。
2、使用父类作为返回值实现多态。
关于向上和向下类型转换:
Animal a =new Cat ();
自动类型提升,猫对象提升了动物类型,但是特有功能无法访问。作用就是限制特有功能的访问。 专业叫:向上转型。将子类型隐藏。就不能使用子类的特有方法。
a . eat ();
如果还想用具体动物猫的特有功能,还可以将对象进行向下转型。
Cat c = (Cat) a;
c . eat ();
c . catchMouse ();
向下转型是为了使用子类中的特有方法。
但是注意:对于转型,自始至终都是子类对象在做着类型的变化。
instanceof关键字
用来判断对象的具体类型。只能用于引用数据类型判断,判断数据类型是否是这一个。
下面对于a对象举例:
if ( a instanceof Cat)
{
Cat c = (Cat) a ;
c.catchMouse();
}
else if ( a instanceof Dog)
{
Dog d=( Dog) a;
d.lookHome();
}
用instanceof是为了判断代码的健壮性。通常在向下类型转换前用于健壮性的判断。
多态时,
成员的特点:
1、成员变量。
编译时:参考引用型变量所属的类中是否有调用的成员变量,有,编译通过,没有编译失败(类文件产生失败)。
编译时:参考引用型变量所属的类中是否有调用的成员变量,并运行该所属类中的成员变量。
简单说就是编译和运行都参考左边。Fu f = new Zi ();
Class Fu
{
int num = 3;
}
Class Zi extends Fu
{
int num = 4;
}
Class DuoTaiDemo
{
public static void main ( String [] args )
{
Fu f = new Zi ();
System.out.println ( f . num );
}
}
输出结果为4
2、成员函数(非静态)。
编译时:参考引用类变量所属的类中是否有调用的函数。有,编译通过,没有编译失败。
运行时:参考的是对象所属的类中是否有调用的函数。
简单说:编译看左边,运行看右边。
Class Fu
{
void show ()
{
System.out.println ( " fu show " );
}
}
Class Zi extends Fu
{
void show ()
{
System.out.println ( " zi show " );
}
}
Class DuoTaiDemo
{
public static void main ( String [] args )
{
Fu f = new Zi ();
f .show();
}
}
输出结果为zi show
非静态是用对象来完成调用,依赖的是对象必须动态绑定到对应的对象上。
3、静态函数。
编译时:参考引用型变量所属的类中是否有调用的静态方法。
运行时:参考引用型变量所属的类中是否有调用的静态方法。
简单说:就是编译和运行都看左边。
其实对于静态方法,是不需要对象的。直接类名点静态方法名即可。
Class Fu
{
static void method ()
{
System.out.println ( " fu static method " );
}
}
Class Zi extends Fu
{
static void method ()
{
System.out.println ( " zi static method " );
}
}
Class DuoTaiDemo
{
public static void main ( String [] args )
{
Fu f = new Zi ();
f .method();
}
}
输出结果是:fu static method
静态函数是 相当于不涉及多态性(对象的多态性),所以在调用静态函数时直接类名点静态方法名:Fu . method();即可。