class Supclass {
protected String className = "父类属性"; public void print() {
System.out.println("thisis父类print()方法" + "——此时对象" + this.toString());
}
}// 子类:
public class fulei_zilei extends Supclass {
protected String className = "子类属性"; public void print() {
System.out.println("thisis子类print()方法" + "——此时对象" + this.toString());
} public static void main(String[] args) {
Supclass sup = new fulei_zilei();
System.out.println("此时的属性时:" + sup.className);

}
}
结果却是:此时的属性时:父类属性
这是为什么呢?按我的理解,子类把父类的属性也给重写了,但现在为什么会出现这种状况呢?
请各位高手指教

解决方案 »

  1.   

    这是Java多态的一种形式,关键在这句表达式 Supclass sup = new fulei_zilei()
    虽然貌似new 了一个子类的,可是sup却是父类的一个实例,所以,用它调用的方法只能调用父类里的那个方法,
    我记得除非父类里没有这样一个方法,那么它就调用子类里的方法,好像是这样的,如果我没记错的话,
    楼主可以试试.
    还有楼主如果想重写一个方法,最好在方法前一行加上 @Override
      

  2.   

    Supclass sup = new fulei_zilei();这里sup是个父类,new fulei_zilei()实例后自然是将Supclass的属性实例了,所以sup.className是父类的属性
      

  3.   

    class Supclass { 
    protected String className = "父类属性"; public void print() { 
    System.out.println("thisis父类print()方法" + "——此时对象" + this.toString()); 

    } // 子类: 
    public class fulei_zilei extends Supclass { 
    protected String className = "子类属性"; public void print() { 
    System.out.println("thisis子类print()方法" + "——此时对象" + this.toString()); 
    } public static void main(String[] args) { 
    fulei_zilei sub = new fulei_zilei(); 
    System.out.println(sub); 
    System.out.println("此时的属性时:" + sub.className); 
    Supclass sup = sub;
    System.out.println(sup); 
    class Supclass { 
    protected String className = "父类属性"; public void print() { 
    System.out.println("thisis父类print()方法" + "——此时对象" + this.toString()); 

    } // 子类: 
    public class fulei_zilei extends Supclass { 
    protected String className = "子类属性"; public void print() { 
    System.out.println("thisis子类print()方法" + "——此时对象" + this.toString()); 
    } public static void main(String[] args) { 
    fulei_zilei sub = new fulei_zilei(); 
    System.out.println(sub); 
    System.out.println("此时的属性时:" + sub.className); 
    Supclass sup = sub;
    System.out.println(sup); 
    System.out.println("sup属性时:" + sup.className); System.out.println("sub属性时:" + sub.className); 


    System.out.println("sup属性时:" + ((fulei_zilei)sup).className); System.out.println("sub属性时:" + sub.className); 


    你运行一下看看结果,好像覆盖是在转换的时候进行的
      

  4.   

    不存在属性覆盖,即使他们名字一样class Supclass { 
    protected String className = "父类属性"; public void print() { 
    System.out.println("thisis父类print()方法" + "——此时对象" + this.toString()); 

    } // 子类: 
    public class fulei_zilei extends Supclass { 
    protected String className = "子类属性"; public void print() { 
    System.out.println("此时父类的" +super.className); 
    } public static void main(String[] args) { 
    fulei_zilei sub = new fulei_zilei(); 
    System.out.println(sub); 
    System.out.println("此时的属性时:" + sub.className); 
    sub.print();///可以看出不存在字段的覆盖,即使重名也是两个不相干的字段
    Supclass sup = sub;
    System.out.println(sup); 
    System.out.println("sup属性时:" + ((fulei_zilei)sup).className); System.out.println("sub属性时:" + sub.className); 

      

  5.   

    楼上的测试已经说明问题了,,简单来说几点是:
    1.访问成员变量时,父类引用只可以由父类所定义的成员变量,而父类不知道子类中的成员变量如何定义;
    2.访问方法,父类引用可以通过自身方法来访问子类的重写方法,如果子类中有的方法,如父类没有,则父类引用。
    其实这样是有好处的,可以现实动态方法调度:比如说有三个类A(父类)、B(继承A)、C(继承A);父类A有一个call()方法,B、C都分别实现了call()方法重写,那么声明一个父类引用就可以分别动态调用B、C中的call()方法:A a = new A();
    B b = new B();
    C c = new C();
    A r;   //声明一个父类引用r
    r = a;
    r.call(); // 指向a则调用父类A的方法
    r = b;
    r.call();  //指向b则调用子类B的方法
    r = c; 
    r.call();  //指向c则调用子类C的方法
      

  6.   

    打漏了几个字:
    楼上的测试已经说明问题了,,简单来说几点是: 
    1.访问成员变量时,父类引用只可以访问由父类所定义的成员变量,而父类不知道子类中的成员变量如何定义,无法访问; 
    2.访问方法,父类引用可以通过自身方法来访问子类的重写方法,如果子类中有的方法,如父类没有,则父类引用无法访问子类的方法。 
    其实这样是有好处的,可以现实动态方法调度:比如说有三个类A(父类)、B(继承A)、C(继承A);父类A有一个call()方法,B、C都分别实现了call()方法重写,那么声明一个父类引用就可以分别动态调用B、C中的call()方法: A a = new A();
    B b = new B();
    C c = new C();
    A r;   //声明一个父类引用r
    r = a;
    r.call(); // 指向a则调用父类A的方法
    r = b;
    r.call();  //指向b则调用子类B的方法
    r = c; 
    r.call();  //指向c则调用子类C的方法
      

  7.   

    成员属性是不重写的
    class Supclass { 
    protected static String className = "父类属性"; 
    public void show(){
    System.out.println(this.className);
    }
    } // 子类: 
    public class FS extends Supclass { 
    protected static String className = "子类属性"; 
    public void show(){
    System.out.println(super.className);
    } public static void main(String[] args) { 
    Supclass fs = new FS(); 
    FS fsi=new FS();
    fs.show();

      

  8.   

    补充一下,
    父类的className和子类的className在这里相当于在两个不同的命名空间中。
    就像在两个package中,有两个同样名字的类,只要指定要使用 哪 个包中的类就不会冲突,也不会出现替代