初始化抽象类的一般变量

时间:2017-10-08 10:28:47

标签: java inheritance abstract-class

我有两个抽象类: Char Weapon 。每个都有两个衍生类: King Troll ,以及 Club Sword

角色总是有武器,但未指定类型。因此,在构建 Char 类时,我无法初始化正确的类型。此外,在选择字符时,我同样无法初始化正确的类型。

  

初始化抽象类是错误的吗?如何初始化一种类,然后更改变量类?如果新类型是同一父类的简单不同的继承?或者应该完全不同地进行它?

很可能我甚至都不理解抽象类的概念。我是Java和纯OOP的新手。

public class Player{
    private Char c;                   // Wrong?

    public void changeChar(int charID, int wepID){
        switch(charID){
            case 1: c = new King(wepID); break;
            case 2: c = new Troll(wepID); break;
        }
    }

    public void fight(){
        c.fight();
    }
}

abstract class Char{
    protected String name;
    public Weapon weapon;         // Wrong?

    Char(int wepID){
        switch(wepID){
            case 1: weapon = new Sword(); break;
            case 2: weapon = new Club(); break;
        }
    }

    public void fight(){
        weapon.useWeapon(name);
    }
}

abstract class Weapon{
    protected String wepName;
    public void useWeapon(String user){
        System.out.println(user + " fights with " + wepName);
    }
}

class Club extends Weapon{
    Club(){
        wepName = "Club";
    }
}

class Sword extends Weapon{
    Sword(){
        wepName = "Sword";
    }
}

class Troll extends Char{
    Troll(int wepID){
        super(wepID);
        name = "Troll";
    }
}

class King extends Char{
    King(int wepID){
        super(wepID);
        name = "King";
    }
}

2 个答案:

答案 0 :(得分:2)

您无法实例化抽象类。更明智的方法是将Char Weapon个实例的构造函数作为参数提供 - 您只需在Char中使用它。

abstract class Char{
    protected String name;
    public Weapon weapon;

    Char(Weapon weapon){
        this.weapon = weapon;
    }

    public void fight(){
        weapon.useWeapon(name);
    }
}

class Troll extends Char{
    Troll(Weapon weapon){
        super(weapon);
        name = "Troll";
    }
}

以及稍后的代码:

Char troll = new Troll (new Club());

答案 1 :(得分:2)

在Java中,允许抽象类具有一个或多个指定但未实现的方法。它们被用作"最高的共同点"对于共享大部分功能的子类,除了一些方法。因此,Java禁止您创建抽象类的实例,并且需要任何子类来提供抽象方法的实现。这是设计的。它背后的基本思想是提升代码的可重用性,但在现实生活中,它是一种权衡取舍,所以你的里程可能会有所不同。大多数情况下,您可以通过非抽象基类和接口的组合实现类似的效果。

根据你的例子,Char不一定是抽象类,但是武器是一个很好的候选者,因为它有一个" useWeapon"方法。你可以声明" useWeapon"作为武器中的抽象,并在剑和俱乐部提供不同的实现。或者,您可以将武器作为界面。你想在这里做的抽象是Char可以使用武器而不知道实际的武器是俱乐部还是剑。这意味着你可以随时给一个Char作为任何类型的武器,一切都应该有效。而不是传递Char an" int"在构造函数中,将武器本身传递给它实际上更好。