父类:
package inherit;public class Supper{
   protected f1(){
      system.out.println("protected f1() in Supper");
   }
}子类:
import inherit.Supper;public class Sub{
   public static void main(string[] args){
     Supper Sup=new Supper();
     Sup.f1();
   }
}发生错误:
Sub.java:11: f1() 可以在 inherit.Supper 中访问 protected
     Sup.f1();
        ^
1 错误子类为什么不能访问Supper的protected方法?

解决方案 »

  1.   

    Sub 并非 Supper 的子类,继承需要使用 extends 关键字。如:public class Sub extends Supper {
       ...
    }即便这样,下边的代码仍然是行不通的:     Supper Sup=new Supper();
         Sup.f1();以这种方式调用,f1 必须是 public 的。
      

  2.   

    extends Supper 是写漏了
    为什么不能调用
      

  3.   

    protected 只能供同一个包中的类和他的子类使用;
              但是子类和父类不在同一个包中 ;
              因此不能调用父类的protected方法 ;
              仔细想一下 protected的使用方法  要点不是在哪里创建  是protected方法的使用
      

  4.   

    protected f1(){
          system.out.println("protected f1() in Supper");
    }这是一个构造函数,即使换成public,也不能像你那样调用。
    改成
    protected void f1(){
          system.out.println("protected f1() in Supper");
    }
    应该就可以了。
      

  5.   

    wdman(天空) 没懂你说的意思,怎么是构造函数呢?
      

  6.   

    protected 只能供同一个包中的类和他的子类使用;
              但是子类和父类不在同一个包中 ;
              因此不能调用父类的protected方法 ;
              仔细想一下 protected的使用方法  要点不是在哪里创建  是protected方法的使用
    -----------------------------------------------------------------------------------
    没错,你只要将Sub和Supper放到同一个包下就可以了
      

  7.   

    lbdy(阿棒)
    public class Sub extends Supper {
       protected f1(){
          system.out.println("protected f1() in Supper");
       }
    }
    这样是编译通不过的,换成
    public class Sub extends Supper {
       protected void f1(){
          system.out.println("protected f1() in Supper");
       }
    }
    就可以了。构造函数一定没有返回值,非构造函数一定要有返回值。
    我不知道其他人回答问题的时候是不是亲自编程试过了。就象上面
    那位回答子和父在同一个包,这是java的package private的问题,
    和本问没有关系。
      

  8.   

    看糊涂了,为什么f1()是构造函数呢,难道可以和类不是一个名字?嗯,没有返回值也能编译通过比较强啊。另外 xiaoxujsj(萧萧) 说得对,我也是这么认为滴。
      

  9.   

    修改:
    protected void f1(){
          system.out.println("protected f1() in Supper");
    }我的程序是这样的,但是就是不能调用。这里也是我写漏的。
      

  10.   

    protected 只能供同一个包中的类和他的子类使用;
              但是子类和父类不在同一个包中 ;
              因此不能调用父类的protected方法 ;
              仔细想一下 protected的使用方法  要点不是在哪里创建  是protected方法的使用
    我不认为这样,java设置protected的目的就是让他的子类也可以访问它的父类,就算他们不是同一个包。如果非得放在同一个包,protected创造出来的意义就没有了java的本意。
      

  11.   

    因为程序错误太多了,让大家误解了我的原意,这是修改后的程序,希望大家给我答案。谢谢父类:
    package inherit;public class Supper{
       protected void f1(){
          system.out.println("protected f1() in Supper");
       }
    }子类:
    import inherit.Supper;public class Sub extends Supper{
       public static void main(string[] args){
         Supper Sup=new Supper();
         Sup.f1();
       }
    }发生错误:
    Sub.java:11: f1() 可以在 inherit.Supper 中访问 protected
         Sup.f1();
            ^
    1 错误子类为什么不能访问Supper的protected方法?protected权限是就算你不在同一个包,只要你是子类就可以访问的,为什么访问不 了?
      

  12.   

    只要是父类的protected方法,对子类来说,都是可以调用的,我认为都可以调用.
    就是说:子类可以拥有父类的(pubilc,protected)方法
    但是如果子类和父类是在同一个包里面,那么子类可以拥有父类的(public,protected,packaged)方法我这里所谓的packaged方法在父类是如下定义的:
    fun(){ //不加任何public,protected和private修饰
        ....
    }
      

  13.   

    package inherit;public class Supper {
        protected void f1() {
            System.out.println("protected f1() in Supper");
        }
    }//////////////////////////////////////////////import inherit.Supper;public class Subber extends Supper {
        public void method() {
            System.out.println("you can see f1()");
            f1();
        }    public static void main(String args[]) {
            Subber s = new Subber();
            s.method();
            // Sup.f1();
        }
    }---初学者
      

  14.   

    大家不要修改我的程序了,我知道那样那样可以运行, wlmmlw(如何讨好女孩子?) 你修改后的程序都不是父类的对象调用父类的protected方法,不是我原意。
    我想问大家的是,为什么我这样写,父类的对象(在子类创建的)就不能调用protected方法。而且是针对我的程序给出解答。我那个程序编译的错误以写出。
      

  15.   

    建议楼主多看看TIJ,protected是只在同一包中和子类中可见,仔细理解一下。
      

  16.   

    就是在研究这个TIJ,protected的定义就是子类并不需要在同一个包中
      

  17.   

    不知道你用什么IDE写的,如果是eclipse什么的应该提示你f1() is not visible啊。
    可能是你对protected理解有问题吧。
      

  18.   

    protected的定义就是子类并不需要在同一个包中
    -------------------------------------------对啊,我说的是在同一包中和子类中可见,子类不一定在同一包中,呵呵,估计楼主应该理解了同一包中的含义,protected的最主要还是让你的类中的属性和方法在你的子类中可见,也就是说你的子类中的任意方法都可以调用他们,不知楼主是否明白?
      

  19.   

    我认为的是,protected方法就是子类不跟父类同一个类,但是父类的方法(protected)还是对子类来说是可见的。要不然,当子类用super调用父类的protected方法时就可以调用。如果照你说的:protected的最主要还是让你的类中的属性和方法在你的子类中可见,那么子类不在同一个包应该用super也看不见protected才对。但是并不是这样。
      

  20.   

    修改:应该是protected方法就是子类不跟父类同一个包
      

  21.   

    我认为的是,protected方法就是子类不跟父类同一个包,但是父类的方法(protected)还是对子类来说是可见的。要不然,为什么当子类用super调用父类的protected方法时就可以调用。如果照你说的:protected的最主要还是让你的类中的属性和方法在你的子类中可见,那么子类不在同一个包应该用super也看不见protected才对。但事实并不是这样。
      

  22.   

    Supper Sup=new Supper();这个应该是属于组合而不是继承了吧,所以调用不了吧
    Sub sub = new Sub(); sub.f1();这样肯定是可以的,这样才是子类访问父类吧。我是这么认为的。
      

  23.   

    Sub sub = new Sub(); sub.f1();这个应该是子类访问子类,这里访问的f1是子类继承过来的,已经属于它了。这里有继承也有组合。因为我明显调用了extends继承了父类。然后我在子类创建一个父类对象,当然算是组合。
    但是这个不是我想讨论的。
      

  24.   

    子类继承父类,调用父类的方法用super.方法名。像你这里可以这样调用:super.f1();  。你自己写的那个调用是创建一个Supper类型的对象,这样不能调用它的protected方法。
      

  25.   

    但是你在父类中如果把f1()声明为默认的,在子类你就不能继承f1()了,这就是protected的作用把。
      

  26.   

    同意msnsnd(无声无隙) 的看法:所谓protected是指
    对一般用户而言,它是private 的,但是如果你想继承这个类,或者开发一个也属于这个package 的类的话,就可以访问它。所以,通过继承关系能够调用f1()方法,怎么通过继承关系调用?你只能用super.f1();或者
    Sub sub = new Sub();
    sub.f1();
    来使用f1()方法。这是继承的语义。但是像
    Supper s = new Supper();
    s.f1();
    这就是组合关系了,你可以把Sub类放在和Supper一个package中,或者将Supper类中的f1()方法定义为public,都是可以正确调用的。这个里面其实有一个界线。好好体会一下。
      

  27.   

    如果把f1()改称默认的,即使你继承了父类后声明子类一个对象,是不能调用子类.f1()的这样当然不能访问啦,因为权限设置为包了。但是我的类是继承来的,为什么就是不能访问父类的protected方法,非要用super不可,wangnewton(逍遥派掌门)要知道,其实super指向的就是一个父类的对象。我还是不能信服啊,但是谢谢你们给了那么多意见!
      

  28.   

    但是像
    Supper s = new Supper();
    s.f1();
    这就是组合关系了,其实说确切一点,这不是组合关系。如果这样都是组合,那么我们的面向对象的程序就都是组合来的。组合不是这样定义的,组合是对类中的类成员来说的。
      

  29.   

    如果这个f方法是static就可以使用父类的对象访问了,这个就不用super关键字。当然static一般用类来访问。不过这个很好的说明了,我的子类不是跟父类同一个包,但是应该可以访问父类的ptotected访问,但是当方法不是static时就错误了。
      

  30.   

    import inherit.Supper;public class Subber extends Supper {
        public void method() {
            System.out.println("you can see f1()");
            f1();
        }    public void method2(){
            Supper s = new Supper();
            super.f1();
            s.f1(); //error
        }
        public static void main(String args[]) {
            Subber s = new Subber();
            s.method();
            s.method2();
            
            super.f1(); //error       
        }
    }//不是protected还是public的问题吧.
    //在子类里建个父类的对象,然后用这个父类的对象就想访问protected方法
    //是不是一些概念搞混了---初学者
      

  31.   

    应该说明确切的原因啊,针对我的程序。我认为可以访问打protected,为什么不能访问。好多谢大家啊!!!!!
    真的。
    但是我还是不能明白编译器为什么不能通过编译。
    而且好像大家开始不是讨论我的问题了,不过都学到很多东西。
      

  32.   

    super.f1(); //error   这个错误不是我想讨论的问题。它错误,是因为super是一个Supper类的引用,指向的是类sub中的supper对象,这个对象是自动创建的,在子类里面。这在子类里面的对象不是static的,当然在非static方法里面就不可以使用啦。
      

  33.   

    我觉得问题还是在于protected的限制定义中关于继承的理解问题,你在子类中声明了一个父类对象,不在同一个包中自然不能访问那个方法了,protected中只能供同一个包中的类和他的子类使用,是它的子类可以使用而不是在他的子类中就可以使用。呵呵。
      

  34.   

    父类:
    package inherit;public class Supper{
       protected f1(){
          system.out.println("protected f1() in Supper");
       }
    }子类:
    import inherit.Supper;public class Sub{
       public static void main(string[] args){
         Supper Sup=new Supper();
         Sup.f1();
       }
    }发生错误:
    Sub.java:11: f1() 可以在 inherit.Supper 中访问 protected
         Sup.f1();
            ^
    1 错误子类为什么不能访问Supper的protected方法?//好长的贴子.
    //---子类为什么不能访问Supper的protected方法?
    //你的这句话是什么意思?
    //你的子类是指子类的定义吧.
    //子类能访问基类的protected,这是地球人都知道的.
    //但你这里是用对象Sup
    //编译程序可不管你在子类方法里用的对象到底是哪家的.
    //如果还不明白,继续讨论(如果你觉得有必要的话)---初学者
      

  35.   

    protected中只能供同一个包中的类和他的子类使用这里不是这样吧,应该是“或”的关系TIJ中对protected的定义是这样写:
    It says “This is private as far as the class user is concerned, but available to anyone who inherits from this class or anyone else in the same package.”
    是“or”关系的
      

  36.   

    因此我是子类,虽然我不是同你一个包,但是我有权限访问protected
      

  37.   

    搞了半天是个语言文字游戏。
    子类访问父类的protected类型method,field,是指通过继承的方式来访问,其他的访问方式,都是非法访问方式。在同一个Package里子类能通过父类的实例访问父类的protected方法,并不是因为这个方法是protected,而是因为protected方法在同一个package里具有package性,其他类都可以像public方法一样访问,与是不是继承没有关系。
      

  38.   

    嗯,同意wdman,其实就是一个文字游戏,你把情况都测试一遍就明白了。哈哈
      

  39.   

    但是为什么protected static 方法不用继承方式来访问?
      

  40.   

    To:wdman(天空)
    老大,亏你还5个三角,是不是看错了?别误人子弟啊,f1()怎么能是构造函数啊,构造函数要和类名相同
      

  41.   

    protected f1(){
    system.out.println("protected f1() in Supper");
    }这是一个构造函数,即使换成public,也不能像你那样调用。
    改成
    protected void f1(){
    system.out.println("protected f1() in Supper");
    }
    应该就可以了。
    -----------------------------
    大放屁。
      

  42.   

    lbdy(阿棒)
    public class Sub extends Supper {
    protected f1(){
    system.out.println("protected f1() in Supper");
    }
    }
    这样是编译通不过的,换成
    public class Sub extends Supper {
    protected void f1(){
    system.out.println("protected f1() in Supper");
    }
    }
    就可以了。构造函数一定没有返回值,非构造函数一定要有返回值。
    我不知道其他人回答问题的时候是不是亲自编程试过了。就象上面
    那位回答子和父在同一个包,这是java的package private的问题,
    和本问没有关系。
    ---------------
    再次大放屁。
      

  43.   

    楼主你写的什么东西。
    package inherit;public class Supper{
    protected f1(){
    system.out.println("protected f1() in Supper");
    }
    }
    这能compile吗?
      

  44.   

    看了半天,感觉楼主概念基本上搞得挺清楚的,不过这里的问题准确的说应该是多态的问题protected所指明的子类可以访问父类的方法应该是指子类自己来访问父类的方法明白这个道理后,问题就出在实例化对象上,Supper Sup=new Supper();创建的是一个父类的对象。在面向对象中,子类一定是一个父类,但是父类并不知道自己被哪些类继承,也就是说父类不是子类(这点很重要),楼主的程序是在子类里面创建父类对象来访问父类的方法f1(),并不是通过子类自己来访问f1()到这里问题就出来了,这个时候有人就说这是组合,如果是组合的话加不加extends对于创建Sup都是一样的,不过且慢,如果把f1()加上static呢,试一试就知道了,Sub类中加上extends的话可以通过Sup对象访问f1(),如果不加extends的话就不能通过Sup对象来访问f1()了,可见这还是继承关系,不是组合关系,是继承中多态的表现
      

  45.   

    因为不是在同一个包内,也不是在子类的类方法里。
    所以无法调用。
    看了上面的讨论,我只能发笑。子类:
    import inherit.Supper;
    public class Sub{
        public void f2(){
            super.f1();//此处的super是关键字,不是你的类名。注意。
                       //在子类的类方法内,可以访问父类的protected方法
        }}
      

  46.   

    public static void main(string[] args)main函数是不在继承的讨论范围内的
      

  47.   

    当父子类不在同一个包中时,new一个父类对象时调用protect方法f1()不行,但如果用super.f1()就可以!
      

  48.   

    回复人: xiamihgy(毛虫) ( ) 信誉:100  2005-10-08 09:44:00  得分: 0  
      
    public static void main(string[] args)main函数是不在继承的讨论范围内的--------------------------------------------------这个是对的
      

  49.   

    你要讨论的问题是“子类竟然不能创建父类对象调用父类的protected方法”
    实际上是可以的,实际你的错误应该与你的包有关系,我把你的包去掉后就可以了!
    父类:
    public class Supper{
       protected void f1(){
          System.out.println("protected f1() in Supper");
       }
    }
    子类:public class Sub extends Supper{
       public static void main(String[] args){
         Supper Sup=new Supper();
         Sup.f1();
       }
    }
    运行通过:
    protected f1() in Supper
    还有请你在编写的时候注意大小写!
      

  50.   

    static 方法中只能访问static的方法
      

  51.   

    回复人:kof811118(郁闷的老黄) ( 一级(初级)) 信誉:100  2005-10-08 11:59:00  得分:0

    你要讨论的问题是“子类竟然不能创建父类对象调用父类的protected方法”
    实际上是可以的,实际你的错误应该与你的包有关系,我把你的包去掉后就可以了!
    父类:
    public class Supper{
    protected void f1(){
    System.out.println("protected f1() in Supper");
    }
    }
    子类:public class Sub extends Supper{
    public static void main(String[] args){
    Supper Sup=new Supper();
    Sup.f1();
    }
    }
    运行通过:
    protected f1() in Supper
    还有请你在编写的时候注意大小写!-------------------------------------------------------
    你是把子类和父类都放一个包中了吧?那样的话即使Sub类没有继承Super类,都可以
    用Super的对象访问protected的成员函数。换句话说,你这个是protected对同个包的
    可访问性。
    其实我觉得上面tlowl(风流才子) ( 三级(初级)) 信誉:100  2005-10-07 21:00:00  得分:0
    的贴是把问题说的最清楚明白的
      

  52.   

    比较同意 qq911110() 的观点试试这样:
    public static void f(){ f1();  } //define in class Sub;你能编译过去吗?
      

  53.   

    其实static方法内也可以调用非静态方法的,是通过对象的引用来实现的,这是TIJ里的注释。
      

  54.   

    更正昨天说的一个错误,该程序中并没有用到多态,在子类中直接声明的是父类的对象而不是将子类对象向上转型至父类对象,即Supper Sup=new Supper();而不是Supper Sup=new Sub();虽然这两种声明对象方法对于访问子类中没有覆写父类的方法的调用结果是一样的今天上课问了问老师,static方法是与对象无关的,通过类即可直接访问,不用创建对象,也就是说在继承中如果子类没有覆盖父类的静态方法那么子类直接指向父类的静态方法,也就是说直接调用即可,像这样:
    public static void main(String[] args){
      //Supper Sup=new Sub();
      //Sup.f1();
      f1();//直接指向Supper中的f1()
    }
    把声明父类对象注释掉,一样可以编译运行,这样就不会造成混淆了
      

  55.   

    我还是想坚持讨论,我在学校依然在想这个问题,但是还是不能给出一个令自己满意的回答,所以就来这里请教大家的。希望后来的人不要看第一程序,那个是错误,这里是我新的通过测试后的程序:父类:
    package inherit;public class Supper{  protected void f1(){   ///非static只是protected方法
       System.out.println("protected supper.f1()");
      }  protected static void f2(){////既是static又是protected方法
       System.out.println("protected static suppe.f2()");
      }  
    }子类:
    import inherit.Supper;class Sub extends Supper{
      
      protected static void f2(){////覆盖Supper的f2()方法
       System.out.println("protected static Sub.f2()");
      }  public static void f3(){
    System.out.println("f3() method in Sub");
    Supper a=new Supper();  
    a.f1();                 ///ERROR
    }

    public static void main(String[] args){
    Supper b =new Supper();
    b.f1();                 ///ERROR
    Supper c =new Supper();
    c.f2();                 ///But no ERROR
    }
    }编译错误如下:Sub.java:14: f1() 可以在 inherit.Supper 中访问 protected
    a.f1();                 ///ERROR
                     ^
    Sub.java:19: f1() 可以在 inherit.Supper 中访问 protected
    b.f1();                 ///ERROR
                     ^
    2 错误    这些错误就是我想讨论的东西:子类为什么不能通过创建父类的对象调用protected方法。不用super这关键字。
        我认为:就像package权限一样,同一个包的类可以通过在另一个类(这两个类是同一个包的)中创建的对象调用package方法,protected的方法应该也可以通过在子类中创建父类的对象调用,但是编译器就告诉我:你不能这样!!
        我就是想知道为什么这样的!这样让我觉得编译器违反了protected的定义:“This is private as far as the class user is concerned, but available to anyone who inherits from this class or anyone else in the same package.”
      

  56.   

    还有那static他不属于某个对象,而是类方法,在你类被加载的时候自动就调用了,并不用产生任何对象所以你产生不产生哪个父类的对象c都一样你可以试着用你的类名inherit.Supper.f2();来调用答案都是正确的,刚学JAVA如果回答错了别骂人就成...
      

  57.   

    Java的访问限定词,例如protected是作用在类之上的,而不是对象上的。
      

  58.   

    还有就是  protected static void f2(){////覆盖Supper的f2()方法
       System.out.println("protected static Sub.f2()");
      } 这并没有覆盖因为你父类的F2是STATIC的你这个只能说又重写了一个F2
    类中所有的PRIVATE和STATIC方法都是FINAL的不能被覆盖,就算编译过了其实你运行看看就明白了
      

  59.   

    父类:
    package test.test.aaa;public class Super
    {
       protected void f1(){
          System.out.println("protected f1() in Supper");
       }
    }子类:
    package test.test.aaa;public class Sub extends Super{
       public static void main(String[] args){
         Super Sup=new Super();
         Sup.f1();
       }
    }没有问题!
      

  60.   

    zisidemao(zisidemao) 你是哪里得到的这句话?
      

  61.   

    子类的方法只能够访问子类对象的受保护字段或方法,也就是你继承过来的,而不能访问其他父类对象的这个字段或方法,也就是你下面创建了一个父类实例然后用父类实例去调这个方法.如果这句话是官方的,或者是专家的,我都信服了,因为我都一直这样给自己解析这个问题,只有这样解析才可以说明。
    但是这样有违protected的初衷……我认为。
      

  62.   

    楼主你好,那句话的确是官方的。
    这个问题我原来也理解错了,现在我引用一段java2学习指南上的原话,
    以方便楼主和各位理解。
    我现在想想可能还真没有多少人能完全真正的理解过protected这个关键字。
    我先引用如下,大家可以再讨论。
    ------------------------------------------------------------------------
    包外子类有权访问父类成员是什么意思?它指子类继承该成员。
    然面,这不意味着包外子类能够使用父类实例的引用访问该成员。
    换句话说,保护=继承。
    保护不是指子类能够处理受保护的父类成员,就好像它是公有的那样。
    因此,如果包外子类获得父类引用,该子类不能在父类引用上使用点运算符来
    访问受保护的成员。
    子类只能通过继承看到受保护的成员。
      

  63.   

    这句话是在JAVA核心技术卷1里找到的,希望可以对你有点帮助