`
lfx_cool
  • 浏览: 67807 次
  • 性别: 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()相对于调用一个不存在的方法,所以出现编译错误。
分享到:
评论

相关推荐

    Java方法继承、方法重载、方法覆盖总结

    1. **可见性修饰符**: 当子类`SubBase`继承自父类`Base`时,父类中的所有`public`和`protected`方法都可以被子类访问。如果父类的方法为默认访问级别(即没有任何修饰符,相当于`package-private`),则只有当子类与...

    JAVA面试题

    第六题和第八题分别讨论了类的方法调用方式和访问数据库的API所在包。在Java中,静态方法(由`static`关键字修饰)可以通过类名直接调用,无需创建类的实例。同时,`public`关键字表示该方法或类可以被任何其他类...

    Java类变量和方法.doc

    最后,访问控制符决定了类成员的可见性:`private`限于本类,`protected`允许同包和子类访问,`public`对所有代码开放,而默认的包访问权限允许同包内的访问。 理解这些概念对于编写健壮、安全且高效的Java代码至关...

    java修饰符总结

    5. **方法(method)可见性修饰符**: - `public`:方法对所有类可见。 - `protected`:方法对子类和同一包内的类可见。 - `private`:方法只对定义它的类可见,不能被子类访问。 - 缺省:在同一包内可见,子类...

    JAVA方法

    9. **方法的可见性** - `public`:任何地方都可以访问。 - `private`:只能在同一个类内部访问。 - `protected`:在同一个包或子类中可以访问。 - 默认(无修饰符):在同一包内可以访问。 10. **异常处理** ...

    带参数的方法.zip

    此外,你可能还会学习到**重载方法**,这是Java中的一种多态性体现。如果一个类中有多个同名但参数列表不同的方法,Java会根据传入的参数类型和数量来决定调用哪个方法。例如,你可以定义一个接受两个浮点数的`...

    java 如何访问同名的方法或变量

    在Java编程语言中,处理同名的方法或变量是一项常见的挑战,尤其是在处理继承、包和类的层次结构时。...在处理同名方法时,重载和重写是两种常用策略,而访问修饰符和多态性则在处理同名变量时起到关键作用。

    java习题集4java习题集4.doc

    14. 访问权限与封装:Java的封装性通过访问权限控制(如private, public, protected等)实现,允许我们控制类的成员对外部的可见性。 15. 构造方法调用顺序:子类构造方法在初始化时,会先调用父类的构造方法。 16...

    java面向对象的设计方法

    在Java中,我们使用访问修饰符(public, private, protected等)来控制类成员的可见性,从而实现封装。这样可以防止代码的误用,提高程序的安全性和可维护性。 继承是另一个关键特性,它允许一个类(子类)从另一个...

    解释UML用例图中包含,扩展、泛化的区别.doc

    UML 用例图是Unified Modeling Language(统一建模语言)中的一种图形表示方法,用于描述系统的功能和行为。在 UML 用例图中,包含、扩展和泛化是三种基本关系,它们之间的区别和联系对正确理解 UML 用例图至关重要...

    面向对象练习

    在Java中,我们通过访问修饰符(如public、private、protected)来控制类的成员变量和方法的可见性。例如,我们可以定义一个私有变量(private),然后提供公共的getter和setter方法来读取和修改该变量的值,这样既...

    第3章 类的方法课件及源代码,第5周实验题目及参考解答

    7. **访问修饰符**:如`public`、`private`、`protected`和默认(包访问),控制方法的可见性和访问范围。 8. **重载和覆盖**:方法重载是指在同一个类中定义多个同名但参数列表不同的方法;方法覆盖发生在子类覆盖...

    Java访问修饰符

    final 方法访问修饰符表示防止任何子类重载该方法。 abstract 方法访问修饰符 abstract 方法访问修饰符表示抽象方法,抽象方法是不能被实现的方法。 native 方法访问修饰符 native 方法访问修饰符表示定义的方法...

    JAVA开发工程师试题J801A

    此外,对访问修饰符的理解,构造函数、重载与重写、this关键字、super关键字的使用也是重要的考点。 三、数据结构与算法 试题中可能包含数组、链表、栈、队列、集合、映射等基本数据结构的运用,以及排序(如冒泡、...

    4、JavaSE:方法-6.pdf

    修饰符决定方法的可见性和访问权限,如`public`、`private`等。返回值类型指明方法执行后可能返回的数据类型,如果是无返回值,使用`void`。方法名应具有描述性,方便理解其作用。参数列表描述了方法接受的输入,...

    OraclePlSql包(package).pdf

    ### 重载包级子程序 重载是指在同一个包中定义多个同名的过程或函数,但是它们具有不同的参数列表。这样,根据传入的参数不同,可以调用不同的子程序。 ### 系统包概述 Oracle提供了一些系统包,它们是预定义的包,...

    第3章计算面积周长——方法与作用域.ppt

    - 变量的作用域决定其可见性和生命周期。在Java中,局部变量(定义在方法内)仅在方法内可见,而成员变量(类级别)在整个类中都可见。 - 如果需要在方法之间共享数据,可以使用类字段(实例变量),或者使用类...

    jQuery可见性过滤选择器用法示例

    `slideToggle()`方法是jQuery中的一个动画效果函数,用于切换元素的可见性。在示例中,它被用于一个ID为`mover`的元素,每次点击该元素都会执行动画,使其在慢速动画效果中切换显示状态。 此外,示例中还包含了一个...

    JAVA全部PPT,PPT

    封装确保了数据的安全性,通过访问修饰符(如public、private、protected等)来控制类成员的可见性和可访问性,避免了不必要的外部干扰。在Java中,构造方法是创建对象时自动调用的特殊方法,主要负责初始化对象的...

    完整版 Java基础教程 Java入门教程 Java语言程序设计 第5章 方法定义及调用(共20页).ppt

    - **访问控制符**:如`public`、`private`、`protected`等,控制方法的可见性。 - **修饰符**:包括`static`、`final`、`abstract`等,它们影响方法的行为。 - **返回值类型**:表示方法执行后返回的数据类型,可能...

Global site tag (gtag.js) - Google Analytics