继承 - 试着理解它是如何工作的

时间:2013-11-12 19:18:36

标签: java inheritance

我有这两个班级:

public class A
{
    protected int _x;

    public A(){  
        _x = 1;  
    }
    public A(int x) {  
        _x = x;  
    }

    public void f(int x) {  
        _x += x;  
    }

    public String toString() {  
        return "" + _x;  
    }
}

public class B extends A
{
    public B() {  
        super(3);  
    }
    public B(int x) {
        super.f(x);
        f(x);
    }

    public void f(int x)
    {
        _x -= x;
        super.f(x);
    }
}

主:

public static void main(String [] args)
{
    A[] arr = new A[3];
    arr[0] = new B();
    arr[1] = new A();
    arr[2] = new B(5);

    for(int i=0; i<arr.length; i++)
    {
        arr[i].f(2);
        System.out.print(arr[i] + " ");
    }
}

我想了解为什么在第一次打印后,结果是3而不是1 在开始时调用Class A空构造函数,因此_x = 1f(int x) from class B所谓_x = _x - 2所以_x = -1以及通话后Super.f(x) _x = _x + x ==&gt; 1

2 个答案:

答案 0 :(得分:1)

arr数组中的第二个元素是A类型的对象,它使用无参数构造函数初始化

arr[1] = new A();
...
public A(){  
    _x = 1;  
}

您在该对象上调用f(2)。这将是 A#f(int) 方法(即f()类中的方法A

public void f(int x) {  
    _x += x;  
}

因此你加2比1,即。 3。


似乎你的意思是第一个元素。使用no arg B构造函数

初始化第一个元素
arr[0] = new B();
...
public B() {  
    super(3);  
}

调用A构造函数

public A(int x) {  
    _x = x;  
}

_x设为3。当您在此对象上调用f(2)时,由于多态性和后期绑定,它会调用f(int)中的B方法。

public void f(int x)
{
    _x -= x;
    super.f(x);
}

这将删除2到3,即。 1. super.f(x)会调用A的{​​{1}}版本,将{2}添加回f(int),即。 _x的最终结果是3。

答案 1 :(得分:0)

第一个元素是B的实例。调用默认构造函数,调用super(3);_x将等于3.循环的第一次迭代将为arr[0].f(2);,这将调用f中的B方法。这将使_x递减2,因此3-2 = 1。然后调用f的超级 - &gt; 1 + 2 = 3。