class 的某些对象可以具有特定行为,但其他对象则没有
Some Object of a class can have a particular behavior but others doesn't
我该如何设计这种特殊情况。
问题是:
- 如果我在 Bird 中实现 Swim 并将 diveNow() 行为添加到 "fly high",但这是不需要的,因为所有的鸟都不能飞。
换句话说“有些对象可以做到这一点,有些则不能,并且都属于同一个 class。
我可以使用策略模式吗?如何?
如果我有一大堆行为 [Interfaces] 遇到同样的问题怎么办?
另一种情况(如果我重写 Animal 中的 flyNow()
但当然有些动物会飞(飞鼠,飞狐猴。)
我不知道 Strategy 模式在这里是否有用,但似乎是一个匿名的 class,您可以在其中实现 flyNow()
和 diveNow()
:
Bird divingCapableBird = new Bird() {
void flyNow() {
}
void diveNow() {
}
};
这种方法的问题在于像 divingCapableBird instanceof Swim
这样的语句将 return false
,因为 divingCapableBird
的类型没有实现 Swim
界面。
为了解决这个问题,你可以实现一个 class,它实现了 Swim
和 extends Bird
并且会公开这两个方法:
class DivingCapableBird extends Bird implements Swim {
//methods here
}
但是,这个结构还有另一个问题 - 现在证明 DivingCapableBird
不是 Animal
。
万恶之源是Animal
不应该同时实现Swim
和Fly
接口。
Animal
应该是顶级 (abstract
) class,而接口应该由 [=22] 的特定子 class 实现=].
所以,你应该拥有的是:
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 Duck extends Bird implements Fly, Swim {}
class Duck extends FlyingBird implements Swim {}
企鹅是会游泳但不会飞的鸟:
class Penguin extends Bird implements Swim {}
鸵鸟既不会飞也不会游泳(据我所知):
class Ostrich extends Bird {}
你可以去利用一些构图。如果在适当的 classes 中分离这些行为,您甚至可以在相同 class 的成员之间自由切换实现。
这也与您的策略模式有关。你可以有这样的东西:
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 class 层次结构中组合任意多的行为。对于具有多种行为的动物和类似的东西,这可能会变得非常复杂,但如果你仔细计划,我想你可能会利用它。
只是把动物和它们的行为分开:
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 设计模式,可以防止每种可能的动物和行为组合的子类数量激增。
来自链接页面的精美插图:
我该如何设计这种特殊情况。
问题是:
- 如果我在 Bird 中实现 Swim 并将 diveNow() 行为添加到 "fly high",但这是不需要的,因为所有的鸟都不能飞。
换句话说“有些对象可以做到这一点,有些则不能,并且都属于同一个 class。
我可以使用策略模式吗?如何? 如果我有一大堆行为 [Interfaces] 遇到同样的问题怎么办?
另一种情况(如果我重写 Animal 中的 flyNow() 但当然有些动物会飞(飞鼠,飞狐猴。)
我不知道 Strategy 模式在这里是否有用,但似乎是一个匿名的 class,您可以在其中实现 flyNow()
和 diveNow()
:
Bird divingCapableBird = new Bird() {
void flyNow() {
}
void diveNow() {
}
};
这种方法的问题在于像 divingCapableBird instanceof Swim
这样的语句将 return false
,因为 divingCapableBird
的类型没有实现 Swim
界面。
为了解决这个问题,你可以实现一个 class,它实现了 Swim
和 extends Bird
并且会公开这两个方法:
class DivingCapableBird extends Bird implements Swim {
//methods here
}
但是,这个结构还有另一个问题 - 现在证明 DivingCapableBird
不是 Animal
。
万恶之源是Animal
不应该同时实现Swim
和Fly
接口。
Animal
应该是顶级 (abstract
) class,而接口应该由 [=22] 的特定子 class 实现=].
所以,你应该拥有的是:
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 Duck extends Bird implements Fly, Swim {}
class Duck extends FlyingBird implements Swim {}
企鹅是会游泳但不会飞的鸟:
class Penguin extends Bird implements Swim {}
鸵鸟既不会飞也不会游泳(据我所知):
class Ostrich extends Bird {}
你可以去利用一些构图。如果在适当的 classes 中分离这些行为,您甚至可以在相同 class 的成员之间自由切换实现。
这也与您的策略模式有关。你可以有这样的东西:
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 class 层次结构中组合任意多的行为。对于具有多种行为的动物和类似的东西,这可能会变得非常复杂,但如果你仔细计划,我想你可能会利用它。
只是把动物和它们的行为分开:
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 设计模式,可以防止每种可能的动物和行为组合的子类数量激增。
来自链接页面的精美插图: