如何java转换工作,是改变Object的状态还是创建新的Object?

时间:2013-09-13 02:43:42

标签: java

我有一个方法dummyA作为类参数,但我需要将子类B的实例传递给该方法。我知道: Does Java casting introduce overhead? Why? java中的向下转换有开销。我的大多数代码都处理子类B所以我不会为此目的使用向下转换。相反,我使用临时实例变量cc来实现此目的。但这不是对子类m的对象进行更改。我需要对变量cc进行更改,例如变量m。这是我的代码:

public class TestCast {

    public TestCast() {
        B m = new B(12, 3);
        dummy(m);
        A cc = m;
        dummy(cc);
        System.out.println(m.a);
        System.out.println(cc.a);
    }

    public void dummy(A t) {
        t.a = 22222;
    }

    public static void main(String[] args) {
        new TestCast();
    }
}

class A {
    public int a = 0;

    public A(int a) {
        this.a = a;
    }
}

class B extends A {

    public int a;
    public int b;

    public B(int a, int b) {
        super(a);
        this.a = a;
        this.b = b;
    }
}

带输出

12
22222

4 个答案:

答案 0 :(得分:3)

在您的特定示例中,父类和子类都声明了名为a的字段。在这种情况下,子变量隐藏父变量。

此外,变量/字段不是类似方法的多态实体。它们可以通过引用的静态类型访问。

换句话说,字段访问

A var = new A(10);
var.a; // returns 10

和现场访问

A var = new B(1501, 10); 
var.a; // also returns 10

A var = new B(1501, 10); 
var.a; // returns 10
((B)var).a; // returns 1501

因为您在具有静态类型a的引用上访问B

在你的方法中

public void dummy(A t) {
    t.a = 22222;
}

t的静态类型为A,因此您将修改父类变量的值。

答案 1 :(得分:1)

Casting告诉编译器引用变量在运行时具有特定的Type

答案 2 :(得分:1)

因为B正在扩展A,所以您不想重新定义变量a

在回答您的评论时,您的代码应该是:

class B extends A {

   public int b;

   public B(int a, int b) {
    super(a);
    this.b = b;
   }
}

答案 3 :(得分:0)

IMO,你的示例代码并不是完美的继承实现。继承使您可以重用代码。换句话说,您无需在课程int a中再次声明B

  

我需要更改变量cc avaliable,例如变量m:

但是,如果您想要更改变量cc,请在a, bA中将变量B声明为私有/受保护。并在这两个类中提供setter和getter。 在课程B中拨打super.setA(a),如下所示。

class B extends A {

    private int a;
    private int b;

    public B(int a, int b) {
        super(a);
        this.a = a;
        this.b = b;
    }

    public setA(int a) {
        super.setA(a);
        this.a = a;
    }
}