重载方法的包可见性问题

今天看到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()相对于调用一个不存在的方法,所以出现编译错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值