最常见的蓝屏原因汇总
|
从上面代码中我们看到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 修饰的方法之外,都是属于后期绑定 合理即正确
显然通过动态绑定来实现多态是合理的。这样子我们在开发接口的时候只需要传入 基类 的引用,从而这些代码对所有 基类 的 导出类 都可以正确的运行。 (编辑:怀化站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

