• 谜题70 : 一揽子


    下面这个程序设计在不同的包中的两个类的交互,main 方法位于 hack.TypeIt 中。那么,这
    个程序会打印什么呢?

    package hack;
    import click.CodeTalk;
    public class TypeIt {
    private static class ClickIt extends CodeTalk {
    void printMessage() {
    System.out.println("Hack");
    }
    }
    public static void main(String[ ] args) {
    ClickIt clickit = new ClickIt();
    clickit.doIt();
    
    }
    }
    package click;
    public class CodeTalk {
    public void doIt() {
    printMessage();
    }
    void printMessage() {
    System.out.println("Click");
    }
    }
    

      

    本谜题看起来很直观。Hack.TypeIt 的 main 方法对 TypeIt.ClickIt 类实例化,
    然后调用其 doIt 方法,该方法是从 CodeTalk 继承而来。接着,该方法调用
    printMessage 方法,它在 TypeIt.ClickIt 中被声明为打印 Hack。然而,如果你
    运行该程序,它打印的将是 Click。怎么会这样呢?
    上面的分析做出了一个不正确的假设,即 Hack.TypeIt.ClickIt.printMessage
    方法覆写了 click.CodeTalk.printMessage 方法。一个包内私有的方法不能被位
    于另一个包中的某个方法直接覆写[JLS 8.4.8]。在程序中的这两个 twoMessage
    方法是无关的,它们仅仅是具有相同的名字而已。当程序在 hack 包内调用
    printMessage 方法时,运行的是 hack.TypeIt.ClickIt.printMessage 方法。这
    个方法将打印 Click,这也就解释了我们所观察到的行为。
    如果你想让 hack.TypeIt.ClickIt 中的 printMessage 方法覆写在
    Click.CodeTalk 中的该方法,那么你必须在 Click.CodeTalk 中的该方法声明之
    前添加 protected 或 public 修饰符。要使该程序能够编译,你还必须在
    hack.TypeIt.ClickIt 的覆写声明的前面添加一个修饰符,该修饰符与你在
    Click.CodeTalk 的 printMessage 方法上放置的修饰符相比,所具备的限制性不
    能更多[JLS 8.4.8.3]。换句话说,两个 printMessage 方法可以都被声明为是
    public 的,也可以都被声明为是 protected 的,或者,超类中的方法被声明为
    是 protected,而子类中的方法被声明为是 public 的。无论你执行了上述三种
    修改中的任何一种,该程序都将打印 Hack,从而表明确实发生了覆写。
    总之,包内私有的方法不能直接被包外的方法声明所覆写。尽管包内私有的访问
    权限和覆写结合到一起会导致某种混乱,但是 Java 当前的行为是允许使用包的,
    以支持比单个的类更大的抽象封装。包内私有的方法是它们所属包的实现细节,
    在包外重用它们的名字是不会对包内产生任何影响的。

  • 相关阅读:
    环保
    A股行情记录
    航运
    黑五类
    家电
    妖股
    高校概念股
    科技园区
    壳股
    白底黑字or黑底白字,眼睛更喜欢哪一个?
  • 原文地址:https://www.cnblogs.com/yuyu666/p/9841015.html
Copyright © 2020-2023  润新知