I was reading on this site about the Liskov substitution principle. It states:
From my understanding this means that whatever methods are in my base class, they must be implemented in my subclass, and according to this page, if you override a method in the base class and it does nothing or throws an exception, you're in violation of the principle.
Suppose I had an abstract class called Weapon, and the subclasses ReloadableWeapon and Sword. ReloadableWeapon contains a method that's unique to that class, called Reload(). When declaring objects, standard practice is you do it from the abstract class and then subclass, like so:
Weapon rifle = new ReloadableWeapon();
Weapon sword = new Sword();
If I wanted to use the reload method for a rifle, I could cast it. Based on numerous articles and textbooks, this could lead to problems later on.
Also, if I have the reload method in the base class Weapon, then Sword would ignore or throw, which is wrong.
If I wanted to avoid all that, would using the Strategy Pattern be a viable option?
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 int attack(String action){} // - Call any actions that are attacks.
public void standardAction(String action){} // - Call aim or reload here.
public static Weapon Sword(final String name, final damage, final List<AttackStrategy> standardActions, final List<Actions> attacks){
return new Weapon(name, damage, standardActions, attacks);
}
Attack Interface and Implementation:
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
}
}
'm not asking if I've implemented the Strategy Pattern correctly, but rather can I use the pattern when faced with a subclass that has a method unique to that subclass and I don't want to cast it? or in other words, rather than violate the LSP, can I prohibit the use of inheritance and use the Strategy Pattern to implement the require methods?
Notes:
The pattern solves my problem in 2 ways:
I don't have to downcast, I can store my Weapons in a List<Weapon> collection without worrying about checking the type, and then casting
Any weapon that isn't Reloadable, won't have the concrete class Reload. This mean no throwing or leaving the method blank
↧