当从子类对象调用此方法时,是否有任何优雅的方法可以使Java方法位于子类的父类返回对象中?如何让Java父类方法返回子类的对象
我想在不使用其他接口和额外方法的情况下实现此功能,并且不使用类转换,辅助参数等等。
更新:
对不起,我是不太清楚。我想要实现方法链,但我有父类方法的问题:当我调用父类方法时,我失去对子类方法的访问... 我想我已经提出了我的核心理念。
所以方法应该返回this
对象this.getClass()
类。
当从子类对象调用此方法时,是否有任何优雅的方法可以使Java方法位于子类的父类返回对象中?如何让Java父类方法返回子类的对象
我想在不使用其他接口和额外方法的情况下实现此功能,并且不使用类转换,辅助参数等等。
更新:
对不起,我是不太清楚。我想要实现方法链,但我有父类方法的问题:当我调用父类方法时,我失去对子类方法的访问... 我想我已经提出了我的核心理念。
所以方法应该返回this
对象this.getClass()
类。
如果你只是在寻找方法链接对定义的子类,那么下面应该工作:
public class Parent<T> {
public T example() {
System.out.println(this.getClass().getCanonicalName());
return (T)this;
}
}
如果你喜欢,那么指定通用返回类型的一些子对象可能是抽象的(这意味着你不能从ChildA访问childBMethod):
public class ChildA extends Parent<ChildA> {
public ChildA childAMethod() {
System.out.println(this.getClass().getCanonicalName());
return this;
}
}
public class ChildB extends Parent<ChildB> {
public ChildB childBMethod() {
return this;
}
}
,然后你使用这样
public class Main {
public static void main(String[] args) {
ChildA childA = new ChildA();
ChildB childB = new ChildB();
childA.example().childAMethod().example();
childB.example().childBMethod().example();
}
}
输出将是
org.example.inheritance.ChildA
org.example.inheritance.ChildA
org.example.inheritance.ChildA
org.example.inheritance.ChildB
org.example.inheritance.ChildB
我确切地知道你的意思,在Perl中有$class
变量,这意味着如果你在子类上调用一些工厂方法,即使它没有在子类中重写,如果它实例化任何$class
实例子类将被创建。
Smalltalk,Objective-C,许多其他语言都有类似的功能。
唉,在Java中没有这样的等效工具。
在Perl中,根本不存在通用的内置'$ class'变量。它可以通过检索类方法的第一个参数(例如,MyClass-> mySub()调用作为第一个参数传递MyClass)或者通过获取object(这是调用对象的方法的第一个参数,例如'$ myclass_object-> mySub()'调用将'$ myclass_object'作为第一个参数,'ref($ myclass_object)'返回'“MyClass”') 。请知道你在说什么。 – DVK 2010-10-27 10:08:01
但是,正如你所说,类方法的第一个参数始终是该方法应用于的类的名称。这意味着您可以编写方法,然后执行'$ class-> newInstance()',如果在子类上调用该方法,将会创建子类的实例。用于工厂方法,施工中的模板方法模式等等。在Java中,即使调用MySubObj.newInstance(),静态MyObj newInstance(){..}也将总是生成一个MyObj,并且没有任何方法可以解决这个问题。在Perl中。 – 2010-10-27 12:14:23
只需证明:
public Animal myMethod(){
if(this isinstanceof Animal){
return new Animal();
}
else{
return this.getClass().newInstance();
}
}
随着子类的添加,更改和删除,此方法必须一次又一次地更改。尽管如此,仍然是一个解决方案。 – BoltClock 2010-10-27 09:58:32
@BoltClock,刚刚证明,我已经解决了您在此更新中的问题。 – 2010-10-27 10:02:49
您可以拨打this.getClass()
获得运行时类。
但是,这不一定是调用该方法的类(它可能会更进一步向下)。
而且您需要使用反射来创建新的实例,这很棘手,因为您不知道子类具有哪种类型的构造函数。
return this.getClass().newInstance(); // sometimes works
听起来像:父母可以通过反思产生一个孩子,但不能保证是他的。 :) – 2010-10-27 10:35:15
它将成为当前类的一个子类,因为“this”总是。不过,它可能是一个间接的子类。 – Thilo 2010-10-28 01:12:19
public class Parent {
public Parent myMethod(){
return this;
}
}
public class Child extends Parent {}
并调用它像
Parent c = (new Child()).myMethod();
System.out.println(c.getClass());
这个解决办法是正确的?如果是,那么它与第一种解决方案有什么不同?
你想达到什么目的?这听起来像个不好的主意。家长不应该对其子女有任何了解。看起来非常接近打破Liskov Substitution Principle。我的感觉是,通过改变总体设计可以更好地服务您的用例,但是如果没有更多信息,很难说。
抱歉听起来有点迂腐,但是当我看到这样的问题时,我有点害怕。
非常感谢。这正是我想要的。 – 2010-10-27 13:16:26
@Errandir没问题 - 很高兴帮助 – 2010-10-27 13:17:22
完美。但是我需要将'@SuppressWarnings(“unchecked”)'添加到'example()'中。 – 2012-10-01 02:52:10