我如何设计这种特殊情况。
问题是:
换句话说“有些对象可以做到,有些不能,两者都属于同一个类。
我可以使用策略模式。怎么样? 如果我有一大堆行为[接口]有同样的问题怎么办。
另一种情况(如果我在Animal中覆盖flyNow() 但当然有些动物可以飞(飞行的莫布拉斯,飞行的LEMURS。)
答案 0 :(得分:3)
并非所有的鸟都能飞,所以不要在那里实施Fly
:
class Bird {}
然而,有些鸟可以:
class FlyingBird extends Bird implements Fly {}
鸭子是可以飞行和游泳的鸟类。两种可能性(两者都具有相同的效果,鸭子是可以飞行和游泳的鸟):
class Duck extends Bird implements Fly, Swim {}
class Duck extends FlyingBird implements Swim {}
企鹅是可以游泳但不会飞的鸟类:
class Penguin extends Bird implements Swim {}
鸵鸟既不会飞也不会游泳(AFAIK):
class Ostrich extends Bird {}
答案 1 :(得分:1)
我不知道策略模式在这里是否有用,但它似乎是一个匿名类,您可以在其中实现flyNow()
和diveNow()
:
Bird divingCapableBird = new Bird() {
void flyNow() {
}
void diveNow() {
}
};
此方法存在的问题是,divingCapableBird instanceof Swim
等语句将返回false
,因为divingCapableBird
的类型未实现Swim
接口。
为了解决这个问题,你可以实现一个实现Swim
和extends Bird
的类,并公开这两个方法:
class DivingCapableBird extends Bird implements Swim {
//methods here
}
但是,这个结构还存在另一个问题 - 现在发现DivingCapableBird
不是Animal
。
这里所有邪恶的根源是Animal
不应该同时实现Swim
和Fly
接口。
Animal
应该是顶级(abstract
)类,而接口应该由Animal
的特定子类实现。
那么,你应该拥有的是:
interface Swim {
void diveNow();
}
interface Fly {
void flyNow();
}
abstract class Animal {
//some common animal features go here
}
class Bird implements Fly {
//implement methods
}
class DivingCapableBird extends Bird implement Swim {
//implement methods
}
答案 2 :(得分:1)
将动物及其行为分开:
interface Animal {}
class Bird implements Animal {}
abstract class AbstractBehavior {
protected final Animal animal;
Behavior(Animal animal) {
this.animal = animal;
}
}
class SwimImpl extends AbstractBehavior implements Swim {
SwimImpl(Animal animal) {
super(animal);
}
void swim() { System.out.println(animal + " is swimming."); }
}
class FlyImpl implements Fly {
FlyImpl(Animal animal) {
super(animal);
}
void fly() { System.out.println(animal + " is flying."); }
}
然后按照自己喜欢的方式撰写:
class SwimFly implements Swim, Fly {
private Swim swim;
private Fly fly;
SwimFly(Animal animal) {
this.swim = new SwimImpl(animal);
this.fly= new FlyImpl(animal);
}
void swim() { swim.swim(); }
void fly() { fly.fly(); }
}
Bird duck = new Bird();
SwimFly duckBehavior = new SwimFly(duck);
duckBehavior.swim();
duckBehavior.fly();
Bird penguin = new Bird();
Swim penguinBehavior = new SwimImpl(penguin);
penguinBehavior.swim();
基本上,这是Bridge设计模式,可防止每种可能的动物和行为组合的子类数量激增。
来自链接页面的精彩插图:
答案 3 :(得分:0)
你可以去利用一些作文。如果在适当的类中分离这些行为,即使在同一个类的成员之间也可以自由切换实现。
这也与您的策略模式相关联。你可以这样:
public interface Behaviour {
void act();
}
public class FlightBehaviour implements Behaviour {
public void act() {
System.out.println("I am flying");
}
}
public class FlightlessBehaviour implements Behaviour {
public void act() {
System.out.println("I don't feel like flying, although I have wings");
}
}
然后,您可以在Animal类层次结构中组合任意数量的行为。对于有多种行为的动物和类似的东西,这会变得相当复杂,但如果你仔细计划,我认为你可以利用它。