簡體   English   中英

我可以在Java中從父實例化相同子類型的類嗎?

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

有沒有辦法從Java中的父實例化相同子類型的類?

例如,我們有:

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

class Rabbit extends Animal {
    ...
}

class Fox extends Animal {
    ...
}

如果我從Rabbits實例調用它,我可以在動物克隆方法中寫一些東西來獲取Rabbit,如果從Fox調用它,我可以寫一些東西給Fox嗎? 我知道我可以在Rabbit和Fox中編寫兩個單獨的克隆方法,但是是否可以在Animal中編寫通用方法? 謝謝!

UPD:正如我在評論中所述,我需要類似PHP的東西:

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

您可以做到...但是您需要大量使用反射。

但是,正確的做法是為每個子類提供自己的克隆方法,並將cloner()抽象方法保留在父類中。 因為您不希望父母知道所有子類別的實現。

(PS。clone方法已經存在於Object類中)

abstract class Animal{

//..
//..

Animal cloner();


}


abstract class Rabbit extends Animal{

//..
//..

Rabbit cloner(){
//impl
}


}



abstract class Fox extends Animal{

//..
//..

Rabbit cloner(){
//impl
}


}

您可以這樣寫:

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;
}

或者如果想使用反射並且不想在每次添加新的子類時更改父類。 您可以使用Dozer Mapper,它將映射到新對象/克隆對象。 請參閱以下代碼:

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);
  }

}

運行並檢查輸出都具有相同的字段,但是是單獨的對象。 注意:您需要在項目中添加推土機映射器依賴項/ jar。 對於Maven檢查: https : //mvnrepository.com/artifact/net.sf.dozer/dozer/5.3.1

但是為什么要這么做呢? 如果要創建克隆,則原型模式是更簡潔的方法。 原型模式: http : //www.newthinktank.com/2012/09/prototype-design-pattern-tutorial/

對於您所要求的內容,只需要讓JVM知道您想要此類,並且它的子類是可克隆的:

class Animal implements Cloneable

並為動物,狐狸和兔子使用Object :: clone()。

這樣,您只會得到對象的淺表副本-意味着克隆對象和原始對象將共享非主要字段的相同實例。

對於每個需要深層復制的對象,您都想實現一個專用的clone()方法。

有關在這里克隆的更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM