2013-06-19 91 views
2

我有一個類似的類的列表,這些類都是同一個抽象類的子類。我也有一些布爾應該與應該使用的類相對應。如何從一組類中創建一個類的實例?

例如,我有一堆類,具有以下約定命名:

boolean[] classesOn = new boolean[4]; 
abstract class myClass {} 

class myClass1 extends myClass { public void myClass1(float x, float y) ...} 
class myClass2 extends myClass {} 
class myClass3 extends myClass {} 
class myClass4 extends myClass {} 
... 

的想法是隻使用了依賴於classesOn相應的布爾的類。爲此,我使用for循環,循環遍歷classesOn並檢查哪些是true。現在,我有以下代碼:

for (int i = 0; i < classesOn.length; i++) { 
    if (classesOn[i]) { 
    switch (i) { 
     case 0: c = new myClass1(x, y); break; 
     case 1: c = new myClass2(x, y); break; 
... 

現在,這是非常低效的,當我加myClass新的擴展我需要添加新的案例。我希望能夠僅僅說if (classesOn[i]) { c = new "myClass" + (i + 1)();}來創建該特定類的實例。

我該怎麼做?

(順便說一句,這只是一個例子,每個類的實際執行情況差異很大)

我目前正在對使用實際上是在加工,那裏有多種配色方案,在一個類中的每個代表。但我很好奇未來如何爲所有類型的課程做到這一點。

是我的工作,現在確切的代碼如下 - (但我感興趣的是一般的答案)

abstract class Scheme { 
    float red,blue,green,x,y; 
    String description; 
    public void mousespot(){ 
    this.x = mouseX; 
    this.y = mouseY; 
    return; 
    } 
    public float getRed(){ 
    return this.red; 
    } 
    public float getBlue(){ 
    return this.blue; 
    } 
    public float getGreen(){ 
    return this.green; 
    } 
    public String getDescription(){ 
    fill(255,255,255); 
    textSize(32); 
    return this.description; 
    } 
} 
class Scheme1 extends Scheme { 
    public Scheme1(float x, float y) { 
    this.description = "Green-Yellow-GW-Turqouise"; 
    this.red = map(x, 0, width, 0, 255); 
    this.blue = map(y, 0, height, 0, 255); 
    this.green = 255 * (float) dist(width/2, height/2, x, y)/(x/y); 
    } 
} 

class Scheme2 extends Scheme { 
    public Scheme2(float x, float y) { 
    this.description = "Red-Yellow-Peach-Magenta"; 
    this.green = map(x, 0, width, 0, 255); 
    this.blue = map(y, 0, height, 0, 255); 
    this.red = 255 * (float) dist(width/2, height/2, x, y)/(x/y); 
    } 
} 

,並在mouseDragged()方法:

for (i = 0; i < colorschemesOn.length;i++) { 
     if (colorschemesOn[i]) { 
     switch(i) { 
      case 0: 
      public Scheme selectedScheme = new Scheme1(mouseX,mouseY); 
      break; 
      case 1: 
      public Scheme selectedScheme = new Scheme2(mouseX,mouseY); 
      break; 
      case 2: 
      public Scheme selectedScheme = new Scheme3(mouseX,mouseY); 
      break; 
      case 3: 
      public Scheme selectedScheme = new Scheme4(mouseX,mouseY); 
      break; 
      case 4: 
      public Scheme selectedScheme = new Scheme5(mouseX,mouseY); 
      break; 
      case 5: 
      public Scheme selectedScheme = new Scheme6(mouseX,mouseY); 
      break; 
      case 6: 
      public Scheme selectedScheme = new Scheme7(mouseX,mouseY); 
      break; 
      case 7: 
      public Scheme selectedScheme = new Scheme8(mouseX,mouseY); 
      break; 
      case 8: 
      public Scheme selectedScheme = new Scheme9(mouseX,mouseY); 
      break; 
      case 9: 
      public Scheme selectedScheme = new Scheme10(mouseX,mouseY); 
      break; 
      case 10: 
      public Scheme selectedScheme = new Scheme11(mouseX,mouseY); 
      break; 
      case 11: 
      public Scheme selectedScheme = new Scheme12(mouseX,mouseY); 
      break; 
      default: 
      public Scheme selectedScheme = new Scheme1(mouseX,mouseY); 
      break; 
     } 
    } 
} 
+0

使用反射,您可以創建一個n由類名實例化。一個例子(使用構造函數,如果它是默認的''clazz.newInstance()''):http://stackoverflow.com/questions/6094575/creating-an-instance-using-the-class-name - 和 - 調用構造函數 順便說一句,你想達到什麼? – MaQy

+0

它實際上在Processing中。我有一個應該有不同配色方案的程序,我將每個方案都表示爲一個班級。 – marisbest2

回答

4

不要依賴於命名約定,而不是創建一個數組:

Class<? extends myClass>[] classes = new Class<? extends myClass>[] { 
    myClass1.class, myClass2.class, myClass3.class, myClass4.class 
}; 
boolean[] classesOn = new boolean[classes.length]; 

然後你就可以與反思實例他們:

if (classesOn[i]) { myClass c = classes[i].getConstructor().newInstance(); } 

如果你的構造函數採用參數:

myClass c; 
if (i < classesOn.lenght && classesOn[i]) { 
    c = classes[i] 
     .getConstructor(float.class, float.class) 
     .newInstance(mouseX, mouseY); 
} else { 
    c = new myClass1(mouseX, mouseY); 
} 
+0

對'getConstructor()'的調用是多餘的,因爲'Class#newInstance()'是隱含的。我不認爲你的意思是創建一個實例的數組?該問題詢問如何創建第n個類的單個實例。 – Vulcan

+0

@Vulcan不是真的,那是一個不同的應用程序。你可以用'newinstance()'來捕獲'InstantiationException'或'InvocationTargetException'(如果我正確地記得它)。你不能用'Class.newInstance()'做同樣的事情。 – gaborsch

+0

我不認爲這會有幫助,因爲它需要我每次手動擴展課程。我只想調整布爾數組中的值的數量。 – marisbest2

2

您可以使用反射

if (classesOn[i]) { c = Class.forName("myClass" + (i + 1)).newInstance(); } 

這很少是一個好主意,並且通常有一個bett呃構建你的類/代碼的方式意味着你不需要它。

更優雅的方式可能是使用Reflections庫。 (不要與內置的混淆)

它支持通過註釋或接口等查詢類。你可以通過它找到myClass的所有子類,而不管它們被稱爲或JAR。

如果你的構造函數有兩個參數,你可以將兩個參數傳遞給它。

if (classesOn[i]) { 
    c = Class.forName("myClass" + (i + 1)) 
       .getConstructor(float.class, float.class) 
       .newInstance(mouseX, mouseY); 
} 
+0

+1,但另一種方法是創建一個'Class'數組,其元素索引與'boolean'數組的索引匹配。 – Vulcan

+0

我的構造函數有兩個參數 – marisbest2

+0

@ marisbest2你需要得到一個匹配的構造函數,注意float!= Float。你的情況必須是'float.class'。 –

相關問題