Java:谈谈protected访问权限

本文分析一下protected 访问权限。
author: ZJ 2007-3-5
Blog: [url]http://zhangjunhd.blog.51cto.com/[/url]
 
来谈谈 protected 访问权限问题。看下面示例 1
Test.java
class MyObject {}
 
public class Test {
    public static void main(String[] args) {
       MyObject obj = new MyObject();
       obj.clone(); // Compile error.
    }
}
此时出现上文提到的错误: The method clone from the type Object is not visiuable.
我们已经清楚 Object.clone() protected 方法。这说明,该方法可以被同包( java.lang )下和它( java.lang.Object )的子类访问。这里是 MyObject 类(默认继承 java.lang.Object )。
同样 Test 也是 java.lang.Object 的子类。但是,不能在一个子类中访问另一个子类的 protected 方法,尽管这两个子类继承自同一个父类。
再看示例 2
Test2.java
class MyObject2 {
    protected Object clone() throws CloneNotSupportedException {
       return super .clone();
    }
}
 
public class Test2 {
    public static void main(String[] args) throws CloneNotSupportedException {
       MyObject2 obj = new MyObject2();
       obj.clone(); // Compile OK.
    }
}
这里,我们在 MyObject2 类中覆盖( override )父类的 clone ()方法,在另一个类 Test2 中调用 clone ()方法,编译通过。
编译通过的原因显而易见,当你在 MyObject2 类中覆盖 clone ()方法时, MyObject2 类和 Test2 类在同一个包下,所以此 protected 方法对 Test2 类可见。
分析到这里,我们在回忆一下 Java中的浅复制与深复制 文中,章节 2.2 中的声明, 在派生类中覆盖基类的clone() 方法,并声明为public 现在明白这句话的原因了吧(为了让其它类能调用这个类的 clone() 方法,重载之后要把 clone() 方法的属性设置为 public )。
下面再来看示例 3
Test3.java
package 1
class MyObject3 {
protected Object clone() throws CloneNotSupportedException {
       return super .clone();
    }
}
 
package 2
public class Test3 extends MyObject3 {
    public static void main(String args[]) {
       MyObject3 obj = new MyObject3();
       obj.clone(); // Compile error.
       Test3 tobj = new Test3();
       tobj.clone(); // Complie OK.
    }
}
这里我用 Test3 类继承 MyObject3 ,注意这两个类是不同包的,否则就是示例 2 的情形。在 Test3 类中调用 Test3 类的实例 tobj clone ()方法,编译通过。而同样调用 MyObject3 类的实例 obj clone ()方法,编译错误!
意想不到的结果, protected 方法不是可以被继承类访问吗?
必须明确,类 Test3 确实是继承了类 MyObject3 (包括它的 clone 方法),所以在类 Test3 中可以调用自己的 clone 方法。但类 MyObject3 protected 方法对其不同包子类 Test3 来说,是不可见的。
这里再给出《 java in a nutshell 》中的一段话:
protected access requires a little more elaboration. Suppose class A declares a protected field x and is extended by a class B, which is defined in a different package (this last point is important). Class B inherits the protected field x, and its code can access that field in the current instance of B or in any other instances of B that the code can refer to. This does not mean, however, that the code of class B can start reading the protected fields of arbitrary instances of A! If an object is an instance of A but is not an instance of B, its fields are obviously not inherited by B, and the code of class B cannot read them.
顺便说两句,国内的很多 Java 书籍在介绍访问权限时,一般都这样描述(形式各异,内容一致):
方法的访问控制:
 
public
protected
default
private
同类
T
T
T
T
同包
T
T
T
 
子类 ( 不同包 )
T
T
 
 
不同包中无继承关系的类
T
 
 
 
所以我想说的是,多读些英语原版书籍。

你可能感兴趣的:(java,访问权限,protected)