Java 类的某些对象可以有特定的行为,但其他对象没有';T
我如何设计这种特殊情况 问题是:Java 类的某些对象可以有特定的行为,但其他对象没有';T,java,design-patterns,Java,Design Patterns,我如何设计这种特殊情况 问题是: 如果我在Bird中实现Swim并将diveNow()行为添加到“flyinghigh”中,但这并不是我想要的,因为所有的鸟都不能飞 换句话说,“有些对象可以这样做,有些对象不能这样做,两者都属于同一个类 我可以使用策略模式吗?如何使用? 如果我有一大堆行为[接口]都有同样的问题呢 另一种情况(如果我在Animal中覆盖flyNow() 当然,有些动物会飞(会飞的鼹鼠、会飞的狐猴)。我不知道策略模式在这里是否有用,但似乎是一个匿名类,您可以在其中实现flyNow
当然,有些动物会飞(会飞的鼹鼠、会飞的狐猴)。我不知道策略模式在这里是否有用,但似乎是一个匿名类,您可以在其中实现
flyNow()
和diveNow()
:
这种方法的问题是,类似Swim的divingCapableBird instanceof Swim
语句将返回false
,因为divingCapableBird
的类型没有实现Swim
接口
为了解决这个问题,您可以实现一个类,该类实现Swim
和扩展Bird
,并将公开这两种方法:
class DivingCapableBird extends Bird implements Swim {
//methods here
}
然而,这种结构也存在另一个问题——现在证明,DivingCapableBird
不是一种动物
这里所有邪恶的根源是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
}
不是所有的鸟都会飞,所以不要在那里执行fly
:
class Bird {}
然而,有些鸟类可以:
class FlyingBird extends Bird implements Fly {}
鸭子是会飞会游的鸟。有两种可能性(都有相同的效果,鸭子是会飞会游的鸟):
企鹅是会游泳但不会飞的鸟:
class Penguin extends Bird implements Swim {}
鸵鸟既不会飞也不会游泳(AFAIK):
你可以使用一些组合。如果你在适当的类中分离这些行为,你甚至可以在同一个类的成员之间自由切换实现
这也与您的战略模式有关。您可以有如下内容:
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");
}
}
然后,您可以在动物类层次结构中根据需要组合任意多个行为。对于具有多种行为的动物和类似的东西,这可能会变得非常复杂,但如果您仔细规划,我认为您可能会利用它。只需将动物和它们的行为分开:
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();
基本上,这是一种设计模式,它可以防止每种可能的动物和行为组合的子类数量激增
链接页面中的一个很好的插图:
您可以扩展类bird
以拥有non-flight
和flight
鸟,或者您甚至可以更详细地扩展类bird
以适合每种鸟的bird
…您可以将bird
制作成一个抽象的类。策略是如果您使用bird
,它可以飞行最近你发现飞机
也可以飞行,你可以用飞机
替换鸟
@brso05,但是如果我在相同的情况下有一组行为(跑步、走路等…)@AsSiDe不确定你的意思吗?在你的非飞行
类中,只需覆盖父类方法flynow()
为非飞行鸟做任何你想做的事情……请注意,鸟
或飞行鸟
也可以是接口或抽象类(如果它们有字段)。
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");
}
}
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();