我有一个问题来确定以下访问是否合法。
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。
但面试官说答案应该是非法的。有人可以帮忙解释一下吗?非常感谢。
答案 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
中,它可以访问自己的y1
或B2
的对象,但无法访问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);
}
}