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

时间:2022-07-04 19:37:10

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对象。

6 个解决方案

#1


54  

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

#2


7  

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. My feeling is that your use case would be better serve by changing the general design, but hard to say without more informations.

你想要达到什么目的?这听起来不错。父类不应该知道它的孩子。它似乎非常接近打破Liskov替代原则。我的感觉是,通过改变一般设计可以更好地服务于您的用例,但如果没有更多信息则很难说。

Sorry to sound a bit pedantic, but I get a bit scared when I read such question.

很抱歉听起来有些迂腐,但是当我读到这样的问题时,我有点害怕。

#3


3  

Simply to demonstrate:

只需演示:

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

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

#4


2  

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

#5


1  

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的任何实例实例化为子类的实例将被创建。

Smalltalk, Objective-C, many other languages have a similar facility.

Smalltalk,Objective-C,许多其他语言都有类似的功能。

Alas, there is no such equivalent facility in Java.

唉,Java中没有这样的等效设施。

#6


0  

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解决方案有何不同?

#1


54  

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

#2


7  

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. My feeling is that your use case would be better serve by changing the general design, but hard to say without more informations.

你想要达到什么目的?这听起来不错。父类不应该知道它的孩子。它似乎非常接近打破Liskov替代原则。我的感觉是,通过改变一般设计可以更好地服务于您的用例,但如果没有更多信息则很难说。

Sorry to sound a bit pedantic, but I get a bit scared when I read such question.

很抱歉听起来有些迂腐,但是当我读到这样的问题时,我有点害怕。

#3


3  

Simply to demonstrate:

只需演示:

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

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

#4


2  

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

#5


1  

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的任何实例实例化为子类的实例将被创建。

Smalltalk, Objective-C, many other languages have a similar facility.

Smalltalk,Objective-C,许多其他语言都有类似的功能。

Alas, there is no such equivalent facility in Java.

唉,Java中没有这样的等效设施。

#6


0  

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解决方案有何不同?