时间:2016-10-17 06:53:35

标签: 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字段为protected 2. B2 extends A1所以B2是A1的子类型。 3.访问控制基于静态类型,x的静态类型为A1。

但面试官说答案应该是非法的。有人可以帮忙解释一下吗?非常感谢。

3 个答案:

答案 0 :(得分:0)

protected修饰符用于继承,因为包可见性仅使用无修饰符。

以下是对

的不同可见性的简要说明 当需要在任何地方都可见时,使用

public修饰符:

public void someMethod(){
    //user code here
}
如果希望通过继承访问类的内容,则使用

protected修饰符:

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

如果只需要包可见性,则不使用修饰符:

void someMethod(){
    //user code here
}

最后private适用于您不想要的情况,只想在内部使用它。

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

有关上述内容的更详细说明,请参阅:Controlling Access to Members of a Class

答案 1 :(得分: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中,它可以访问自己的y1B2的对象,但无法访问y1的{​​{1}}或任何其他对象SomePack.A1 x的子类。

答案 2 :(得分:-1)

  • 只能在子类中的包外部访问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);
    }

}