当从子类对象调用此方法时,是否有任何优雅的方法使Java方法位于子类的父类返回对象中?
我想在不使用其他接口和额外方法的情况下实现它,并且在没有类强制转换,辅助参数等的情况下使用它。
更新
很抱歉我不太清楚。
我想实现方法链接,但我遇到了父类方法的问题:当我调用父类方法时,我无法访问子类方法... 我想我已经提出了我的想法。
因此,方法应该返回this
类的this.getClass()
对象。
答案 0 :(得分:59)
如果您只是在寻找针对已定义子类的方法链接,那么以下内容应该有效:
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
答案 1 :(得分:7)
你想要达到什么目的?这听起来不错。父类不应该知道它的孩子。它似乎非常接近打破Liskov Substitution Principle。我的感觉是,通过改变一般设计可以更好地发挥你的用例,但没有更多的信息就很难说。
很抱歉听起来有些迂腐,但当我读到这样的问题时,我有点害怕。
答案 2 :(得分:3)
简单地说明:
public Animal myMethod(){
if(this isinstanceof Animal){
return new Animal();
}
else{
return this.getClass().newInstance();
}
}
答案 3 :(得分:2)
您可以调用this.getClass()
来获取运行时类。
但是,这不一定是调用该方法的类(它可能在层次结构中更远)。
并且您需要使用反射来创建新实例,这很棘手,因为您不知道子类具有哪种构造函数。
return this.getClass().newInstance(); // sometimes works
答案 4 :(得分:1)
我确切地知道你的意思,在Perl中有$class
变量,这意味着如果你在子类上调用一些工厂方法,即使它没有在子类中重写,如果它实例化$class
{1}}将创建子类的实例。
Smalltalk,Objective-C,许多其他语言都有类似的功能。
唉,Java中没有这样的等效设施。
答案 5 :(得分:1)
如果您使用的是Kotlin,则可以创建扩展功能
abstract class SuperClass
class SubClass: SuperClass()
fun <T : SuperClass> T.doSomething(): T {
// do something
return this
}
val subClass = SubClass().doSomething()
答案 6 :(得分:0)
public class Parent {
public Parent myMethod(){
return this;
}
}
public class Child extends Parent {}
并像
一样调用它 Parent c = (new Child()).myMethod();
System.out.println(c.getClass());
这个解决方案是否正确?如果是,那么它与#1解决方案有何不同?