java protected

1. protected 访问控制符能被用于方法和成员变量。
  
 2. 声明为protected的方法和成员变量能被同一个包里的所有类所访问,就像默认修饰符package一样。
  
 3. 能被该类的子类所访问,子类可以和父类不在一个包中。
  
 这样,当你想让一个类中的某个方法或成员变量在包中都可见,而且其子类也能访问(子类有可能和父类不在同一个包中)但又不想让所有类都可以访问该类时,就可以用protected修饰符。

    可访问性:  public > protected > package >private

 注意:
 4. But a subclass in another package can access the protected members in the super-class via only the references of subclass or its subclasses. A subclass in the same package doesn’t have this restriction. This ensures that classes from other packages are accessing only the members that are part of their inheritance hierarchy.

但是位于与父类不同包中的一个子类,能够使用其父类中protected成员的途径只能是,使用子类(或者是子类的子类)的引用。子类和父类在同一个包中则没有这个限制。这样就保证了其他包中的类只能访问它们所继承的部分成员。

下面的例子可以说明上述几点:(特别注意第4点)

1 创建一个父类Bird.java,放在birdpack包中,父类中有一个protected int的成员变量nFeathers:

 
 
  1. package birdpack;  
  2.  
  3. public class Bird {  
  4.     protected int nFeathers;  

2 创建Bird的一个子类Duck1.java,放在duckpack包中,这个程序说明在子类中直接使用父类的protected变量是可以的,父类的protected权限的成员变量可以被子类继承

 
 
  1. package duckpack;  
  2.  
  3. import birdpack.Bird;  
  4.  
  5. public class Duck1 extends Bird {  
  6.     public void setn(int duck1n) {  
  7.         nFeathers = duck1n;  
  8.     }  

3 创建Bird的一个子类Duck2.java,放在duckpack包中,这个程序说明在子类中通过子类的对象访问父类的protected成员是可以的

 
 
  1. package duckpack;  
  2.  
  3. import birdpack.Bird;  
  4.  
  5. public class Duck2 extends Bird {  
  6.     public void constructor(int newDuck2) {  
  7.         Duck2 d2 = new Duck2();  
  8.         //在子类中通过子类的对象访问父类中的protected变量  
  9.         d2.nFeathers = newDuck2;  
  10.     }  

4 创建Bird的一个子类Duck3.java,放在duckpack包中,这个程序说明在子类中使用父类的对象访问父类的protected成员反而是不行的

 
 
  1. package duckpack;  
  2.  
  3. import birdpack.Bird;  
  4.  
  5. public class Duck3 extends Bird {  
  6.     public void constructor(int newDuck3) {  
  7.         Bird b = new Bird();  
  8.         //子类中用父类对象反而不能访问父类中的protected变量  
  9.         //b.nFeathers = newDuck3;  
  10.     }  

5 创建Bird的一个子类Swan.java,放在duckpack包中,这个程序说明在子类中使用其他子类的对象访问父类的protected成员也是不行的

 
 
  1. package duckpack;  
  2.  
  3. import birdpack.Bird;  
  4.  
  5. public class Swan extends Bird {  
  6.     public void constructor(int swan) {  
  7.             Duck1 d1 = new Duck1();  
  8.             //子类中用另外一个子类的对象也不能访问父类中的protected变量  
  9.             //d1.nFeathers = swan;  
  10.     }  
  11. }  

-------------------------------------------------------------------------------------------------------------------------------

转载这篇文章,主要是为了说明,虽然在java中,父类中protected权限的成员变量可以被子类访问,但是还是有条件的,具体如下:

1.在子类中直接使用父类的protected变量是可以的,父类的protected权限的成员变量可以被子类继承

2.在子类中通过子类的对象访问父类的protected成员是可以的

3.在子类中使用父类的对象访问父类的protected成员反而是不行的

4.在子类中使用其他子类的对象访问父类的protected成员也是不行的

原文链接:http://www.bitscn.com/plus/view.php?aid=20796



作者:狄方方
链接:https://www.zhihu.com/question/30643322/answer/88352660
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这里存在一个很大的误区:子类(父类的外部包)中访问父类的protetcted属性或者方法,是不可以通过创建父类对象调用的。
注意:此处不讨论同包下的父类子类,因为同包下所有类都可访问protected属性或者方法。

请参见Java官方文档:Chapter 6. Names中的6.6.2.1. Access to a protected Member
具体例子如下:

父类C:在包c下
package c;
public class C {
  protected int id;
  protected void test() {

  }
}

子类S:在包s下
package s;
import c;
import q;
import t;
public class S extends C {
void accessProtected() {
  //C中的protected仅允许其子类S内部访问
  id = 5;
  test();
  //此外通过E.id访问(在C子类S的内部),则E必须是S或者S的子类(注意不是C)
  S s = new S();
  s.id = 6;
  s.test();

  Q q = new Q();
  q.id = 5;
  q.test();

  //此外通过E.id访问(在C子类S的内部),则E必须是S或者S的子类(注意不是C)
  //所以c.id不可访问
  // C c = new C();
  // c.id;
  // c.test();

  //此外通过E.id访问(在C子类S的内部),则E必须是S或者S的子类(注意不是C)
  //所以t.id不可访问
  // T t = new T();
  // t.id;
  // t.test();
  }
}



S的子类Q,包q下
package q;
import s;
public class Q extends S{

}



C的子类T,包t下
package t;
import c;
public class T extends C {

}


public class testC {
	private int a;
	public void testF(testC a) {
		testC t = new testC();
		this.a = t.a;
		this.a = a.a;
	}
	public testC() {
	}
}

只有在类定义下才可以实现类对象(实例)直接访问类私有成员。
具体的原因我简单百度了下,结合自己浅薄的知识有这样一个猜测:
private(私有域)定义为本类作用域可见。即testC{私有域}中定义的成员,方法在本域是可见的。
类比{}中定义的局部变量,只有在{}中才是可见的(java)。
注意一个问题,由于子类继承的问题,java中直接使用extends继承,所以基类的私有域实际上也是子类的私有域。
很可能我的猜测是错的,就当做是抛砖引玉吧。



  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值