加入收藏 | 设为首页 | 会员中心 | 我要投稿 怀化站长网 (https://www.0745zz.cn/)- 语音技术、云资源管理、物联设备、云计算、决策智能!
当前位置: 首页 > 站长资讯 > 动态 > 正文

最常见的蓝屏原因汇总

发布时间:2021-02-12 18:42:21 所属栏目:动态 来源:互联网
导读:从上面代码中我们看到sup.field输出的值不是 Son 对象中所定义的,而是Super本身定义的。这与我们认识的多态有点冲突。 其实不然,当Super对象转型为Son引用时,任何域访问操作都将由编译器解析,因此不是多态的。在本例中,为Super.field和Son.field分配了

从上面代码中我们看到sup.field输出的值不是 Son 对象中所定义的,而是Super本身定义的。这与我们认识的多态有点冲突。

其实不然,当Super对象转型为Son引用时,任何域访问操作都将由编译器解析,因此不是多态的。在本例中,为Super.field和Son.field分配了不同的存储空间,而Son类是从Super类导出的,因此,Son实际上是包含两个称为field的域:「它自己的+Super的」。

虽然这种问题看上去很令人头痛,但是我们开发规范中,通常会将所有的域都设置为 private,这样就不能直接访问它们,只能通过调用方法来访问。

「static 带来的失灵」:

看到这里,小伙伴们应该对多态有个大致的了解,但是不要掉以轻心哦,还有一种情况也是会出现失灵的,「那就是如果某个方法是静态的,那么它的行为就不具有多态性。」

老规矩,我们看下这组代码:

 

是否感到有点奇怪,为什么这个时候调用的f()是基类中定义的,而不像上面所述的那样,通过动态绑定,从而调用导出类PrivateOverride中定义的f()。不知道心细的你是否发现,基类中f()方法的修饰是「private」。没错,这就是问题所在,PrivateOverride中定义的f()方法是一个全新的方法,因为private的缘故,对子类不可见,自然也不能被重载。

结论:

只有非 private 修饰的方法才可以被覆盖

我们通过 Idea 写代码的时候,重写的方法头上可以标注@Override注解,如果不是重写的方法,标注@Override注解就会报错:

 

其中Monkey、Pig、Dog皆是Animal的导出类

Animal animal = new Monkey() 看上去不正确的赋值,但是上通过继承,Monkey就是一种Animal,如果我们调用animal.eat()方法,不了解多态的小伙伴常常会误以为调用的是Animal的eat()方法,但是最终却是调用了Monkey自己的eat()方法。

Animal作为基类,它的作用就是为导出类建立公用接口。所有从Animal继承出去的导出类都可以有自己独特的实现行为。

可扩展性

有了多态机制,我们可以根据自己的需求对系统添加任意多的新类型,而不需要重载void start(Animal animal)方法。

在一个设计良好的OOP程序中,大多数或者所有方法都会遵循start()方法的模型,只与基类接口同行,这样的程序就是具有「可扩展性」的,我们可以通过从通用的基类继承出新的数据类型,从而添加一些功能,那些操纵基类接口的方法就不需要任何改动就可以应用于新类。

失灵了?我们先来复习一下权限修饰符:

 

在start()方法中传入的是Animal 的对象引用,如果有多个Animal的导出类,那么执行eat()方法的时候如何知道调用哪个方法。如果通过前期绑定那么是无法实现的。因此就有了后期绑定。

动态绑定:又称为后期绑定。是在程序运行时根据对象类型进行绑定的,因此又可以称为运行时绑定。而 Java 就是根据它自己的后期绑定机制,以便在运行时能够判断对象的类型,从而调用正确的方法。

「小结:」

Java 中除了 static 和 final 修饰的方法之外,都是属于后期绑定

合理即正确

显然通过动态绑定来实现多态是合理的。这样子我们在开发接口的时候只需要传入 基类 的引用,从而这些代码对所有 基类 的 导出类 都可以正确的运行。


 

(编辑:怀化站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读