//B.java
import pa.*;
class B extends A{
public static void main(String args[]){
A a = new A();

a.i = 2;
a.print();
a.StPrint();

(new A()).StPrint();
}
}//A.java
package pa;
public class A{
protected int i = 1;
protected void print(){
System.out.println("print");
}
protected static void StPrint(){
System.out.println("StPrint");
}
}
B和A不在同一个包中,B继承A,为什么B可以访问A的StPrint方法,不能访问A的print方法。

解决方案 »

  1.   

    你应该这么访问
    public static void main(String args[]){ 
    B b = new B(); b.i = 2; 
    b.print(); 
    b.StPrint(); } 
      

  2.   

    static void StPrint()静态方法,不要实例化class A
      

  3.   

    为什么同为protected,a.print()不能访问,a.StPrint()可以访问。static要怎么去理解?我只知道static方法可以直接来访问。但是实例化了后,有什么不同呢?
      

  4.   

    public static void main(String args[]) {
    A a = new A();
    a.i = 2; //  i 是 A 的 protected field, 不在同一个package内无法访问
    a.print();//  print 是 A 的 protected method, 不在同一个package内无法访问 a.StPrint(); // 因为StPrint 是static Method , static method 调用
                                     // 不需要通过对象的实例,跟写成 A.StPrint() 是一样的效果
                                     // 也就是说在B的main函数里面调用了父类的一个 protect method,         (new A()).StPrint(); //同上 B b = new B();
    b.i = 2; // 是 B 的field 所以能访问
    b.print(); // B继承的方法,可以访问
    b.StPrint(); // B 继承的方法,可以访问
    }
            这里面要注意的就是: a.i, a.print() 的a是A的实例,
             而 a.StPrint()方法貌似跟a.print()类似,实际上确跟A.stPrint()等价,
             而它的protected属性表明了它可以被子类直接调用。
      

  5.   

    为了避免混绕, 建议避免将静态函数写成a.stprint(), 如果你使用Eclipse,你会发现会有一个警告:
    The static method stprint() from type A should be accesed in a static way
      

  6.   

    可以理解成StPrint属于Class A而不是对象a
      

  7.   

    好的,谢谢各位。
    我就把a.StPrint()理解为super.StPrint()。因为是protected,所以可以被不同包内的子类中访问。对了,我在A中加
    protected A(){}
    在B中加
    B(){}
    结果编译报错,说A()必须为public。这个又要怎么理解呢?构造函数和普通方法的protected不同?
      

  8.   

    你是在B中实例化了B的对象,还是实例化了A的对象?
    感觉实例化了B的对象应该没问题吧
      

  9.   

    艺海拾贝
    好的,谢谢各位。 
    我就把a.StPrint()理解为super.StPrint()。因为是protected,所以可以被不同包内的子类中访问。 对了,我在A中加 
    protected A(){ } 
    在B中加 
    B(){ } 
    结果编译报错,说A()必须为public。这个又要怎么理解呢?构造函数和普通方法的protected不同?
    ------------------------------------
    因为你没有在B构造函数写明要调用A的构造函数,而A有无法调用默认的构造的函数,因为你已经声明为protected(只能被包外子类访问,它是不会自动调用protected A()的)的了。在B构造函数中加个super()来调用A的构造这应该不会错了。
      

  10.   

    To barech,
    我是在B中实例化A。
    To jaylongli,
    编译报错:
    B.java:7: A() has protected access in pa.A
                    A a = new A();
                          ^
    1 error它能找到protected A(),只是由于不是public,所以不能访问。你说的super()我试了,一样的报错。
      

  11.   

    子类是不能继承父类构造方法的,当实例化子类的时候,而子类又确实要用到父类的构造方法时,才需要在子类的构造方法当中加入super()在这里我没有看到实例化B的一个代码,B的构造方法没有调用,跟super()没有关系的
      

  12.   

    我觉得还是那句话,子类是不能继承父类构造方法的所以你在B当中实例化A的时候,肯定要将A的构造方法声明为public的了,现在是protected说明符,在不同包内是无法访问的构造方法跟普通方法,变量是不一样的,继承的时候也是如此
      

  13.   

    子类为什么不能继承父类的构造方法?
    我的想法如下:
    1. 从A本身来说, public A(){}, protectedA(){}, private A(){} 都没有任何问题
        所不同的是 new A() ;这个方法的调用范围不一样而已。
    2. B extends A . 那么 B(){}; 等价于B(){super());
       也就是说,B的构造方法首先得调用父类的某一个构造函数,然后才能干点其它的什么,
       所以,当A(){}声明为public或者protected的时候没有任何问题,
       只有当A(){} 声明为private的时候会报错,因为此时,B不能调用任何A的构造函数
      

  14.   

    子类的构造方法一定要用“super”调用一次父类的构造函数,否则报错!对于继承后的子类,如果要重新定义父类的非private方法,必须使用override关键词。
      

  15.   

    子类不是不能继承父类构造方法,反过来子类构造函数必须在第一行调用父类的某一个构造函数(super()可以省略,但是实际上是内含在第一行的)
      

  16.   

    不在子类构造方法中调用super,你调用个父类的构造方法试试看
      

  17.   

    super要写在第一行这个确实,但可以省略我还是第一次听,至少我忘记写super的时候,编译不会通过
      

  18.   

    当然可以省略了
    不能省略的情况是这样的,父类没有可见的无参数的构造函数
    只要父类有类似public A(){...} 或者protected A(){...}
    super()就可以省略
      

  19.   

    刚我查了下,是可以省略,但平时我不爱省但只是利用super调用了默认的父类构造方法,并不是继承所以我说编译器报错的问题,跟super应该没什么关系
      

  20.   

    正是因为有super调用了父类不带参数的构造函数,所以才会发生编译器报错,因为不是继承而来的,而是用super调用的,protected说明符的方法不能被不同包的类所访问
      

  21.   

    看来楼上还有点误解, 即使不在同一个包,子类还是可以调用父类 protected 的函数,包括构造函数和普通函数.
    继承不是说继承了某一个函数,而是继承了某一个类。在此基础上,不论是否在同一个包里,任何public和protected函数都可以被子类调用的。
      

  22.   

    首先楼主要搞清一个概念:
    修饰符:protected  类属变量及方法,包内的任何类,及包外的那些继承了此类的子类才能访问;
    要搞清这个概念啊,楼主.