`
lfx_cool
  • 浏览: 66217 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

重载方法的包可见性问题

    博客分类:
  • Java
阅读更多
今天看到polygoncell的一篇博客,起初疑惑,经过一番实考,感觉受益颇深。
(他的文章的地址:http://www.iteye.com/topic/12599)
他的文章有下面三段代码:
1,父类supper.TestSupper 。
package supper;

public class TestSupper {   
    String getString()
    {
        return "This is supper class.";
    }
}
---------------------------------------------------
2,子类sub.TestSub。
//TestSub类版本1
package sub;

import supper.TestSupper;

public class TestSub extends TestSupper {
  public String getString(){
        return "This is sub class.";
    }
}
------------------------------------------------------
3,一个测试程序(版本1),和TestSupper在一个包里:
//测试类版本1
package supper;

import sub.TestSub;

public class Test {
    public static void main(String[] args) {
        TestSupper test = new TestSub();
        System.out.println(test.getString());
    }
}
----------------------------------------------------
    这段代码输出"This is supper class."。这使我很困惑,因为TestSupper.getString()是default的,具有包可见性,只能在supper包里面访问到,既然TestSub和TestSupper不在同一个包类,TestSub自然不能看到getString方法,无法继承它,当然不会重写它,测试类Test里这段代码:TestSupper test = new TestSub(); 将TestSub类的对象test向上转型为TestSupper类,实际调用时还是应该调用TestSub类的getString()。但TestSub并没有能够从TestSupper类中继承到getString()方法,现在在测试类里调用System.out.println(test.getString()); 居然能够运行,输出"This is supper class."。
    如果把测试类Test放在sub包中,即和子类TestSub在同一个包中,代码如下:
4,修改后的测试类Test。
//测试类Test版本2
package sub;

import supper.TestSupper;

public class Test {
    public static void main(String[] args) {
        TestSupper test = new TestSub();
        System.out.println(test.getString()); //编译错误
    }
}
-------------------------------------------------
这时候编译不能通过,显示TestSupper 类的getString()不可见。
    看来这个测试类的位置很重要!
    在测试类Test的版本1中,TestSupper.getString()对Test是可见的,但TestSub.getString()对Test不可见,所以代码"System.out.println(test.getString());” 能够运行,但是调用的TestSupper.getString(),所以输出
"This is supper class.”,
    在测试类Test的版本2中,TestSupper.getString()对Test是不可见的,"System.out.println(test.getString()); ”就会有问题,此时test是一个TestSupper对象,在Test中调用不可见的TestSupper.getString()就会编译错误。
    现在将测试类TestSub的代码修改一下,删除getString()方法。
5,删除getString()后的TestSub类
//TestSub类版本2
package sub;

import supper.TestSupper;

public class TestSub extends TestSupper {

}
-----------------------------------------------------
    没有getString()方法,现在运行Test版本1,仍然输出"This is supper class.",看来TestSub有没有getString()方法根本不重要,因为它对Test类来说本来就不可见。
    Java具有向上转型和动态绑定的特性。将一个子类赋予一个父类的引用时,如果在这个引用上调用父类没有的、属于子类特有的方法,那么就会编译错误。如果调用一个父类和子类都有的方法,就没有问题,但运行的时候会自动调用子类的方法,因为它毕竟是一个子类的对象,这就是动态绑定。
    本文中的例子比较特殊,在测试类中将TestSupper的引用赋予一个TestSub的对象test,调用test.getString(),在测试类(版本1)中子类的getString()不可见,仍然能够成功运行,执行的是TestSupper.getString(),这个时候似乎动态绑定没有起作用。在测试类(版本2)中父类的getString()不可见,此时调用test.getString()相对于调用一个不存在的方法,所以出现编译错误。
分享到:
评论

相关推荐

    extern 'C' 详解

    在 C++ 中,extern 是一个关键字,用于声明函数或变量的可见性。 extern int a;仅仅是声明一个变量,并不是定义变量 a,並未为 a 分配内存空间。变量 a 在所有模块中作为一种全局变量只能被定义一次,否则会出现...

    Scala程序设计(第2版)

    13.1 默认可见性:公有可见性 301 13.2 可见性关键字 302 13.3 Public可见性 303 13.4 Protected可见性 304 13.5 Private可见性 305 13.6 作用域内私有和作用域内受保护可见性 306 13.7 对可见性...

    CLR.via.C#.(中文第3版)(自制详细书签)Part2

    6.6.2 合理使用类型的可见性和成员的可访问性 6.6.3 对类型进行版本控制时的虚方法的处理 第7章 常量和字段 7.1 常量 7.2 字段 第8章 方法 8.1 实例构造器和类(引用类型) 8.2 实例构造器和结构(值类型) 8.3...

    UML用例图的包含,扩展,泛化的详细阐述.doc

    包含关系是一种从现有的用例中抽取出公共的那部分信息,作为一个单独的用例,然后通过不同的方法来重用这个公共的用例,以减少模型维护的工作量。包含关系对典型的应用就是复用,也就是定义中说的情景。但是有时当某...

    Kotlin 中文文档.pdf

    类和继承 属性和字段 接口 可见性修饰词 扩展 数据对象 泛型 嵌套类 枚举类 对象表达式和声明 代理模式 代理属性 函数和lambda表达式 函数 高阶函数和lambda表达式 内联函数 其它 多重申明 Ranges 类型检查和自动...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    11.3.7 访问控制符可见性汇总 306 11.3.8 访问控制符带来的覆盖问题 306 11.3.9 final:不允许方法被覆盖 310 11.3.10 重温静态方法 311 11.3.11 静态方法——类范围里的概念 312 11.3.12 静态方法何以为“静态...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    11.3.7 访问控制符可见性汇总 306 11.3.8 访问控制符带来的覆盖问题 306 11.3.9 final:不允许方法被覆盖 310 11.3.10 重温静态方法 311 11.3.11 静态方法——类范围里的概念 312 11.3.12 静态方法何以为“静态...

    C++编程思想习题

    3.6.1可见的实现部分 3.6.2减少重复编译 3.7小结 3.8练习 第4章 初始化与清除 4.1用构造函数确保初始化 4.2用析构函数确保清除 4.3清除定义块 4.3.1for循环 4.3.2空间分配 4.4含有构造函数和析构函数的stash 4.5含有...

    JAVA面试题最全集

    被声明为final的方法也同样只能使用,不能重载 finally?再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。 ...

    KotlinTutorials:这是一个包含有关Kotlin编程语言的课程和示例的项目。

    Kotlin教程 什么是Kotlin? 我添加了它支持的平台和...可见性修改器 抽象类 介面 嵌套和内部类 资料类别 密封类 对象声明和表达式 伴侣对象 扩展功能 资源 https://kotlinlang.org/docs/kotlin-docs.pdf https://

    Kotlin官方参考文档中文版

    可见性修饰符 扩展 数据类 密封类 泛型 嵌套类 枚举类 对象 2 1.5.12 1.5.13 1.6 1.6.1 1.6.2 1.6.3 1.6.4 1.7 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.7.10 1.7.11 1.7.12 1.7.13 1.7.14 1.8 ...

    java自学之道

    5.4 包的可见性 接口 6.1 接口的概念 6.2 接口的声明 6.3 接口的实现 四、IO流及异常处理 1、流和文件 1.1 流 1.2 文件 2、常用流类 2.1 字节流 2.1.1 InputStream(输入流) 2.1.2 OutputStream(输出流) 2.1.3...

    DWR.xml配置文件说明书(含源码)

    解析规则是不可见的,但有两种例外情况. 一种情况是因为DWR1.0的解析器中有个Bug,在有些场合会无法处理返回值的类型.所以应该要避免这种情况的发生. 一种情况是因为解析器是一个语法宽松的解析器,他不象编译器一样对...

    CLR.via.C#.(中文第3版)(自制详细书签)Part1

    6.6.2 合理使用类型的可见性和成员的可访问性 6.6.3 对类型进行版本控制时的虚方法的处理 第7章 常量和字段 7.1 常量 7.2 字段 第8章 方法 8.1 实例构造器和类(引用类型) 8.2 实例构造器和结构(值类型) 8.3...

    CLR.via.C#.(中文第3版)(自制详细书签)

    6.6.2 合理使用类型的可见性和成员的可访问性 6.6.3 对类型进行版本控制时的虚方法的处理 第7章 常量和字段 7.1 常量 7.2 字段 第8章 方法 8.1 实例构造器和类(引用类型) 8.2 实例构造器和结构(值类型) 8.3 ...

    CLR.via.C#.(中文第3版)(自制详细书签)Part3

    6.6.2 合理使用类型的可见性和成员的可访问性 6.6.3 对类型进行版本控制时的虚方法的处理 第7章 常量和字段 7.1 常量 7.2 字段 第8章 方法 8.1 实例构造器和类(引用类型) 8.2 实例构造器和结构(值类型) 8.3...

    综合非对称暗物质模型

    我们提出了一种有关ADM的综合理论,该理论解决了质量密度相似性问题,超越了通常ADM对相似数密度的解释。 它具有显式的物质-反物质不对称产生机理,具有完整的热历史和其他可能性的建议,并且满足所有现象学,宇宙...

    快学 scala 中文版 带完整目录

    7.6 包可见性 97 7.7 引入 97 7.8 任何地方都可以声明引入 98 7.9 重命名和隐藏方法 99 7.10 隐式引入 99 练习 100 第8章 继承 A1 103 8.1 扩展类 103 8.2 重写方法 104 8.3 类型检查和转换 105 8.4 受...

    程序设计基础(C) 视频.txt

    5.4.2可见性105 5.4.3生存期105 5.5编译预处理105 5.5.1文件包含106 5.5.2宏定义106 5.5.3条件编译108 5.6多文件结构109 本章小结110 习题110 第6章指针114 6.1指针的概念114 6.1.1指针变量的声明115 6.1.2指针变量...

Global site tag (gtag.js) - Google Analytics