本文介绍说自己会Java就得会多态。
![]()
今天,跟往常一样踩点来到了公司。坐到自己的工位上打开电脑, ![]() 这不是多态吗,谁在我电脑写的测试,不禁一阵奇怪。
一阵声音从身后传来,因为在思考输出结果,也没在意声音的来源,继续看了看代码,便得出结论: polygon() before cal() square.cal(), border = 2 polygon() after cal() square.square(), border = 4复制代码 心里想:就这?起码也是名 Java 开发工程师好吗,虽然平时搬搬砖,一些基本功还是有的。不禁有点得意了~
声音又突然响起,这次我不淡定了,尼玛!这答案我也是在心里想的好吗,谁能看得到啊,而且说得话让人那么想施展一套阿威十八式。 上班时间,睡着了?我睁开了眼,看了下周围环境,原来是梦啊,舒了一口气。望眼就看到部门主管站在我面前,上班时间睡觉,你是身体不舒服还是咋样?昨天写了一堆 bug 没改,今天又提交什么乱七八糟的东西上去,我看你这个月的绩效是不想要的,而且基于你的表现,我也要开始为部门考虑考虑了。
奇怪,怎么会做那么奇怪的梦,也太吓人了。然后就想到了梦中的那部分代码,难道我的结果是错的吗?凭着记忆,在电脑上重新敲了出来,运行结果如下: /* polygon() before cal() square.cal(), border = 0 polygon() after cal() square.square(), border = 4 */复制代码
有些小伙伴疑惑的点可能不止 多态在面向对象的程序设计语言中,多态是继数据抽象和继承之后的第三种基本特征。 多态不但能够改善代码的组织结构和可读性,还能够创建可扩展的程序。多态的作用就是消除类型之间的 1. 向上转型根据 对象既可以作为它自己本身的类型使用,也可以作为它的基类型使用。而这种吧对某个对象的引用视为对其基类型的引用的做法被称作为 - public class Animal { void eat() { System.out.println("Animal eat()"); } }class Monkey extends Animal { void eat() { System.out.println(" Monkey eat()"); } }class test { public static void start(Animal animal) { animal.eat(); } public static void main(String[] args) { Monkey monkey = new Monkey(); start(monkey); } }/* OUTPUT: Monkey eat() */复制代码 上述 打个不是特别恰当的比方:你父亲的财产会继承给你,而你的财产还是你的,总的来说,你的财产不会比你父亲的少。 ![]() 忘记对象类型在 直观也许是它的优点,但是就会带来其他问题: 因此这样就有了 2.显露优势方法调用中分为
引出思考: public static void start(Animal animal) { animal.eat(); }复制代码 在
小结: Java 中除了 合理即正确显然通过 ![]() 其中
可扩展性有了多态机制,我们可以根据自己的需求对系统添加任意多的新类型,而不需要重载 在一个设计良好的OOP程序中,大多数或者所有方法都会遵循 失灵了?我们先来复习一下权限修饰符:
私有方法带来的失灵: 复习完我们再来看一组代码: public class PrivateScope { private void f() { System.out.println("PrivateScope f()"); } public static void main(String[] args) { PrivateScope p = new PrivateOverride(); p.f(); } }class PrivateOverride extends PrivateScope { private void f() { System.out.println("PrivateOverride f()"); } }/* OUTPUT PrivateScope f() */复制代码 是否感到有点奇怪,为什么这个时候调用的 结论: 只有非 我们通过 Idea 写代码的时候,重写的方法头上可以标注 ![]() 这样也可以很好的提示我们非重写方法,而是全新的方法。 域带来的失灵: 当小伙伴看到这里,就会开始认为所有事物(除 让我们再看看下面这组代码: class Super { public int field = 0; public int getField() { return field; } }class Son extends Super { public int field = 1; public int getField() { return field; } public int getSuperField() { return super.field; } }class FieldTest { public static void main(String[] args) { Super sup = new Son(); System.out.println("sup.field:" + sup.field + " sup.getField():" + sup.getField()); Son son = new Son(); System.out.println("son.field:" + son.field + " son.getField:" + son.getField() + " son.getSupField:" + son.getSuperField()); } }/* OUTPUT sup.field:0 sup.getField():1 son.field:1 son.getField:1 son.getSupField:0 */复制代码 从上面代码中我们看到 ![]() 其实不然,当 虽然这种问题看上去很令人头痛,但是我们开发规范中,通常会将所有的域都设置为 private,这样就不能直接访问它们,只能通过调用方法来访问。 static 带来的失灵: 看到这里,小伙伴们应该对多态有个大致的了解,但是不要掉以轻心哦,还有一种情况也是会出现失灵的,那就是如果某个方法是静态的,那么它的行为就不具有多态性。 老规矩,我们看下这组代码: class StaticSuper { public static void staticTest() { System.out.println("StaticSuper staticTest()"); } }class StaticSon extends StaticSuper{ public static void staticTest() { System.out.println("StaticSon staticTest()"); } }class StaticTest { public static void main(String[] args) { StaticSuper sup = new StaticSon(); sup.staticTest(); } }/* OUTPUT StaticSuper staticTest() */复制代码 静态方法是与类相关联,而非与对象相关联 3.构造器与多态首先我们需要明白的是构造器不具有多态性,因为构造器实际上是 我们先回到开头的那段神秘代码: ![]() 其中输出结果是: /* polygon() before cal() square.cal(), border = 0 polygon() after cal() square.square(), border = 4 */复制代码 我们可以看到先输出的是基类 这是因为基类的构造器总是在导出类的构造过程中被调用,而且是按照继承层次逐渐向上链接,以使每个基类的构造器都能得到调用。 ![]() 因为构造器有一项特殊的任务:检查对象是否能正确的被构造。导出类只能访问它自己的成员,不能访问基类的成员(基类成员通常是private类型)。只有基类的构造器才具有权限来对自己的元素进行初始化。因此,必须令所有构造器都得到调用,否则就不可能正确构造完整对象。 步骤如下:
打个不是特别恰当的比方:你的出现是否先要有你父亲,你父亲的出现是否先要有你的爷爷,这就是逐渐向上链接的方式 构造器内部的多态行为有没有想过如果在一个构造器的内调用正在构造的对象的某个动态绑定方法,那么会发生什么情况呢? 动态绑定的调用是在运行时才决定的,因为对象无法知道它是属于方法所在的那个类还是那个类的导出类。如果要调用构造器内部的一个动态绑定方法,就要用到那个方法的被覆盖后的定义。然而因为被覆盖的方法在对象被完全构造之前就会被调用,这可能就会导致一些难于发现的隐藏错误。 问题引索: 一个动态绑定的方法调用会向外深入到继承层次结构内部,它可以调动导出类里的方法,如果我们是在构造器内部这样做,那么就可能会调用某个方法,而这个方法做操纵的成员可能还未进行初始化,这肯定就会招致灾难的。 敏感的小伙伴是不是想到了开头的那段代码: ![]() 输出结果是: /* polygon() before cal() square.cal(), border = 0 polygon() after cal() square.square(), border = 4 */复制代码 我们在进行 这组代码初始化的实际过程为:
![]()
以上就是这年头,说自己会Java就得会多态的详细内容,更多请关注模板之家(www.mb5.com.cn)其它相关文章! |