代码之家  ›  专栏  ›  技术社区  ›  wutzebaer

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

  •  2
  • wutzebaer  · 技术社区  · 7 年前

    设置字段

    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 回复  |  直到 7 年前
        1
  •  1
  •   Oleg Cherednik    7 年前

    我想这要看情况而定。两个例子都正确。

    如果您有继承,并且子类的数量是一般逻辑,那么您的第一种方法更好。 ,一定要把你的财产 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);
        }
    }
    

    或者

    public interface Weapon {
        Integer getDamage();
    }
    
    public class Knive implements Weapon {
        // light-weight strategy
    
        public Integer getDamage() {
            return 100;
        }
    }
    
        2
  •  0
  •   davidxxx    7 年前


    但他们的意图并不相同。
    带参数的构造函数允许用此参数值创建的实例:它设置实例状态。

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

    假设你有课 Warrior Weapon 作为场,你可以计算 由于这个方法,每个子类都必须实现:

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

    现在没什么能阻止你储存 damage 您在中收到的信息 武器 子类:

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

        3
  •  0
  •   krishnashu    7 年前

    我不认为这是关于个人品味,而是关于可重用性、正确性和跨扩展类的一致性。

    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,可以重写它。

        4
  •  0
  •   Ali    7 年前

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

    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方法,甚至不必重写子类中的任何内容。