多态性
1.方法的多态性:重载和覆写
重载:同一个方法名称,根据不同的参数类型及个数可以完成不同的功能;
覆写:同一个方法,根据不同的实例化的子类对象不同,所完成的功能也不同。
2.对象的多态性:父子类对象的转换
向上转型:子类对象变为父类对象,格式:父类 父类对象=子类实例,自动转换;
向下转型:父类对象变为子类对象,格式:子类 子类对象=(子类)父类实例,强制转换;
例:对象向下转型:
class A4{
public void print(){
System.out.println("父类");
}
}
class B4 extends A4{
public void print(){
System.out.println("子类");
}
}
public class Test1_1_3_7 {
public static void main(String args[]){
A4 a=new B4();
a.print();
}
}
//结果:
//子类
根据实例化对象所在的类是否覆写了父类中的方法来决定最终执行,本程序实例化的是子类对象(new B4()),并且print()方法又是被子类覆写了,那么最终所调用的一定是被覆写过的方法(不要看类名称,而要看实例化对象的类)。
例:对象向下转型
class A4{
public void print(){
System.out.println("父类");
}
}
class B4 extends A4{
public void print(){
System.out.println("子类");
}
}
public class Test1_1_3_7 {
public static void main(String args[]){
A4 a=new B4(); //实例化的是子类对象,对象向上转型
B4 b=(B4)a; //对象需要强制性地向下转型
b.print(); //调用被子类覆写过的方法
}
}
//结果:
//子类
因为有强制转换的操作,所以向下转型操作本身是有前提条件的,即必须发生向上转型后才可以发生向下转型。
例:错误的向下转型操作
class A4{
public void print(){
System.out.println("父类");
}
}
class B4 extends A4{
public void print(){
System.out.println("子类");
}
}
public class Test1_1_3_7 {
public static void main(String args[]){
A4 a=new A4(); //直接实例化子类对象,没有进行向上转型
//此时并没有发生子类对象向上转型的操作,所以强制转型会带来安全隐患
B4 b=(B4)a; //强制向下转型,产生异常
b.print(); //此语句无法执行
}
}
特点:
向上转型:其目的是参数的统一,但是向上转型中,通过子类实例化后的父类对象所能调用的方法只能是父类中定义过的方法;
向下转型:其目的是父类对象要掉用实例化它的子类中的特殊方法,但是向下转型是要强制转换的,这样的操作容易带来安全隐患。
为了保证转型的顺利进行,Java提供了一个关键字:instanceof,利用此关键字可以判断某个对象是否是指定类的实例。
使用格式如下:
对象 instanceof 类 返回boolean型
如果某个对象是某个类的实例,就返回true,否则返回false。
例:使用instanceof判断
class A6{
public void print(){
System.out.println("父类");
}
}
class B6 extends A6{
public void print(){ //覆写
System.out.println("子类");
}
public void funB(){
System.out.println("子类扩充的方法");
}
}
public class Test1_1_3_9 {
public static void main(String args[]){
fun(new B6()); //对象向上转型
}
public static void fun(A6 a){
a.print();
if(a instanceof B6){ //如果a对象是B6类的实例
B6 b=(B6)a; //向下转型
b.funB(); //调用子类扩充的方法
}
}
}
//结果
//子类
//子类扩充的方法