测试代码如下:
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();
}
}
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();
}
}
{
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();
}
}
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();
}
}
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呢?
这样一来,继承的作用值得我怀疑,如果继承的方法只能调用父类的数据成员或方法,那么是否只要继承的方法需要调用到类数据成员或类成员方法,就需要覆写该方法呢?这样,继承的作用好像被收窄了很多,甚至让我感到失望。