浏览 1799 次
锁定老帖子 主题:javac与protected
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-09-09
最后修改:2009-09-09
声明:希望大家拍砖,但不要人身攻击
protected:是包和子类可见。但有一个现象很难理解(子类在不同的包中),举个例子。 设计三个类,TObject(基类,其中有个protected void sayHello()方法),TObjectExtends1,TObjectExtends2; 其中TObject和TObjectExtends1在一个包中,TObjectExtends2在另一个包中; TObjectExtends1和TObjectExtends2继承TObject;然后在TObjectExtends1中运行TObjectExtends2的sayHello()方法。 编译通过,然后运行成功; 然后我在TObjectExtends2中重写了sayHello()方法,权限是protected,然后编译,编译器报错,试图在TObjectExtends1中调TObjectExtends2中受protected方法; 如果把TObjectExtends2 te2=new TObjectExtends2();改成TObject te2=new TObjectExtends2();改一下声明;又居然可以编译通过了,运行成功; 也就是说在不同包的子类中调用其他子类的protected方法,有可以成功(如果调用的子类没有覆盖父类的protected),也有可能失败,如果都声明成最大的那个超类,那都可以运行了,貌似是编译器的错, 测试代码: TObject: package extends1; public class TObject { /** * Method TObject * * */ public TObject() { // TODO: Add your code here } protected void sayHello(){ System.out.println("TObject"); } } TObjectExtends1: package extends1; import extends2.*; public class TObjectExtends1 extends TObject { /** * Method TObjectExtends2 * * */ public TObjectExtends1() { // TODO: Add your code here } public static void main(String[] args){ TObject te2=new TObjectExtends2(); te2.sayHello(); // TObjectExtends2 te2=new TObjectExtends2(); // te2.sayHello();编译通不过 } } TObjectExtends2: package extends2; import extends1.TObject; public class TObjectExtends2 extends TObject { /** * Method TObjectExtends1 * * */ public TObjectExtends2() { // TODO: Add your code here } @Override protected void sayHello(){ System.out.println("TObjectExtends2"); } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-09-09
最后修改:2009-09-09
在main方法里面,是不存在具体的某个类,因而没有类继承的可见性,只有包的可见性。
因而: TObject te2=new TObjectExtends2(); te2.sayHello(); 当前main所在的类与te2的声明类在同一包里,因而是正确的调用,可以通过编译。 第二种情形,main所在类与te2的声明类不在同一个包,因而不能编译通过。 |
|
返回顶楼 | |
发表时间:2009-09-09
= =!不明白楼主想说的是什么?
|
|
返回顶楼 | |
发表时间:2009-09-09
首先谢谢大家的回复
dengtl 写道 在main方法里面,是不存在具体的某个类,因而没有类继承的可见性,只有包的可见性。
我对你的解释有点疑问: 如果在main方法中没有继承的可见性,那我把那个代码放到另一个方法中应该可以了吧;但编译还是通不过。 package extends1; import extends2.*; public class TObjectExtends1 extends TObject { /** * Method TObjectExtends2 * * */ public TObjectExtends1() { // TODO: Add your code here } public void mainTest(){ TObjectExtends2 te2=new TObjectExtends2();//[color=red]编译通不过[/color] te2.sayHello(); } public static void main(String[] args){ //TObject te2=new TObjectExtends2(); //te2.sayHello(); // TObjectExtends3 te3=new TObjectExtends3(); // te3.sayHello(); TObjectExtends1 te1=new TObjectExtends1(); te1.mainTest(); } } 难道你说的是对于编译器来说继承的可见性是没有的吗?但在子类中可以调父类的properted的域和方法(子类和父类不在同一个包),希望你详细介绍。 我觉得编译器是不允许一个基类的兄弟子类之间相互调protected的域和方法,如果我们用基类,编译器的语法检查可以通过了,但解释器遇到这个时他会用动态绑定来找到子类的那个方法;希望大家谈谈自己的看法 |
|
返回顶楼 | |
发表时间:2009-09-11
我也觉得有点多态的意思,使用父类的引用,调用protected方法,编译器能够通过。 在执行的时候,由于父类的方法被子类2给覆盖了,所以执行子类2的方法。
我只能理解到这个层次上了,再深入就不知了 |
|
返回顶楼 | |
发表时间:2009-09-11
多态的原因
你按照t2来声明,t2的sayHello只对直接继承对象有可见性,所以main方法不可以调用。 按照父类声明,TObject的sayHello是任意可见的,main方法可以调用,但是是调用哪一个方法是由实例子类决定的,这里T2是实例,t2覆盖了夫类sayHello()方法,相当于sayHello对于TObject是可见的,所以最后结果是TObjectExtends2的sayhello被调用 可以这样理解,TObjectExtends2的sayhello对mian不可见,但是对T1可见,就像你不能学生听话,好好写作业,可以叫家长,家长能让学生好好写作业 java里面有个规定,就是从夫类到子类,方法的可见性应该逐渐放开,而不是逐渐缩小 否则就会有你现在的尴尬,虽然声明为protect,但是封装性依旧被继承破坏了 |
|
返回顶楼 | |