Java:由Object.clone()而引出的protected权限问题

Object.clone()

大家可能不太理解由Object.clone()而引出的protected权限问题这句话,那我们先看一段代码:
第一个类CloneClassOne

package com.ustc.sup;
public class CloneClassOne {
}

第二个类CloneClassTwo

package com.ustc.sup;

public class CloneClassTwo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        CloneClassOne one=new CloneClassOne();
        one.clone();
        Object object = new Object();
        object.clone(); 
    }
}

大家觉得这段代码有没有错呢?
答案:
one.clone();和object.clone();这两句提示The method clone() from the type Object is not visible

我们会有疑问:Object类是所有类的父类,那么为什么子类不能访问父类的protected修饰的方法呢?
与基类不在同一个包中的子类,只能访问自身从基类继承而来的受保护成员,而不能访问基类实例本身的受保护成员
例如:
父类Person在包com.ustc.sub;

package com.ustc.sub;

public class Person {

    protected int a = 4;

    protected int getA() {
        return a;
    }
}

子类Manager 、Student在包com.ustc.sup

package com.ustc.sup;

import com.ustc.sub.Person;

public class Student extends Person {

    int getB()
    {
        return getA();
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Manager m = new Manager();
        System.out.println(m.getB());
        System.out.println(m.getA());//error
    }

}
package com.ustc.sup;

import com.ustc.sub.Person;

public class Manager extends Person {

    int getB()
    {
        return getA();
    }
    public static void main(String[] argr) {
        Student s = new Student();
        System.out.println(s.getB());
        System.out.println(m.getA());//error
    }
}

父类和子类不太一个包中,子类的方法getB()可以访问getA(),而实例s,m不能访问getA()方法。

protected

我们都知道:protected 修饰的类和属性,对于自己、本包和其子类可见
但这样说你并不完全正确
对于protected的成员或方法,要分子类和超类是否在同一个包中。与基类不在同一个包中的子类,只能访问自身从基类继承而来的受保护成员,而不能访问基类实例本身的受保护成员。在相同包时,protected和public是一样的
这里写图片描述

  • Class SubB has
    access only to the inherited from Base protected elements,
    i.e. its own elements, but the protecteddata of other Base instances
    is not accessible from SubB.

接下来将一些实例,看完既可以完全理解protected权限了
例1

class MyObject {}

public class Test {
    public static void main(String[] args) {
       MyObject obj = new MyObject();
       obj.clone(); // Compile error.
    }
}

虽然MyObject与Test属于同一个包,但受保护的clone方法来自java.lang.Object类型,而在Test中,其基类Object的受保护方法是不可见的。

例2

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.
    }
}

MyObject与Test在同一个包中,受保护的clone方法来自MyObject本身,所以它对Test而言是可见的。(在相同包时,protected和public是一样的)另外在这个示例中,还说明了super关键字对于基类受保护成员的调用是个语言设计之中的“例外”。

例3

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.
    }
}

企图跨越不同的包,从子类中调用基类实例的受保护方法。明显不行。

例4

class MyObject extends Test{}
public class Test {
  public static void main(String[] args) {
    MyObject obj = new MyObject();
    obj.clone(); // Compile ok.
  }
}

可见呢?因为MyObject的clone方法继承自Test,而Test做为相对于Object的子类,是可以访问继承而来的属于它自己的受保护方法的。

例5

package 1
class MyObject extends Test {
}

package 2
public class Test {
  public static void main(String args[]) {
    MyObject obj = new MyObject();
    obj.clone(); // Compile OK
  }
}

虽然处于不同的包,但子类的受保护方法实际上继承自父类,父类的自己的受保护方法对自己可见,其原理同示例4.

例6

package 1
class MyObject extends Test {
  protected Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
}

package 2
public class Test {
  public static void main(String args[]) {
    MyObject obj = new MyObject();
    obj.clone(); // Compile error!
  }
}

不同包中子类本身的受保护方法当然不可能对父类可见
例7

package a;
class MyObject extends Test {
    public static void main(String[] args) {
    Test test = new Test();
    test.clone(); // Compile error.
  }
}
package a;
public class Test {

}

同一个包中,父类实例的clone方法在子类中依然不可见,原理同示例1,就是因为父类的clone方法,实际上来自java.lang.Object。

推荐

http://www.tuicool.com/articles/neURniJ

  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值