JAVA个人笔记之多态转型

个人笔记之多态转型问题

在转型问题的上有点小问题,有点绕,故抽出时间来整理一下思路 ( 纯属个人思考方式 ) 。

1.多态
​ 多态就是留下一个口子(方法、函数),这个口子可以跑很多方法(函数)但是这些函数功能或许有差异,但对这些函数的操作是一样的,这样能快速使用各类函数而不需要反复地写调用语句。
举个例子:在继承中,子类可以拥有父类全部(可以使用的)的方法和属性,但若父类方法满足不了要求时就需要另写方法。具体实现最常见的是重写,若父类中自带的函数无法满足需求,子类中可以重写该方法。若运行时在子类中没有找到对应的方法,则会在父类中寻找对应的方法,直到找到Object类为止。

编译时多态:编译时就能看出来的多态(会直接报错标红)

运行时多态:运行时,调用各个new出来的函数时才能体现的多态,一般编译时不报错,跑起来才报错。

而转型时遇到的比较麻烦的问题就是运行时多态–编译时不报错但运行时报错

故简单分析下转型多态问题

首先创建两个类,父类A和子类B。(为了方便起见就不用变量举例子了)

父类A写了个 printA 方法, 打印printAA

class  A{
    void printA(){
        System.out.println("printAA");
    }
        }

子类B继承A,写了个printB方法,打印printBB

class B extends A{
    void printB(){
        System.out.println("printBB");
    }
        }

再来个main方法,先正常创建AB,然后给AB各种转换都来一下,跑一(N)下

  •  public static void main(String[] args) {
    //new 个 A 和 B
            A a = new A();
            a.printA();
            B b = new B();
            b.printB();
    //  用 a 引用 new B
            A a1 = new B();
            a1.printA();
    !//  a1.printB(); //报错了
            ((B) a1).printB(); //修正后 跑出来了
    //  这里就是将a1强转为B
            System.out.println("***********************************");
    //  用 b 引用 new A
    !//    B b1 = new A();  //报错,此时没有自动转换,需要强转
            System.out.println("===B b0 = (B) new A(); : ===");
     /* Exception in thread "main" java.lang.ClassCastException:
        com.cl251ka.demo005.A cannot be cast to com.cl251ka.demo005.B
       at com.cl251ka.demo005.DuoTai.main(DuoTai.java:18)*/
    !// B b0 = (B) new A();//报了个异常
    //  b0.printA();
    //  b0.printB();
            System.out.println("===B b1 = (B)a;: ===");
    /*  Exception in thread "main" java.lang.ClassCastException:
        com.cl251ka.demo005.A cannot be cast to com.cl251ka.demo005.B
       at com.cl251ka.demo005.DuoTai.main(DuoTai.java:25)*/
    //  B b1 = (B)a; ---->a强转为B后,大于a范围部分无法接收,故运行时出错
    //  b1.printA();
    //  b1.printB();
            System.out.println("===B b2 = (B)a1;: ===");
    //  AB方法均调用成功
    //  因为a1是由B类型强转过来的,本身带有B大于a的部分,只是由于强转没有使用,此时转回B类型又可以使用了
        B b2 = (B)a1;
        b2.printA();
        b2.printB();
        }
    }
    

此时可以很清楚地看到

`	A a1 = new B();
     a1.printA();
!//  a1.printB(); //报错了`

这一部分用 a 引用直接 new 了 B 对象直接成功了,是因为此时有一个自动类型转换:

A a1 = (A) new B(); (应该是这样的,子类转父类自动进行了)

而从方法的调用可以看出,此时虽然创建了B对象,但是B中的方法还是调用不了,通俗一点来说就是在自动转换时给了一个B的内存空间,却只让a1访问a那么大的部分,所以能调用A的方法却不能调用B的方法。
(注意此处的内存空间的说法并不严谨,只是为了方便理解这么说的)
结合

B b2 = (B)a1;
b2.printA();
b2.printB();

看,此时将a1强转成B类型时,B方法又能调用了,而

// B b1 = (B)a; ---->a强转为B后,大于a范围部分无法接收,故运行时出错
// b1.printA();
// b1.printB();

直接对 a 强转时却在运行时报错了,这是因为 a 是直接由 A a = new A();得到的,而此时 A 作为 B 的父类,强行给它转换成B类型在运行时出现了 类型转换( ClassCastException )异常 ,其实可以用 instanceof 解除该风险。

总结:

向上转型:子类转父类可以自动进行,但转换后只能调用父类中原有的属性和方法

向下转型:父类转子类必须显示(强制)进行,而且转换后在运行时有出现类型转换异常的风险

​ (但如果是从B转到A再转到B的话,还是可以使用A 和 B中的所有的方法的)

================================================
随后发现了自己踩的一个坑:
父类引用指向子类对象其实是JAVA多态的一种体现,其实并不是说子类的方法就不能用了而是需要重写再使用,至于这样有什么好处,,,好处就在于JAVA中一个父类可以有很多子类,而每个子类都可能有自己独特的某方法,这样在用多态的思想创建对象时可以很方便地找到对应的子类,知道这个子类中独有的方法需要如何实现就可以直接重写该方法,不需要再写这个类的其他方法了。
至于标题上的强转问题,只是遇到了然后想了想,了解一下就好。

00:09,睡了

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值