简体   繁体   English

使Java父类方法返回子类对象的方法

[英]Way to make Java parent class method return object of child class

Is there any elegant way to make Java method located within parent class return object of child class, when this method is called from child class object?当从子类对象调用此方法时,是否有任何优雅的方法使位于父类中的 Java 方法返回子类的对象?

I want to implement this without using additional interfaces and extra methods, and to use this without class casts, auxiliary arguments and so on.我想在不使用额外接口和额外方法的情况下实现它,并且在没有类转换、辅助参数等的情况下使用它。

Update:更新:

Sorry that I was not so clear.对不起,我不是很清楚。

I want to implement method chaining, but I have problems with methods of parent class: I lose access to child class methods, when i call parent class methods... I suppose that I'v presented the core of my idea.我想实现方法链,但是我对父类的方法有问题:当我调用父类方法时,我无法访问子类方法......我想我已经提出了我的想法的核心。

So the methods should return this object of this.getClass() class.所以这些方法应该返回this.getClass()类的this对象。

If you're just looking for method chaining against a defined subclass, then the following should work:如果您只是在寻找针对已定义子类的方法链接,那么以下方法应该有效:

public class Parent<T> {

  public T example() {
    System.out.println(this.getClass().getCanonicalName());
    return (T)this;
  }
}

which could be abstract if you like, then some child objects that specify the generic return type (this means that you can't access childBMethod from ChildA):如果您愿意,这可以是抽象的,然后是一些指定通用返回类型的子对象(这意味着您无法从 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;
  }
}

and then you use it like 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();
  }
}

the output will be输出将是

org.example.inheritance.ChildA 
org.example.inheritance.ChildA 
org.example.inheritance.ChildA 
org.example.inheritance.ChildB 
org.example.inheritance.ChildB

What are you trying to achieve ?你想达到什么目的? It sounds like a bad idea.这听起来是个坏主意。 A parent class should not know anything about its children.父类不应该对其子类一无所知。 It seems awfully close to breaking the Liskov Substitution Principle .这似乎非常接近于打破Liskov 替换原则 My feeling is that your use case would be better serve by changing the general design, but hard to say without more informations.我的感觉是,通过更改总体设计,您的用例会得到更好的服务,但如果没有更多信息,就很难说。

Sorry to sound a bit pedantic, but I get a bit scared when I read such question.抱歉听起来有点迂腐,但当我读到这样的问题时,我有点害怕。

Simply to demonstrate:简单演示一下:

public Animal myMethod(){
  if(this isinstanceof Animal){
     return new Animal();
  }
  else{

     return this.getClass().newInstance();
  }
}

You can call this.getClass() to get the runtime class.您可以调用this.getClass()来获取运行时类。

However, this is not necessarily the class that called the method (it could be even further down the hierarchy).但是,这不一定是调用该方法的类(它甚至可以在层次结构的更下方)。

And you would need to use reflection to create new instances, which is tricky, because you do not know what kind of constructors the child class has.并且您需要使用反射来创建新实例,这很棘手,因为您不知道子类具有什么样的构造函数。

return this.getClass().newInstance(); // sometimes works

I know exactly what you mean, in Perl there is the $class variable which means if you call some factory method on a subclass, even if it is not overridden in the subclass, if it instanciates any instances of $class an instance of the subclass will be created.我确切地知道你的意思,在 Perl 中有$class变量,这意味着如果你在子类上调用一些工厂方法,即使它没有在子类中被覆盖,如果它实例化了$class的任何实例是子$class的实例将被创建。

Smalltalk, Objective-C, many other languages have a similar facility. Smalltalk、Objective-C,许多其他语言都有类似的功能。

Alas, there is no such equivalent facility in Java.唉,Java 中没有这样的等效工具。

If you are using Kotlin, you can create an extension function如果你使用 Kotlin,你可以创建一个扩展函数

abstract class SuperClass
class SubClass: SuperClass()

fun <T : SuperClass> T.doSomething(): T {
    // do something
    return this
}

val subClass = SubClass().doSomething()
public class Parent {
    public Parent myMethod(){
        return this;
    }
}
public class Child extends Parent {}

And invoke it like并像这样调用它

       Parent c = (new Child()).myMethod();
       System.out.println(c.getClass());

Is this solution is correct?这个解决方案是否正确? If it is, then, how is it different from the #1 solution?如果是,那么它与#1 解决方案有何不同?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM