2017-04-15 92 views
0

我很難理解抽象方法的概念以及如何正確使用它們。正確使用抽象方法

基本上,我被指示編寫一個抽象超類「外星人」和2個子類「火星人和星期六」的代碼,在這些類中存在invade()方法,該方法應該接受外星人的名字作爲參數攻擊並且不返回值。

import java.util.Arrays; 
import java.util.List; 
import java.util.ArrayList; 

abstract class Alien 
{ 
private String planet; 
private String age; 
private String name; 
private String skinColor; 
private String alienPower; 

public Alien(String planet, String age, String name, String skinColor, String alienPower) 
{ 
    this.planet=planet; 
    this.age=age; 
    this.name=name; 
    this.skinColor=skinColor; 
    this.alienPower=alienPower; 
} 

public abstract void invade(String planetName); 
public String toString() 
{ 
    return name + " is from " + planet + ", is " + age + " years old, " + " has " + skinColor + " skin, and has the ability " + alienPower ; 
} 
} 

class Martian extends Alien { 
public Martian(String p, String a, String n, String s, String ap) { 
    super(p,a,n,s,ap); 
} 

@Override 
public void invade(String strategy, String planetName) { 
    System.out.println("I am a Martian " + strategy + planetName); 
} 

} 


class Saturner extends Alien { 
public Saturner(String p, String a, String n, String s, String ap) { 
    super(p,a,n,s,ap); 
} 

public void invade(String strategy, String planetName) { 
    System.out.println("I am a Saturner " + strategy + planetName); 
} 
} 

public class TestAlien { 
public static void main(String[]args) { 
    ArrayList<Alien> alienList = new ArrayList<>(); 
    List<String> planets = Arrays.asList(new String[] {"Earth", "June", "Mercury", "Venus", "Neptune"}); 
    List<String> methods = Arrays.asList(new String[] {"shooting missiles at", "polluting the water systems of", "burning", "flooding"}); 

    alienList.add(new Martian("Mars", "148", "Zornok", "red", "Read minds")); 
    alienList.add(new Saturner("Saturn", "89", "Hookman", "pitch black ", "Go invisible")); 
    alienList.add(new Martian("Mars", "18", "Guthrax", "gray", "Teleport")); 
    alienList.add(new Saturner("Saturn", "300", "Lamron", "blue", "Fly\n")); 
    int i = 0; 

    for (Alien al : alienList) { 
     System.out.println("Alien race: " + al.getClass().getName() + " || description = " + al.toString()); 
     al.invade(methods.get(i) al.invade(planets.get(i)); 
     i++; 
    } 

回答

1

的變化是不變,摘要什麼樣的變化的唯一的事情。在你的情況下,每個外星人可能有不同的入侵行星的方式,這種行星可能基於外星人所屬的家族,可用資源以及基於行星類型入侵的行星。

類外國人是超一流的,可能不知道的行星的(將來可能會有更多),因此還可能有許多種diffenert外星人。每個行星的本地人可能有不同的入侵行爲。因此方法侵入()最好是作爲abstract製成。

現在,當你說接受這個星球的名稱侵入並返回什麼。您可以在Alien.java中將其定義爲摘要

public abstract void invade(String planetName); 

所有子類都將實現並提供具體實現。

在驅動代碼中,您可以迭代,並且可以調用具有星球名稱的方法invade

編輯如果你需要不同的戰略爲入侵然後再次,我們需要考慮使得它作爲抽象的。您可以定義一個抽象類InvadingStrategy或可以有一個接口。 這可以包括與策略相關的方法。一種這樣的methid可以像下面

public abstract String getStrategyDescription(); 

您可以有不同的具體類(WaterSystemPollutionStrategyBombingStrategy等),這將提供的由InvadingStrategy定義的抽象方法的實現。現在,您的invade方法簽名可以像

public abstract void invade(String planetName, InvadingStrategy strategy); 

可以調用invade方法按照這個星球的名字入侵和具體策略類的對象。在invade方法由Alien.java的子類的實現,你可以打印由getStrategyDescription()作爲返回隨着字符串傳遞行星的名字。

編輯2

下面你可以看到的類和接口,我試圖保持爲您提供的代碼相似的結構,但仍設法保持代碼的靈活性,以適應未來的變化。通過遵循良好的OOP原則,您可以編寫易於維護和理解的簡潔代碼。

Alien.java

public abstract class Alien { 
    // Copying it from the question, Suggestion : USE contextual meaningful names 
    public Alien(String p, String a, String n, String s, String ap) { 
     // set the properties and do the necessary initialization. 
    } 
    public abstract void invade(String planetName, InvadingStrategy strategy); 
} 

子類外國人的:Martian.java喜歡聰明人,你可以有外國人

public class Martian extends Alien { 
    public Martian(String p, String a, String n, String s, String ap) { 
     super(p, a, n, s, ap); 
    } 

    @Override 
    public void invade(String planetName, InvadingStrategy strategy) { 
     System.out.println("I am Martian, I am going to invade " + planetName + " and My Strategy will be " 
       + strategy.getStrategyDescription()); 
    } 
} 

InvadingStrategy接口的各個子類:這可以包括該策略的必要方法。目前只有一種方法來獲得戰略的描述。

public interface InvadingStrategy { 
    String getStrategyDescription(); 
} 

具體類實現InvadingStrategy:MissileStrategy喜歡聰明人,你可以有不同的策略

public class MissileStrategy implements InvadingStrategy { 

    @Override 
    public String getStrategyDescription() { 
     return "shooting missiles at"; 
    } 

} 

一個更具體的類實現InvadingStrategy:WaterSystemDestructionStrategy

public class WaterSystemDestructionStrategy implements InvadingStrategy { 

    @Override 
    public String getStrategyDescription() { 
     return "polluting the water systems of"; 
    } 

} 

驅動代碼 進口的java.util.ArrayList; import java.util.Arrays; import java.util.List;

public class Driver { 
    public static void main(String[] args) { 
     ArrayList<Alien> alienList = new ArrayList<>(); 
     alienList.add(new Martian("Mars", "148", "Zornok", "red", "Read minds")); 
     alienList.add(new Saturner("Saturn", "89", "Hookman", "pitch black ", "Go invisible")); 
     alienList.add(new Martian("Mars", "18", "Guthrax", "gray", "Teleport")); 
     alienList.add(new Saturner("Saturn", "300", "Lamron", "blue", "Fly\n")); 

     List<String> planets = Arrays.asList(new String[] {"Earth", "June", "Mercury", "Venus", "Neptune"}); 
     List<InvadingStrategy> methods = Arrays.asList(new InvadingStrategy[]{new MissileStrategy(),new WaterSystemDestructionStrategy(),new BurningStrategy(),new FloodingStrategy()}); 

     int i = 0; 
     for(Alien alien : alienList){ 
      alien.invade(planets.get(i) , methods.get(i)); 
      i++; 
     } 
    } 
} 
+0

對於簡單情況,您可以使用字符串,但是從良好的靈活設計角度來看,您必須將策略相關行爲封裝在單獨的類中。你將來可能有不同的策略。我再次編輯了我的答案,希望這會有所幫助。 –

+0

你可以看看我編輯的代碼在原來的帖子和評估它,我添加策略的入侵方法,並添加了一些東西到ArrayList的驅動程序 –

+0

@KelOkekpe你可以很好地起訴簡單的字符串,但正如我所說將不會靈活的設計來適應未來的變化,我編輯了我的答案,幷包括我所說的結構。希望它會有所幫助。歡呼和快樂的學習。 –

0

如果你的入侵()方法應該接受一個星球,第一步是實際執行行星式(閱讀:類),然後實現了每一個物種這樣的入侵方法:

@Override 
void invade(Planet target) { 
    //attack planet 
} 

爲攻擊不同的行星,你需要提供行星的列表,迭代的外國人,從行星列表中選擇一個隨機的行星(退房java.util.Random中),並調用每個外星人入侵的方法:

Random rng = new Random(); 
for (Alien alien : aliens) { 
    int roll = rng.nextInt(aliens.size()); 
    Planet target = planets.get(roll); 
    alien.invade(target); 
} 
1

我認爲你正在尋找的東西是這樣的:

import java.util.Arrays; 
import java.util.List; 
import java.util.ArrayList; 

abstract class Alien { 
    private String p; 
    private String a; 
    private String n; 
    private String s; 
    private String ap; 

    public Alien(String p, String a, String n, String s, String ap) { 
     this.p = p; 
     this.a = a; 
     this.n = n; 
     this.s = s; 
     this.ap = ap; 
    } 

    public abstract void invade(String planetName); 
} 

class Martian extends Alien { 
    public Martian(String p, String a, String n, String s, String ap) { 
     super(p,a,n,s,ap); 
    } 

    @Override 
    public void invade(String planetName) { 
     System.out.println("I am a Martian invading " + planetName); 
    } 

} 


class Saturner extends Alien { 
    public Saturner(String p, String a, String n, String s, String ap) { 
     super(p,a,n,s,ap); 
    } 

    public void invade(String planetName) { 
     System.out.println("I am a Saturner invading " + planetName); 
    } 
} 

public class TestAlien { 
    public static void main(String[]args) { 
     ArrayList<Alien> alienList = new ArrayList<>(); 
     List<String> planets = Arrays.asList(new String[] {"Earth", "June", "Mercury", "Venus", "Neptune"}); 

     alienList.add(new Martian("Mars", "148", "Zornok", "red", "Read minds")); 
     alienList.add(new Saturner("Saturn", "89", "Hookman", "pitch black ", "Go invisible")); 
     alienList.add(new Martian("Mars", "18", "Guthrax", "gray", "Teleport")); 
     alienList.add(new Saturner("Saturn", "300", "Lamron", "blue", "Fly\n")); 
     int i = 0; 

     for (Alien al : alienList) { 
      System.out.println("Alien race: " + al.getClass().getName() + " || description = " + al.toString()); 
      al.invade(planets.get(i)); 
      i++; 
     } 
    } 
} 
+0

這有助於很多,但我沒有在我的原始文章中包含的是入侵方法不僅應該獲得行星的價值,而且也應該入侵的方法。因此,而不是輸出是的「我是火星人入侵」或「我是一個Saturner入侵:」每次,它應該有所不同,從(即)我在:,是一個火星拍攝的導彈或我是一個Saturner污染水系統: –

+0

@Kel Okekpe,您也可以參考我的回答,希望這將有助於你在抽象的概念,多一點理解。歡呼和快樂學習 –

+0

我已將此添加到入侵方法 公共無效入侵(字符串planetName,字符串invadeMethod){ 的System.out.println(「我是一個Saturner」 + invadeMethod + planetName); 這到ArrayList: 列表方法= Arrays.asList(新的String [] { 「在射擊導彈」, 「污染的水系統」, 「燃燒」, 「氾濫」}); 這是正確的? –