关于Java继承一个值得思考的问题。

        最近一段时间在写一个类树的时候,发现了一些关于继承的值得思考的问题,于是自己写了简单的测试代码进行分析,经过分析与跟csdn论坛朋友的探讨,弄清楚了java的一些继承的机制,但依然有所迷惑。

        测试代码如下:
public abstract class A {
  
int i=1;

  
public void printI() {
    System.
out.println("i="+i);
  }

}



public class B {
  
int i=2;
  
  
public static void main(String[] args) {
    B b
=new B();
    b.printI();
  }

}

上述代码,抽象类A有一个数据成员i,有一个提供了实现细目的方法pringI(),然后实体类B继承了A,拥有一个数据成员i。我的想法是,B继承了A,自然继承了方法pringI(),那么在调用b.printI()时候,应该打印出B中的数据成员变量i的值,但现实与我的想法不一致,b.printI()打印了A中的i的值,就是1。

一直想不明白,在csdn一个网友的帮助下,修改代码如下:
public B extends A {
  
{
    i
=2;
  }


  
public static void main(String[] args) {
    B b
=new B();
    b.printI();
  }

}


这次,程序如我的意图执行,打印出B中的数据成员i 。

于是我发现了如下问题,B继承了A,同时继承了A的方法printI(),但printI()方法执行的是:打印A的数据成员i,在第一段代码中,B重新定义了继承自A的数据成员i,并赋值2,而调用printI(),打印的依然是A中的i 。
第二段代码中,其实如果把i=2放入到main方法中,作用是一样的,就是,没有重新定义数据成员i,而是直接修改继承自A的数据成员i ,所以这个时候打印的i,能够变成2。

再次修改程序如下:
public abstract class A {
  
private i=1;
  
  
public void printI() {
    System.
out.println("i="+i);
  }

}


public class B extends A {
  
public static void main(String[] args) {
    B b
=new B();
    b.printI();
  }

}


这次编译收到错误:
C:\classes\a>javac B.java
B.java:3: i has private access in A
    i=2;
    ^
1 error

很明显,由于A中的数据成员被定义为private,那么B并不能继承A的i,于是出现上述错误。
但如果去掉i=2; ,程序照常执行,因为B调用了A中的方法printI(),而printI()属于A,所以能够调用A中的private数据成员i 。

再次修改程序如下:
public class B extends A {
  
  
public void printI() {
    System.
out.println("i="+i);
  }

  
  
public static void main(String[] args) {
    B b
=new B();
    b.getI();
  }

}


上面程序视图覆写A中的方法printI(),结果编译期收到与前一段程序相同的错误信息。

通过几次程序测试,已经可以确定,子类继承了父类的方法,如果没有覆写该方法,那么就相当与直接调用父类的方法。

但有一点依然让我迷惑,就是,如果在A中定义了 int i=1,同时B中再次定义int i=2,那么B中的i,应该像{ i=2; }一样,覆盖并修改了i ,但为什么第一段程序,打印出来依然是1呢?

这样一来,继承的作用值得我怀疑,如果继承的方法只能调用父类的数据成员或方法,那么是否只要继承的方法需要调用到类数据成员或类成员方法,就需要覆写该方法呢?这样,继承的作用好像被收窄了很多,甚至让我感到失望。
原文地址:https://www.cnblogs.com/johnny/p/35849.html