简体   繁体   English

我可以在Java中从父实例化相同子类型的类吗?

[英]Could I instantiate class of the same child type from parent in Java?

Is there is the way to instantiate class of the same child type from parent in Java? 有没有办法从Java中的父实例化相同子类型的类?

Eg We have: 例如,我们有:

class Animal {
    Animal clone() {
        ...
    } 
}

class Rabbit extends Animal {
    ...
}

class Fox extends Animal {
    ...
}

Could I write something in animal clone method to get Rabbit if I call it from Rabbits instance and Fox if calling from Fox? 如果我从Rabbits实例调用它,我可以在动物克隆方法中写一些东西来获取Rabbit,如果从Fox调用它,我可以写一些东西给Fox吗? I know that I may write two separate clone methods in Rabbit and Fox but if there is a way to write common method in Animal? 我知道我可以在Rabbit和Fox中编写两个单独的克隆方法,但是是否可以在Animal中编写通用方法? Thanks! 谢谢!

UPD: As I stated in comment I need something like PHP: UPD:正如我在评论中所述,我需要类似PHP的东西:

function clone (): Animal
{
    return eval("return new " . get_class($this) . " ();");
}

You can do it...but you need to use reflection heavily. 您可以做到...但是您需要大量使用反射。

However, the right thing to do would be giving each child class its own clone method and keep the cloner() abstract method in the parent class. 但是,正确的做法是为每个子类提供自己的克隆方法,并将cloner()抽象方法保留在父类中。 As you would not want the parent to be aware of all child class implementations. 因为您不希望父母知道所有子类别的实现。

(PS. clone method is already present in Object class) (PS。clone方法已经存在于Object类中)

abstract class Animal{

//..
//..

Animal cloner();


}


abstract class Rabbit extends Animal{

//..
//..

Rabbit cloner(){
//impl
}


}



abstract class Fox extends Animal{

//..
//..

Rabbit cloner(){
//impl
}


}

You could write something like this: 您可以这样写:

Animal clone1() {
    if (this instanceof Rabbit){
      System.out.println("Returning Rabbit instance");
      return new Rabbit();
    }
    elseif (this instanceof Fox){
      System.out.println("Returning Fox instance");
      return new Fox();
    }else
      return null;
}

or if want to use reflection and do not want to change the super class every time new subclass is added. 或者如果想使用反射并且不想在每次添加新的子类时更改父类。 You could use Dozer Mapper, which will map to a new/clone object. 您可以使用Dozer Mapper,它将映射到新对象/克隆对象。 See below code: 请参阅以下代码:

class Animal {

  Animal clone2(){
    Mapper mapper = new DozerBeanMapper();
    return mapper.map(this, this.getClass());
  }

}

class Rabbit extends Animal {
  int testVar = 20;
}

public class App {
  public static void main(String[] args) throws CloneNotSupportedException, IOException {
    Rabbit rabbit = new Rabbit();
    System.out.println("Object: " + rabbit.hashCode());
    System.out.println("Object var: " + rabbit.testVar);

    Rabbit rabbit2 = (Rabbit) rabbit.clone2();
    System.out.println("Clone object: " + rabbit2.hashCode());
    System.out.println("Object var: " + rabbit2.testVar);
  }

}

Run and check the output both have same field but but are separate object. 运行并检查输出都具有相同的字段,但是是单独的对象。 Note: you need to add dozer mapper dependency/jar in your project. 注意:您需要在项目中添加推土机映射器依赖项/ jar。 For maven check: https://mvnrepository.com/artifact/net.sf.dozer/dozer/5.3.1 对于Maven检查: https : //mvnrepository.com/artifact/net.sf.dozer/dozer/5.3.1

But why would you want to do that? 但是为什么要这么做呢? If you want to create clone, prototype pattern is much cleaner approach. 如果要创建克隆,则原型模式是更简洁的方法。 Prototype pattern : http://www.newthinktank.com/2012/09/prototype-design-pattern-tutorial/ 原型模式: http : //www.newthinktank.com/2012/09/prototype-design-pattern-tutorial/

For what you ask you only need to let JVM know you want this class and it's sub-classes to be cloneable: 对于您所要求的内容,只需要让JVM知道您想要此类,并且它的子类是可克隆的:

class Animal implements Cloneable

and use Object::clone() for Animal, Fox and Rabbit. 并为动物,狐狸和兔子使用Object :: clone()。

With this you only get a shallow copy of the object - meaning the clone and the original object will share the same instances of the non-primary fields. 这样,您只会得到对象的浅表副本-意味着克隆对象和原始对象将共享非主要字段的相同实例。

For every object that requires a deep copy you want to implement a dedicated clone() method. 对于每个需要深层复制的对象,您都想实现一个专用的clone()方法。

More about cloning here . 有关在这里克隆的更多信息。

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

相关问题 子实例从父类实例化 - Child Instantiate from parent class 有没有办法在java中用父对象实例化子类? - Is there a way to instantiate a child class with parent object in java? 我如何接收子类作为需要父类的参数,但不允许用户实例化父类? - How could i receive a child class as a parameter where a parent class is expected, yet not allow the user to instantiate the parent class? Java:声明为父类,但实例化为Child,然后在Child中使用唯一方法 - Java: Declare as a parent class, but instantiate as Child, then using the unique method in Child Java:如何在不使用父构造函数的情况下从子对象实例化父对象? - Java: How can I instantiate a parent object from child without using parent constructor? Java继承:父类的对象实例与2个子类相同 - Java Inheritance: instance of object from parent class same for 2 child classes Java调用相同父类的子构造函数 - Java Calling child constructors of same parent class 从父类型子类对象Java访问子类实例方法 - Accessing Child class instance method from Parent type child class object Java 如果我从父类中创建子类,则再次创建Java - if I create a child class from within a parent class, the parent class gets created again the Java 无法从元组实例化 class - Could not instantiate class from tuple
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM