正确使用抽象方法

时间:2017-04-15 17:03:29

标签: java arrays list methods abstract

我无法理解抽象方法的概念以及如何正确使用它们。

基本上,我被指示编写一个带有抽象超类“Alien”和2个子类“Martian and Saturner”的代码,在这些类中存在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++;
    }

3 个答案:

答案 0 :(得分: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++;
        }
    }
}

答案 1 :(得分:1)

变化是唯一不变的,抽象变更。在你的情况下,每个外星人可能有不同的入侵行星的方式,这可能是基于外星人所属的家庭,可用资源以及入侵的行星类型。

等级外星人是超级阶级,可能不知道行星的类型(将来可能会有更多),因此也可能有许多不同类型的外星人。行星的每个本地人可能具有不同的入侵行为。因此,方法 invade()最好是 abstract

现在正如你所说它接受行星的名字入侵并且什么都不返回。您可以在Alien.java中将其定义为抽象

public abstract void invade(String planetName);

所有子类都将实现并提供具体实现。

在驱动程序代码中,您可以迭代并可以使用行星名称调用方法invade

编辑如果你需要不同的策略进行入侵,那么我们需要考虑将其作为抽象。您可以定义抽象类InvadingStrategy或可以具有接口。 这可以包括与策略相关的方法。一个这样的方法可以如下所示

public abstract String getStrategyDescription();

您可能有不同的具体类(WaterSystemPollutionStrategyBombingStrategy等),它们将提供InvadingStrategy定义的抽象方法的实现。现在,invade方法的签名可能就像

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

您可以根据要侵略的行星名称和具体策略类的对象调用invade方法。在Alien.java的子类实现invade方法时,您可以打印与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);
}

Alien的子类:Martian.java 同样聪明的你可以拥有Alien的各种子类

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 Interface :这可以包含策略的必要方法。目前只是采用一种方法来获得战略的描述。

public interface InvadingStrategy {
    String getStrategyDescription();
}

实施InvadingStrategy的具体类:MissileStrategy 同样你可以有各种策略

public class MissileStrategy implements InvadingStrategy {

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

}

另一个实现InvadingStrategy的Concrete类:WaterSystemDestructionStrategy

public class WaterSystemDestructionStrategy implements InvadingStrategy {

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

}

驱动程序代码     import 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++;
        }
    }
}

答案 2 :(得分:0)

如果你的invade()方法应该接受一个行星,第一步实际上是实现一个行星类型(读取:类),然后为每个物种实现这样的入侵方法:

@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);
}
相关问题