当我自己写代码,把父类放一个包中,子类放另一个包中,子类没有重写父类的protect方法,在子类包中直接访问父类的 protect方法,不会提示错误。

但是为什么当我直接调用java中写好的类中protect方法时会提示不可见?

比如 clone()方法,它是根类Object的方法,当没有重写clone()扩大权限时,直接在自己写的类中调用 提示 不可见??这是怎么回事??


2个回答

protected 关键字是针对子类而言的。

A类要调用B类的protected方法只有两种可能(反射的情况不考虑!)

1.A是B的子类 2.A和B同一个包

package sun.nio.ch.a;

public class Father {

protected String getName() {
    return "Father";
}

}

package sun.nio.ch.a;

public class C {

public static void main(String[] args) {
    Father father = new Father();

    father.getName();    //可以访问,同包下
}

}

package sun.nio.ch.b;

import sun.nio.ch.a.Father;

public class Son extends Father {

public static void main(String[] args) {
    Father father = new Father();

    //father.getName()      //访问不了.

    Son son = new Son();

    son.getName();          //可以访问.子类
}

}


baidu的一段解释:

对于Object类,它的clone方法实现如下:

protected native Object clone() throws CloneNotSupportedException;

也就是说,如果你在它的子类中没有覆盖clone方法,永远都是抛出一个CloneNotSupportedException,这就是为什么一调用就失败。

要想使用的话,不仅要让子类实现Cloneable接口,还要覆盖这个clone方法。

如果用protected修饰,它的子类是可以访问的,所以子类调用的其实是Object的clone方法,而这个方法永远抛出一个CloneNotSupportedException:比如下面的代码是可以正常运行的:

public class Clone
{
  public static void main(String[] args)
  {
  Clone c = new Clone();
  try
  {
  c.clone();
  }
  catch (CloneNotSupportedException e)
  {
  e.printStackTrace();
  }
  }
}

如果Object的clone方法子类不能访问,那么c.clone()这句会编译失败。

Object类的这个clone方法完全是为了子类覆盖它服务的,并不是让子类直接调用的,这也就是为什么在覆盖clone方法时一般到调用super.clone()的原因。

clone方法是可以被覆盖的,但是必须实现Cloneable接口,所以你覆盖后,它就不会调用父类的方法,而调用你覆盖后的方法。