我不知道这种传递对象作为参数的方式是什么。所以我不知道在网站上搜索什么。如果以前曾经问过我,我很抱歉,我确信它已经有了。
有人可以告诉我这两种传递对象作为参数的方式之间的区别是什么?为什么我不能以第一种方式覆盖属性和方法?
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不能识别我试图向构造函数发送参数?
感谢阅读!
答案 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;
}
您现在可以覆盖匿名类中的名称。