class 的某些对象可以具有特定行为,但其他对象则没有

Some Object of a class can have a particular behavior but others doesn't

我该如何设计这种特殊情况。

问题是:

  1. 如果我在 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,它实现了 Swimextends Bird 并且会公开这两个方法:

class DivingCapableBird extends Bird implements Swim {
    //methods here
}

但是,这个结构还有另一个问题 - 现在证明 DivingCapableBird 不是 Animal

万恶之源是Animal不应该同时实现SwimFly接口。

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 设计模式,可以防止每种可能的动物和行为组合的子类数量激增。

来自链接页面的精美插图: