2016-10-17 85 views
2

我被给了一个问题来确定以下访问是否合法。受保护字段外部包的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场protectedextendsA1所以B2是A1的亚型。 3.访问控制基于静态类型,x的静态类型为A1。

但面试官说答案应该是非法的。任何人都可以解释这一点?非常感谢。

+2

这将帮助[控制对类的成员的访问](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) –

+0

恕我直言,正确的采访答案是:“它不编译它的事情,不应该首先完成!“ –

回答

0

protected构件或构造方法的对象可以从它仅由代码中声明的封装,外部访问负责执行对象

看到https://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.6.1

实施例6.6-1。访问控制:

package points; 
public class Point { 
    protected int x, y; 
    public void move(int dx, int dy) { x += dx; y += dy; } 
    public int getX() { return x; } 
    public int getY() { return y; } 
} 

字段x和y的声明保护,并且是包点外部访问仅在Point类的子类,而只有当他们正在通过代码实现的对象领域即访问它们。

所以在B2类,它可以访问的本身或B2对象y1,但不能访问的SomePack.A1 x或任何其他A1的子类的对象y1

+0

谢谢。如何解释这句话:'只有当它们是正在访问它们的代码正在实现的对象的字段时。 ?' –

+0

@FongTinyik这意味着如果使用'x'和'y'的代码也是实现相应子类的代码,则可以在包外部访问'x'和'y'。 – locoyou

+0

实现“相应子类”的代码只能访问“相应子类”的(对象)的“x”,“y”。 – locoyou

-1
  • A protected成员只能在子类之外的包之外访问。
  • 如果您需要访问protected成员变量外包,它只需要通过继承来访问。
  • 如果需要使用引用变量访问它,它需要位于同一个包中。

下面的例子将在上面进行阐述。

当您修改成员变量为protected时,那么受保护的成员变量只能通过继承在包外部访问。

声明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); 
    } 

} 
+0

如果我想更改'x'的y1字段,该怎么办? –

+0

我们已经在做它。请检查更新的代码。 –

+0

感谢Prasad并祝贺10k。但我的问题是为什么不能访问'x'的'y1'字段,而不是如何访问'this'的'y1'。 –

0

受保护的修饰符用于继承,对于包可见性只使用无修饰符。

这里是什么样的不同的可见旨在为

public修改的简要说明用于在需要时能见度无处不在:当你想要的类的内容

public void someMethod(){ 
    //user code here 
} 

protected改性剂通过继承可访问:

protected void someMethod(){ 
    //user code here 
} 

当您想要p时不使用修饰符只有ackage知名度:

void someMethod(){ 
    //user code here 
} 

最后private是当你想不可见,只希望在内部使用它。

private void someMethod(){ 
    //user code here 
} 

对于上述我要提到的一个更详细的解释:Controlling Access to Members of a Class