我有两个JAVA源文件,一个是Base,它的代码如下:
package a;
public class Base{
protected String str="cc";
public void make(){}
}还有一个是Sub,它的代码如下:
package b;
import a.*;
public class Sub extends Base{
public void make(){
str="abc";
}
public void use(Sub s){
System.out.println(s.str);
}
public void use(Base b){
System.out.println(b.str); //编译出错
}
}
请问下各位,为什么Sub类中的System.out.println(b.str);会出现编译出错?我只知道这个和protected的使用有关,而且如果我将Base类中的str字段改成静态的(即protected static String str="cc";),它就可以通过编译了,这是为什么呢?

解决方案 »

  1.   

    protected,不同的package访问不到,你的问题不涉及到继承的问题还有,别搞标题党了
      

  2.   


    class Sub extends Base{
        public void use(){
            System.out.println(str);
        }
    }class Sub extends Base{
        public void use(Base b){
            System.out.println(b.str);
        }
    }
    不要搞混了
      

  3.   

    首先,protected对于子类来说父类中的变量是可以访问的,你所写的两个use()方法是子类中的方法重载(参数不同),最后你所写的这个代码是没有错的,可以正常编译运行。结果都是cc
      

  4.   

    protected的子类是得不到的,把protected去掉或改成public
      

  5.   

    对于静态的东西,JVM在加载类时,就在內存中开辟了这些静态的空间。引用static的方法和变量,不需要和实例捆绑在一起。
      

  6.   

    你们都把protected的用法想的太简单了,如果都这么简单,那我还出高分提问做什么呢?是吧。
    我已经说过这是一个JAVA SE基础但又不是平凡的问题了。
      

  7.   

    这个确实和一般的书上说的有点冲突。看来,尽信书,不如无书,此话不假。估计可以这样理解:protected让子类使用父类定义的变量,但又希望变量封装起来。就是说 父类这样定义protected Object variable; 子类中this.variable这样访问是合法的,obj.variable是不合法的。这个机制体现了面向对象的封装特性。加上了static,这个东西就是对象的一部分了,和上面的不冲突。
      

  8.   

    lz可能问的是关于static的问题。到baidu上搜就可以。
      

  9.   

    哈哈!!告诉你一个protected顺口溜:同胞友好互助,
    同根也须继承。JAVA 官方不推荐使用protected ,因为只要继承一个类就可以拥有一个类的内部属性访问权,这对于熟知二进制文件结构或是.class的的黑客来说,只要将自己的文件(.class)上传到指定地点就可以对系统内部肆意破换或是获取信息。
      

  10.   

    通过这个问题我发现原来同一包下
    其他类可以访问某一类的protected属性,这一点有点出乎我的意料
    public class MyTest {
    public static void main(String[] args){
    Base base=new Base();
    System.out.println(base.str);
    }
    }class Base{
        protected String str="cc";
        public void make(){}
    }
      

  11.   


     public void use(Base b){
            System.out.println(b.str);        //编译出错
        }--------------》》》》》 public void use(){
            System.out.println(str);        
        }
      

  12.   

    protected str,这个属性访问不到的!又不是同一个包中!
      

  13.   

    首先LZ这个编译错误跟继承的确没有关系
    因为你参数中的【Base b】就相当于【Base b = new Base()】
    根本就没有涉及到继承,解释只有一个,protected不能挎包访问。对于protected这个属性很多人有误解,其实是这样的:
    package a;public class Base {    public String str1 = "1";    protected String str2 = "2";    private String str3 = "3";
    }package b;import a.Base;public class Sub extends Base {    public void test() {        Base b = new Base();        System.out.println(b.str1);// 可以挎包访问public的属性[通过对象点的形式]
            System.out.println(b.str2);// 不可以挎包访问protected的属性[通过对象点的形式]
            System.out.println(b.str3);// 不可以挎包访问private的属性[通过对象点的形式]        System.out.println(str1);// 可以挎包访问public的属性[通过继承的形式]
            System.out.println(str2);// 可以挎包访问protected的属性[通过继承的形式]
            System.out.println(str3);// 不可以挎包访问private的属性[通过继承的形式]
        }
    }
      

  14.   

    System.out.println(b.str2);// 不可以挎包访问protected的属性[通过对象点的形式]
    System.out.println(str2);// 可以挎包访问protected的属性[通过继承的形式]这两句是重点,别搞混了、、、
      

  15.   

    不是package的问题,大家看看这个连接
    http://www.diybl.com/course/3_program/java/javaxl/2008104/147426.html
      

  16.   

    如果你要跨包访问protected成员变量的话,可以这样做:package b;
    import a.*;
    public class Sub extends Base{
        public void make(){
            str="abc";
        }
        public void use(Sub s){
            System.out.println(s.str);
        }
        public void use(Base b){
            System.out.println(super.str);
        }
    }
      

  17.   

    你把BASE 里的str改成public不就得了 
      

  18.   


    使一个类成员成为protected意味着它可以被扩展这个类的类所访问,但是这句话并不一定准确。更准确地讲,一个受保护的成员除了可以被类自身以及与其在同一个包中的代码访问之外,它还可以在一个类中通过对象引用来访问,这些对象引用的类型要与受保护成员所在类的类型是相同的或是其子类型的。这段你能看的懂吗?
      

  19.   

    这是我在JAVA之父写的书上找到的。这也是JLS规范中的内容。
      

  20.   

    我引用错了,我是在和“KAKUKYOWU”说
      

  21.   

    楼主是 炫耀 还是 咱的?????????
    很少用protected的路过,除里面试的时候。
      

  22.   

    我刚刚翻了一下《Java程序设计语言》,发现答案就在同一段话里面,“这些对象引用的类型要与受保护成员所在类的类型是相同的或是其子类型的。”也就说public void use(Reference b);Reference只能是Sub类或者Sub的子类,但是Base不是Sub类型,只能说Sub是Base类型
      

  23.   

    protected子类可以访问父类的东西 但是必须在同一个包里面
      

  24.   


    ==》我猜这是你自己翻译的吧?你好好看看是不是翻译的有问题。尤其是最后一句,根本就不对对于protected的访问权限问题,可以分为两大类:1)同包  2)不同包1)同包:本类可以直接使用 
             其它类可以创建对象来引用(对象点的方式)2)不同包:只有其子类才可以引用,而且是以继承的特性来引用(相当于自身的属性)
               而不是通过创建父类对象的方式来引用(不能用父类对象点的方式)就这些