包外受保护字段的Java访问控制
我被问到一个问题,以确定以下访问是否合法包外受保护字段的Java访问控制,java,Java,我被问到一个问题,以确定以下访问是否合法 package SomePack; public class A1 { ... protected int y1; } /////////// package Whatever; class B2 extends A1 { void h(SomePack.A1 x) { x.y1 = 3; // Is this line legal? } } 我想这应该是合法的 1.y1字段受保护 2.B2扩展了A1,因此
package SomePack;
public class A1 {
...
protected int y1;
}
///////////
package Whatever;
class B2 extends A1 {
void h(SomePack.A1 x) {
x.y1 = 3; // Is this line legal?
}
}
我想这应该是合法的
1.y1字段受保护
2.B2扩展了A1,因此B2是A1的一个子类型。
3.访问控制基于静态类型,x的静态类型为A1
但是采访者说这个答案应该是非法的。有人能解释一下吗?非常感谢
受保护的成员只能在子类中访问包外部。
如果您需要访问包外部的受保护成员变量,则只需要通过继承来访问它。
若需要使用引用变量访问它,那个么它需要在同一个包中。
下面的例子详细阐述了上述内容
当您将一个成员变量修改为受保护时,那个受保护的成员变量只能通过继承在包外部访问
package somepack;
public class A1 {
protected int y1;
}
class C{
public static void main(String args[]){
A1 obj = new A1();
System.out.println(obj.y1);
}
}
报表x.y1=3;它试图使用引用变量进行访问,这在包外是不可能的
如果您想访问它,只需将其设为y1=3
使用以下代码应该可以访问y1
package whatever;
import somepack.A1;
class B2 extends A1 {
void h(somepack.A1 x) {
System.out.println(y1);
y1 = 3;
System.out.println(y1);
}
public static void main(String args[]){
B2 obj = new B2();
obj.h(new A1());
}
}
这将在下面打印
0
3
如您所见,我们可以仅使用继承直接将值分配给受保护的成员
现在,让我们看看如何使用引用变量类型(即无继承)进行访问
package somepack;
public class A1 {
protected int y1;
}
class C{
public static void main(String args[]){
A1 obj = new A1();
System.out.println(obj.y1);
}
}
受保护的成员只能在子类中访问包外部。
如果您需要访问包外部的受保护成员变量,则只需要通过继承来访问它。
若需要使用引用变量访问它,那个么它需要在同一个包中。
下面的例子详细阐述了上述内容
当您将一个成员变量修改为受保护时,那个受保护的成员变量只能通过继承在包外部访问
package somepack;
public class A1 {
protected int y1;
}
class C{
public static void main(String args[]){
A1 obj = new A1();
System.out.println(obj.y1);
}
}
报表x.y1=3;它试图使用引用变量进行访问,这在包外是不可能的
如果您想访问它,只需将其设为y1=3
使用以下代码应该可以访问y1
package whatever;
import somepack.A1;
class B2 extends A1 {
void h(somepack.A1 x) {
System.out.println(y1);
y1 = 3;
System.out.println(y1);
}
public static void main(String args[]){
B2 obj = new B2();
obj.h(new A1());
}
}
这将在下面打印
0
3
如您所见,我们可以仅使用继承直接将值分配给受保护的成员
现在,让我们看看如何使用引用变量类型(即无继承)进行访问
package somepack;
public class A1 {
protected int y1;
}
class C{
public static void main(String args[]){
A1 obj = new A1();
System.out.println(obj.y1);
}
}
受保护的修饰符用于继承,对于包可见性,仅使用无修饰符 以下是不同可视性的用途的简要说明 当到处都需要可见性时,使用公共修饰符:
public void someMethod(){
//user code here
}
当您希望通过继承访问类的内容时,将使用受保护的修饰符:
protected void someMethod(){
//user code here
}
当您只需要包可见性时,不使用任何修改器:
void someMethod(){
//user code here
}
最后,private用于不需要可见性而只想在内部使用它的情况
private void someMethod(){
//user code here
}
有关上述内容的更详细解释,我将参考:受保护的修饰符用于继承,对于包可见性,只使用不使用修饰符 以下是不同可视性的用途的简要说明 当到处都需要可见性时,使用公共修饰符:
public void someMethod(){
//user code here
}
当您希望通过继承访问类的内容时,将使用受保护的修饰符:
protected void someMethod(){
//user code here
}
当您只需要包可见性时,不使用任何修改器:
void someMethod(){
//user code here
}
最后,private用于不需要可见性而只想在内部使用它的情况
private void someMethod(){
//user code here
}
有关上述内容的更详细解释,我将参考:对象的受保护成员或构造函数可以从包外部访问,在包中它只能由负责实现该对象的代码声明
看
例6.6-1。访问控制:
字段x和y被声明为受保护的,并且只有在类Point的子类中,并且只有当它们是由访问它们的代码实现的对象的字段时,才能在包点之外访问它们
因此,在B2类中,它可以访问自身的y1或B2的对象,但不能访问SomePack.A1 x的y1或任何其他A1的子类的对象。对象的受保护成员或构造函数可以从包外部访问,在包中它只能由负责实现该对象的代码声明
看
例6.6-1。访问控制:
字段x和y被声明为受保护的,并且只有在类Point的子类中,并且只有当它们是由访问它们的代码实现的对象的字段时,才能在包点之外访问它们
因此,在B2类中,它可以访问自身的y1或B2的对象,但不能访问SomePack.A1 x的y1或任何其他A1子类的对象。这将有助于IMHO正确的访谈答案是:编译不重要,首先不应该做!这将有助于IMHO正确的面试答案是:编译没关系,一开始就不应该这么做!如果我想换衣服怎么办
我们已经在做了。请检查更新的代码。感谢Prasad,祝贺你完成10公里。但我的问题是为什么不能访问x的y1字段,而不是如何访问其中的y1;公共类C1{protected int M;}包P2;类C2扩展了C1{void fP1.C1 x{x.M=3;}这是合法的吗?如果我想更改x的y1字段怎么办?我们已经在做了。请检查更新的代码。谢谢Prasad,祝贺达到10k。但我的问题是为什么不能访问x的y1字段,而不是如何访问其中的y1。因为java语言就是这样设计的:包P1;公共类C1{protected int M;}包P2;类C2扩展了C1{void fP1.C1 x{x.M=3;}这是合法的吗?谢谢。如何解释这句话:并且只有当它们是由访问它们的代码实现的对象字段时。@FongTinyik这意味着如果使用x和y的代码也是实现相应子类的代码,则可以在包外访问x和y。实现相应子类的代码子类也只能访问对应子类对象的x,y。因此在子点内部,我们只能访问这个.x或子点的其他实例的x。正确吗?@FongTinyik是的。但不能访问子点2.x的点.x。如何解释这句话:并且仅当它们是由代码t实现的对象字段时这意味着如果使用x和y的代码也是实现相应子类的代码,那么x和y可以在包外访问。实现相应子类的代码也只能访问相应子类对象的x,y。因此在子点内,我们只能访问这个.x或其他子类的x子点的实例。正确吗?@FongTinyik是。但无法访问子点2.x的点.x