这段Java是什么意思?

时间:2015-06-16 07:40:44

标签: java

我不知道这种传递对象作为参数的方式是什么。所以我不知道在网站上搜索什么。如果以前曾经问过我,我很抱歉,我确信它已经有了。

有人可以告诉我这两种传递对象作为参数的方式之间的区别是什么?为什么我不能以第一种方式覆盖属性和方法?

myObject.doSomethingWithOtherObject((new OtherObject() {
  // why can't I override properties here?
  public String toString () {
    return "I am the other object.";
  }
  ...
}));
myOtherObject = new OtherObject();
myObject.doSomethingWithOtherObject(myOtherObject);

然后我有第二个问题,但也许回答第一个问题也会回答这个问题。 为什么这不起作用:

public class OtherObject {
    public OtherObject (String str) {
        super();
    }
}

myObject.doSomethingWithOtherObject((new OtherObject("string arg") {
  public void overrideSomething () {

  }
}));

字符串"字符串arg"没有像我期望的那样传递给构造函数。而是抱怨没有找到构造函数OtherObject()。 为什么Java不能识别我试图向构造函数发送参数?

感谢阅读!

5 个答案:

答案 0 :(得分:3)

当你执行new OtherObject然后打开大括号{ ...时,您正在创建一个新的(匿名)类。不是已定义的OtherObject类的新Object。看看Java的匿名类,以便更好地理解

答案 1 :(得分:1)

第一个称为匿名类。这意味着您实际上实例化了一个没有名称的子类,以覆盖某些内容。

在第二个中,编译器抱怨你没有构造函数。正如您在第一个问题的答案中所描述的那样,您实际上是在这里进行子类化,这意味着如果需要,您必须定义一个构造函数。

答案 2 :(得分:1)

您的代码:

myObject.doSomethingWithOtherObject((new OtherObject() {
  // why can't I override properties here?
  public String toString () {
    return "I am the other object.";
  }
...
}));

大致相当于:

class OtherSubObject extends OtherObject {
  public String toString () {
    return "I am the other object.";
  }
}

...
myObject.doSomethingWithOtherObject(new OtherSubObject());

除了没有名称(即匿名)创建了OtherObject的子类,因此无法在其他任何地方引用。

您的代码:

myOtherObject = new OtherObject();
myObject.doSomethingWithOtherObject(myOtherObject);

不会创建新类,只是将OtherObject的实例作为参数传递。

答案 3 :(得分:1)

首先,我想确认我之前的发言者所说的话:

当您在对象初始化中添加花括号时,您将创建一个类的匿名子类型,您可以像在示例中那样覆盖方法。

但是现在你的评论问题:为什么我不能在这里覆盖属性?

你可以:通过添加另一对花括号,它将为匿名类型创建一个构造函数,例如:

public class OtherObject {
    protected String name;

    public OtherObject(String name) {
        super();
        this.name = name;
    }

    public String toString() {
        return getClass() + ": " + name;
    }

    public static void main(String[] args) {
        OtherObject o1 = new OtherObject("bar");
        OtherObject o2 = new OtherObject("bar") { // will call parent constructor first -> name = "bar"
            {
                // constructor for the anonymous type
                name = "foo"; // overwrite the name
            }           
        };

        System.out.println(o1); // prints "class OtherObject: bar"
        System.out.println(o2); // prints "class OtherObject$1: foo"
    }
}

答案 4 :(得分:0)

使用一个新对象调用一个方法,后跟花括号,就像扩展该类一样,在java中称为匿名类。

myObject.doSomethingWithOtherObject(new OtherObject() {
  public String toString () {
    return "I am the other object.";
  }

});

您无法覆盖属性的原因可能是因为它们的访问修饰符。 对于覆盖类成员,它应该具有至少受保护的访问修饰符。

public class OtherObject {
    protected String name;
}

您现在可以覆盖匿名类中的名称。