Java 初始化抽象类的一般变量

Java 初始化抽象类的一般变量,java,inheritance,abstract-class,Java,Inheritance,Abstract Class,我有两个抽象类:Char和arm。每一个都有两个衍生类:国王和巨魔,以及棍棒和剑 角色始终有武器,但未指定类型。因此,在构建Char类时,我无法初始化正确的类型。此外,在选择字符时,我同样无法初始化正确的类型 初始化抽象类是错误的吗?如何初始化一种类型的类,然后更改变量类?假设新类型是同一父类的微小不同继承?还是应该采取完全不同的做法 很可能我还没有理解抽象类的概念。我不熟悉Java和纯OOP public class Player{ private Char c;

我有两个抽象类:Char和arm。每一个都有两个衍生类:国王和巨魔,以及棍棒和剑

角色始终有武器,但未指定类型。因此,在构建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";
    }
}

不能实例化抽象类。一个更聪明的方法是为
Char
一个
武器
实例提供构造函数作为参数-您只需在
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());

不能实例化抽象类。一个更聪明的方法是为
Char
一个
武器
实例提供构造函数作为参数-您只需在
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());

在Java中,抽象类允许有一个或多个指定但未实现的方法。它们是用来作为共享大多数功能的子类的“最高公分母”,除了一些方法。因此,Java禁止您创建抽象类的实例,并要求任何子类提供抽象方法的实现。这是故意的。它背后的基本思想是促进代码的可重用性,但在现实生活中,这是一个权衡的组合,因此您的里程可能会有所不同。大多数情况下,您可以通过非抽象基类和接口的组合实现类似的效果


根据您的示例,Char不必是一个抽象类,但武器是一个很好的候选,因为它有一个“useWearm”方法。您可以在武器中声明“UseAnsware”为抽象,并在剑和棍棒中提供不同的实现。或者,你可以把一件武器作为一个接口。你想在这里做的抽象是,一个角色可以使用武器,而不知道实际的武器是棍棒还是剑。这意味着你可以随时给一个字符任何种类的武器,一切都应该工作。与在构造函数中传递字符和“int”不同,实际上最好将武器本身传递给它。

在Java中,抽象类允许有一个或多个指定但未实现的方法。它们是用来作为共享大多数功能的子类的“最高公分母”,除了一些方法。因此,Java禁止您创建抽象类的实例,并要求任何子类提供抽象方法的实现。这是故意的。它背后的基本思想是促进代码的可重用性,但在现实生活中,这是一个权衡的组合,因此您的里程可能会有所不同。大多数情况下,您可以通过非抽象基类和接口的组合实现类似的效果


根据您的示例,Char不必是一个抽象类,但武器是一个很好的候选,因为它有一个“useWearm”方法。您可以在武器中声明“UseAnsware”为抽象,并在剑和棍棒中提供不同的实现。或者,你可以把一件武器作为一个接口。你想在这里做的抽象是,一个角色可以使用武器,而不知道实际的武器是棍棒还是剑。这意味着你可以随时给一个字符任何种类的武器,一切都应该工作。与其在构造函数中将字符传递为“int”,实际上最好是将武器本身传递给它。

即使你的问题也不是clear@Ravi让我试着重新措辞和编辑。我不知道这句话的意思:初始化抽象类是错误的吗?如何初始化一种类型的类,然后更改变量类?一个抽象类-Char有一个类型为武器的变量-另一个抽象类。在运行时,将从武器继承的实际武器类型指定给变量。这似乎在代码中起作用,但这是“良好实践”,还是会适得其反?如果是这样的话,还有什么办法呢?使用
public
作为实例变量的访问修饰符会适得其反,使用
int
确定武器或角色的类型会适得其反,抽象类中没有正确的构造函数会适得其反。在
usebarm
中传递字符串会适得其反。即使你的问题不是这样clear@Ravi让我试着重新措辞和编辑。我不知道这句话的意思:初始化抽象类是错误的吗?如何初始化一种类型的类,然后更改变量类?一个抽象类-Char有一个类型为武器的变量-另一个抽象类。在运行时,将从武器继承的实际武器类型指定给变量。这似乎在代码中起作用,但这是“良好实践”,还是会适得其反?如果是这样的话,还有什么办法呢?使用
public
作为实例变量的访问修饰符会适得其反,使用
int
确定武器或角色的类型会适得其反,抽象类中没有正确的构造函数会适得其反。在
usebarm
中传递字符串会适得其反。“无法初始化抽象类”?你这是什么意思?抽象类可以像其他类一样具有构造函数。或者你的意思是实例化?但是代码是有效的。所以,看起来一个人实际上“可以”初始化一个抽象类,甚至可以为它指定一个继承的、非抽象的版本。@Felix,你说得对-我更正了我的答案,我的意思是实例化。您不能创建抽象类的实例,只能创建完成其实现的类的实例。有关这方面的更多详细信息,请阅读