我有以下两段代码:
/**
*
*/
package com.akshu.multithreading;
/**
* @author akshu
*
*/
public class MyThread extends Thread {
protected int b;
private int a;
@Override
public void run() {
super.run();
System.out.println("int a:"+a);
}
}
-----------
package com.akshu.utility;
import com.akshu.multithreading.MyThread;
public class MyUtility extends MyThread{
public static void main(String args[])
{
MyThread th1 = new MyThread();
int d =th1.b; // line1
System.out.println("int d"+d);
}
}
使用上面的代码文件我试图理解受保护的访问修饰符的目的。在文件MyUtility中,我试图引用类MyThread.But的变量b,它给我下面的错误:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The field MyThread.b is not visibilty.
我关注的是变量b应该可以从子类访问,因为我已经扩展了Mythread。但它给了我编译时错误。此外,当我在我的超类中将此变量声明为静态时,我能够直接访问它。当我尝试通过实例访问时,我正在做什么错误?
答案 0 :(得分:2)
您无法从实例访问受保护的属性。您只能在继承类中访问它们。在这一行 -
MyThread th1 = new MyThread (); int d = th1 . b ;
您实际上是在尝试从实例th1
访问受保护的属性。
答案 1 :(得分:2)
方法main不是MyThread的明确部分 - 如果你要实现另一个函数,例如prtintB(),您可以使用“。”直接访问。运营商。要从main访问它,你必须编写一个getter函数。
答案 2 :(得分:2)
从Kathy Sierra's好书中解释对protected
范围的误解:
但是对于包外的子类来说它意味着什么 访问超类(父)成员?这意味着子类继承 会员。然而,它并不意味着 subclass-outside-the-package可以使用引用访问该成员 到超类的一个实例。换句话说,protected = 遗产。受保护并不意味着子类可以对待 受保护的超类成员,就好像它是公共的一样。所以,如果 subclass-outside-the-package获取对超类的引用(by, 例如,在某处创建超类的实例 子类'代码',子类不能使用点运算符 超类引用访问受保护的成员。到了 子类 - 外包,受保护的成员也可能 默认(甚至是私有),当子类使用引用时 超类。 子类只能通过查看受保护的成员 继承。强>
因此,在您的情况下,您尝试使用引用来访问父类包之外的受保护成员:
MyThread th1 = new MyThread();
int d =th1.b; //b cannot be reached !
答案 3 :(得分:1)
Java lang规范第6.6.2.1节将告诉你实情:
如果访问是通过字段访问表达式
E.Id
,其中E
是主表达式,或是通过方法调用表达式E.Id(. . .)
进行访问,其中E
是主要表达式表达式,当且仅当E
的类型为S
或S
的子类时才允许访问。
此处MyThread
为C
,MyUtility
为S
,b为Id
。因此,在MyUtility ionstance中,您无法使用对实例pf MyThread
的引用来访问其b