我知道这是java的基本语法规则,至于为什么这样设计,找了些资料,说是因为多态,如果有更严格的访问权限,通过子类就不能访问父类中的方法还是什么原因……,总之看的不是很明白假设这样class A {
public void test(){
}
}class B extends A{
void test(){
}
}子类中重写的方法test()比父类中的方法具有更严格的访问权限,那么
A a = new B;
a.test(); // 把A,B放在同个包内,因为子类中重写的方法是default权限,即同一个包内的类都可以访问的,那么会出现什么问题呢,不是可以访问吗很乱,感觉是多态和权限方面的知识搞混了麻烦大家帮忙解释下,总之就是为什么这样规定,如果不这样实现多态的时候会出现什么问题???
public void test(){
}
}class B extends A{
void test(){
}
}子类中重写的方法test()比父类中的方法具有更严格的访问权限,那么
A a = new B;
a.test(); // 把A,B放在同个包内,因为子类中重写的方法是default权限,即同一个包内的类都可以访问的,那么会出现什么问题呢,不是可以访问吗很乱,感觉是多态和权限方面的知识搞混了麻烦大家帮忙解释下,总之就是为什么这样规定,如果不这样实现多态的时候会出现什么问题???
解决方案 »
- Java 对象序列化,有疑问?
- 如何快速学习struts 1.0啊
- 有个概念不知道,大家都明白不?
- 哪位仁义的大哥能帮小弟个忙。。一个让我头疼的编程
- JB9哪有注册版的下载呀?
- 如何创建速度快,效率高的聊天室,欢迎大家交流!!!!
- 为我的jsp聊天室出点主意吧(没做过的不妨尝尝这个挑战哦)。
- 我想学JAVA ,是买THINK IN JAVA 还是JAVA2核心技术:卷1 好???
- java在中国的前途将会极其艰难
- DWRSession过期拦截,通过继承实现 DWRSessionServiceextendsDefaultRemoter 登陆时如何绕过这个验证
- 莱鸟请教各位一个问题
- 一个java调试问题
会让你越来越乱,待到有了几个工作
对整个JAVA的机制有了很好的了解再回来看这个问题
限制子类化当然也有它的使用场合,但更多的是让人觉得困惑、增加了编程难度:在使用某个对象的时候,必须要知道它的实际类型,免得调用了“在子类中已经不允许调用的方法”。而对于建立在反射基础上的Java,限制子类化就更加危险了。(反射可以动态加载类并创建其对象。换句话说,只有程序运行到某句代码,才能知道这句代码中那个对象的真实类型。如果某个类的成员在子类中的访问级别不可预料,那这种打击是相当致命的!!说得严重一点,你就不敢使用动态绑定了,多态性也就变成空谈了。)
出于种种原因,于是呢,Java中不再允许这样做。
说了一大堆,其实就一句话:
就是语法规则,楼主不必细抠了。
一定要琢磨这事,就成钻牛角尖啦,呵呵。
关键理解子类可以"替换"父类.
如果父类提供了一个方法,但是子类中限制了这个方法的访问权限,那么这种替换功能就无法实现了.
a.test(); // 调用的是子类的test方法
继承关系可以表述为 is-a 的关系,也就是说如果B继承A,那么
A,B的关系为 B is a A,从字面上理解就是说: B类是一个A类(实际上,B类除了是一个A类之后还会比A多一些东西)
从上面的关系可以得知,B必须包含A的所有东西(包括成员变量,成员方法,等等)
那么,从外界看来,如果A有一个public的test方法,B就应该要有一个public的方法,为什么呢?
因为,比如在一个C类(不和A B在同一个包)里面去看A和B,如果能调用A的test,而不能调用B的test,就会给C这个类觉得,B不是A,所以B必须要有一个public的test方法.
因此,子类覆盖的成员访问权限不能低于父类.2.从安全的角度去考虑:
同样是B继承A. 如果A有一个public的test方法,而B覆盖的时候是一个protected的test方法,那么
在B所在的包外就不能用B的实例对象来调用test方法了(因为B的test是protected的).
但是,如果你用这种方法就可以绕过这个protected的访问权限了:
A a = new B();
a.test();
因为A的test是public的,所以a.test()是可以的,但是
根据多态的性质,引用a实际上指向的内存是一个B类的对象,当运行时,a.test()实际上是会执行B类的test方法,这样就绕过了B类的protected的访问权限了.因此这样是不安全的.综上两点所述,子类覆盖的访问权限必须大于等于父类.等待另外的看法.