包外受保护字段的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