使用字段或重写方法来定义抽象类的值

时间:2018-08-17 10:23:09

标签: java

设置父类的值时,更可取的方法是

设置字段

public abstract class Weapon {
    final Integer damage;
}
public class Knive extends Weapon {
    public Knive(){
        damage = 100;
    }
}

覆盖方法

public abstract class Weapon {
    public abstract int getDamage();
}
public class Knive extends Weapon {
    @Override
    public int getDamage(){
        return 100;
    }
}

还是个人品味?

4 个答案:

答案 0 :(得分:1)

我认为这取决于情况。这两个例子都是正确的。

当您拥有继承权时,最好使用拳头方法,这是子类数量的通用逻辑。 但是,请确保您的财产为protected

第二种方法更适合使用轻型类,例如没有默认实现的策略。在这种情况下,您可以将父类更改为interface

public abstract class Weapon {
    protected final Integer damage;

    protected Weapon(Integer damage) {
        this.damage = damage;
    }

    // more logic here
}

public class Knive extends Weapon {
    public Knive(){
        super(100);
    }
}

OR

public interface Weapon {
    Integer getDamage();
}

public class Knive implements Weapon {
    // light-weight strategy

    public Integer getDamage() {
        return 100;
    }
}

答案 1 :(得分:0)

这两种方式不反对。您可以使用一个,第二个或两个。
但是这些目的并不相同。
带参数的构造函数允许使用此参数对创建的实例进行赋值:它设置实例状态。

在将方法指定为抽象的同时,可以定义子类必须遵守的协定。这样,基类或任何其他类都可以依靠此方法执行某些逻辑。模板方法使用了这个想法。

假设您有一个Warrior类的字段Weapon,由于每个子类都必须实现此方法,因此您可以计算Weapon所造成的损害:< / p>

public class Warrior{
   private Weapon weapon;
   // ...
   public void attack(Warrior otherWarrior){
        otherWarrior.receiveAttack(weapon.getDamage());
   }
}

现在,没有什么可以阻止您存储在damage子类中收到的Weapon信息了:

public class Knive extends Weapon {
    private int damage; 

    public Knive(int damage){
       this.damage = damage;
    }
    @Override
    public int getDamage(){
        return damage;
    }
}

如前所述,这两种方法完全没有对立。

答案 2 :(得分:0)

这很大程度上取决于您要在何时何地设置该值,但是请注意,抽象类可以具有字段,方法甚至构造函数,但是无法实例化。因此对于您提供的示例,我更喜欢使用以下示例:

abstract class Weapon{
   private int damage;

   public Weapon(int damage) {
       this.damage = damage;
   }

   public int getDamage() {
       return damage;
   }
}

class Knife extends weapon{
   //damage as a parameter
   public Knife(int damage) {
       super(damage);
   }

   //damage as a default value
   public Knife(){
       super(100);
   }
}

然后您可以通过以下方式使用它:

Weapon knife = new Knife(100);
Weapon defaultKnife = new Knife();
System.out.print(knife.getDamage()); --->100

您还可以在父类中具有getter和setter方法,甚至不必重写子类中的任何内容。

答案 3 :(得分:0)

我不认为这与个人品味有关,而是与扩展类的可重用性,正确性和统一性有关。

public abstract class Weapon {
    protected Integer damage;
    public void setDamage(Integer damage){
        this.damage = damage;
    }
    public Integer getDamage(){
        return this.damage;
    }
}
public class Knive extends Weapon {
    public Knive(){
        setdamage(100);//or damage = 100;
    }
} 

所有扩展类的setter和getter都相同。如果您想为某些特定结果显式覆盖setter和getter,则可以覆盖它。