私はこの質問についてフォローアップしていますが、コードから原則に焦点を移しています。
Liskov置換原理(LSP)についての私の理解から、私の基本クラスにあるメソッドは何でも、それらは私のサブクラスに実装する必要があります。このページによれば、基本クラスのメソッドをオーバーライドし、何も実行しないか、例外、あなたは原則に違反しています。
さて、私の問題は次のようにまとめることができます:私は抽象Weapon
class
と2つのクラス、Sword
とを持っていReloadable
ます。と呼ばれるReloadable
特定のが含まれている場合、それにアクセスするにはダウンキャストする必要があります。理想的には、それを回避する必要があります。method
Reload()
method
次に、を使用することを考えましたStrategy Pattern
。このように、各武器は実行可能なアクションのみを認識していたため、たとえば、Reloadable
武器は明らかにリロードSword
できますが、リロードすることはできませんReload class/method
。Stack Overflowの投稿で述べたように、ダウンキャストする必要はなく、List<Weapon>
コレクションを維持できます。
で別のフォーラム、最初の答えができるようにする提案Sword
を認識するReload
だけで何もしません、。これと同じ答えが、上でリンクしたスタックオーバーフローのページにもありました。
理由はよくわかりません。なぜ原則に違反し、Swordにを認識さReload
せ、空白のままにするのですか?Stack Overflowの投稿で述べたように、SPで問題がほぼ解決しました。
なぜそれが実行可能な解決策ではないのですか?
public final Weapon{
private final String name;
private final int damage;
private final List<AttackStrategy> validactions;
private final List<Actions> standardActions;
private Weapon(String name, int damage, List<AttackStrategy> standardActions, List<Actions> attacks)
{
this.name = name;
this.damage = damage;
standardActions = new ArrayList<Actions>(standardActions);
validAttacks = new ArrayList<AttackStrategy>(validActions);
}
public void standardAction(String action){} // -- Can call reload or aim here.
public int attack(String action){} // - Call any actions that are attacks.
public static Weapon Sword(String name, damage, List<AttackStrategy> standardActions, List<Actions> attacks){
return new Weapon(name, damage,standardActions, attacks) ;
}
}
攻撃インターフェースと実装:
public interface AttackStrategy{
void attack(Enemy enemy);
}
public class Shoot implements AttackStrategy {
public void attack(Enemy enemy){
//code to shoot
}
}
public class Strike implements AttackStrategy {
public void attack(Enemy enemy){
//code to strike
}
}
reload()
、空白かどうかstandardActions
リロードアクションが含まれていないことは、単に別のメカニズムです。基本的な違いはありません。両方を行うことができます。=>あなたの解決策は実行可能です(これはあなたの質問でした)。Weaponに空白のデフォルト実装が含まれている場合、Swordはリロードについて知る必要はありません。
class Weapon { bool supportsReload(); void reload(); }
。クライアントは、リロードする前にサポートされているかどうかをテストします。reload
iffをスローするように契約で定義されてい!supportsReload()
ます。これは、駆動されたクラスが先ほど説明したプロトコルに準拠していれば、LSPに準拠しています。