对象的多态性

目录

一 、对象转型 

 1 、对象的向上转型

2 、对象的向下转型

注意:在进行对象向下转型前,必须先进行对象向上转型,否则将出现对象转换异常

二 、对象多态性的应用

设计一个方法,要求此方法可以接收父类的任意子类对象,并调用方法

1 、不使用对象多态性实现功能 

2 、使用对象多态性实现功能


 

一 、对象转型 

面对对象有三大特征:封装性、继承性、多态性。而多态性在面向对象中是一个最重要的概念,在Java中面向对象主要有以下两种主要体现:

(1)方法的重载与覆写

(2)对象的多态性

对象的多态性主要分为以下两种类型:

(1)向上转型:子类对象 → 父类对象

(2)向下转型:父类对象 → 子类对象

【对象转型格式】

对象向上转型:父类 父类对象 = 子类实例

对象向下转型:子类 子类对象 = (子类)父类实例

 1 、对象的向上转型

class A{
    public void fun1(){
        System.out.println("A --> public void fun1(){}");
    }
    public void fun2(){
        this.fun1();
    }
}

class B extends A{
    public void fun1(){  //覆写父类A的fun1方法
        System.out.println("B --> public void fun1(){}");
    }
    public void fun3(){
        System.out.println("B --> public void fun3(){}");
    }
}

public class PolDemo01 {
    public static void main(String[] args) {
        B b = new B();  //实例化子类对象
        A a = b ;   //对象向上转型:父类 父类对象 = 子类实例
        a.fun1();   //此方法被子类覆写过
    }
}

程序运行结果:

从程序运行结果发现,发生向上转型后,父类对象实际上调用的是被子类覆写过的方法,如果子类没有覆写父类的方法,则父类对象调用自己的方法,同时要注意:此时父类对象a是无法调用到B类中的fun3()方法的,因为此方法只在子类中定义,而没有在父类中定义。

也就是说,以前对象只能调用自己类中的方法,发生向上转型关系后,父类对象不仅可以调用自己类中的方法,还可以调用子类中覆写父类的方法 

而向下转型之后,子类对象可以调用子类、父类中的所有方法

2 、对象的向下转型

class A{
    public void fun1(){
        System.out.println("A --> public void fun1(){}");
    }
    public void fun2(){
        this.fun1();
    }
}

class B extends A{
    public void fun1(){   //覆写父类A的fun1()方法
        System.out.println("B --> public void fun1(){}");
    }
    public void fun3(){
        System.out.println("B --> public void fun3(){}");
    }
}

public class PolDemo01 {
    public static void main(String[] args) {
        A a = new B();  //发生向上转型
        B b = (B)a;     //发生向下转型
        b.fun1();
        b.fun2();
        b.fun3();
    }
}

程序运行结果:

如果子类B没有覆写父类A的方法,则子类对象b将调用父类A中的fun1()方法,代码如下:

class A{
    public void fun1(){
        System.out.println("A --> public void fun1(){}");
    }
    public void fun2(){
        this.fun1();
    }
}

class B extends A{
    public void fun3(){
        System.out.println("B --> public void fun3(){}");
    }
}

public class PolDemo01 {
    public static void main(String[] args) {
        A a = new B();  //发生向上转型
        B b = (B)a;     //发生向下转型
        b.fun1();
        b.fun2();
        b.fun3();
    }
}

程序运行结果:

也就是说,以前对象只能调用自己类中的方法,发生向上转型关系后,父类对象不仅可以调用自己类中的方法,还可以调用子类中覆写父类的方法 

而向下转型之后,子类对象可以调用子类、父类中的所有方法

两者都是先找被覆写过的方法,没有再调用原方法

 

观察以上程序向下转型过程:

    public static void main(String[] args) {
        A a = new B();  //发生向上转型
        B b = (B)a;     //发生向下转型
        b.fun1();
        b.fun2();
        b.fun3();
    }

注意:在进行对象向下转型前,必须先进行对象向上转型,否则将出现对象转换异常

如下代码所示: 

class A{
    public void fun1(){
        System.out.println("A --> public void fun1(){}");
    }
    public void fun2(){
        this.fun1();
    }
}

class B extends A{
    public void fun3(){
        System.out.println("B --> public void fun3(){}");
    }
}

public class PolDemo01 {
    public static void main(String[] args) {
        A a = new A();  //错误 ,向下转型之前没先向上转型 
        B b = (B)a;     //发生向下转型
        b.fun1();
        b.fun2();
        b.fun3();
    }
}

程序编译报错:类转换异常

 为什么会出现异常呢?先从父类的定义来看:

class A{
    public void fun1(){
        System.out.println("A --> public void fun1(){}");
    }
    public void fun2(){
        this.fun1();
    }
}

从父类的定义来看,父类它本身并不确定谁是自己的子类,它不像 class B extends A{ } 这样明确确定B 继承A,为A的子类。所以直接进行向下转型就会出现类转换异常,此时,需要将两个对象建立关系,通过向上转型,“A a = new B()”,由子类去实例化父类对象,这时父类就知道自己有这么一个子类,再进行向下转型 

 

 

二 、对象多态性的应用

设计一个方法,要求此方法可以接收父类的任意子类对象,并调用方法

1 、不使用对象多态性实现功能 

class A{					// 定义类A
    public void fun1(){		// 定义fun1()方法
        System.out.println("A --> public void fun1(){}") ;
    }
    public void fun2(){
        this.fun1() ;		// 调用fun1()方法
    }
};
class B extends A{
    public void fun1(){		// 此方法被子类覆写了
        System.out.println("B --> public void fun1(){}") ;
    }
    public void fun3(){
        System.out.println("B --> public void fun3(){}") ;
    }
};
class C extends A{
    public void fun1(){		// 此方法被子类覆写了
        System.out.println("C --> public void fun1(){}") ;
    }
    public void fun5(){
        System.out.println("C --> public void fun5(){}") ;
    }
};
public class PolDemo04{
    public static void main(String asrgs[]){
        fun(new B()) ;	// 传递B的实例
        fun(new C()) ;	// 传递B的实例
    }
    public static void fun(B b){
        b.fun1() ;		// 调用覆写父类中的fun1()方法
    }
    public static void fun(C c){
        c.fun1() ;		// 调用覆写父类中的fun1()方法
    }
};

程序运行结果:

不使用对象多态性可以实现功能,但是每增加一个子类,fun()方法就得重载一次。

 

2 、使用对象多态性实现功能

class A{					// 定义类A
    public void fun1(){		// 定义fun1()方法
        System.out.println("A --> public void fun1(){}") ;
    }
    public void fun2(){
        this.fun1() ;		// 调用fun1()方法
    }
};
class B extends A{
    public void fun1(){		// 此方法被子类覆写了
        System.out.println("B --> public void fun1(){}") ;
    }
    public void fun3(){
        System.out.println("B --> public void fun3(){}") ;
    }
};
class C extends A{
    public void fun1(){		// 此方法被子类覆写了
        System.out.println("C --> public void fun1(){}") ;
    }
    public void fun5(){
        System.out.println("C --> public void fun5(){}") ;
    }
};
public class PolDemo04{
    public static void main(String asrgs[]){
        fun(new B()) ;	// 传递B的实例,产生向上转型
        fun(new C()) ;	// 传递B的实例,产生向上转型
    }
    public static void fun(A a){  //接收父类对象
        a.fun1() ;		
    }
};

 程序运行结果:

 从以上程序可以发现,fun()方法使用了对象多态性,可以接收任意的子类对象,这样无论子类如何增加,fun()方法都不用改变。因为子类对象发生向上转型关系,此时父类a调用被子类覆写过的方法

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值