我最近在一次面试中被问到这个问题:
是随着时间的推移改变行为的动物模型。
- A butterfly can fly \* A butterfly does not make a sound
- A caterpillar cannot fly
- A caterpillar can walk (crawl)
我创建了一个具有顶级接口(Insect
)的层次结构,其中有两个接口对其进行了扩展(GroundInsect
和FlyingInsect
)。然后我让Caterpillar
实现了GroundInsect
,让ButterFly
实现了FlyingInsect
。然而,我不能为变形部分想出一个解决方案。下面是我的代码:
昆虫界面:
public interface Insect { }
FlyingInsect接口:
public interface FlyingInsect extends Insect {
public boolean fly();
}
GroundInsect接口:
public interface GroundInsect extends Insect {
// Walk/Crawl
public boolean walk();
}
卡特彼勒类:
public class Caterpillar implements GroundInsect {
@Override
public boolean walk()
{
System.out.println("Caterpillar Walk method");
return true;
}
}
ButterFly类:
public class Butterfly implements FlyingInsect {
@Override
public boolean fly() {
System.out.println("ButterFly Flying method");
return false;
}
}
发布于 2018-09-29 21:46:19
让我们保持示例的简单性并坚持您的初始方法。
首先,我将介绍一个描述各种昆虫的通用接口:
interface Insect {
boolean fly();
boolean walk();
boolean sound();
}
方法fly
、walk
、sound
表示昆虫与其邻居之间可能的相互作用(根据这些相互作用的性质,方法可能会有所不同且更复杂:返回复杂的响应、接受回调等)。
你的第一只蝴蝶可能只是接口的一些具体实现:
class Butterfly implements Insect {
boolean fly() { return true; }
boolean walk() { return true; }
boolean sound() { return false; }
}
现在,让我们添加转换功能。再说一次,一般来说,有多种方法可以做到这一点,所以让我们继续使用蝶形示例。
假设我们想要一个毛毛虫,并且它的相关的蝶形是一个单一的实体(我们不希望毛毛虫在蝴蝶已经存在的情况下仍然四处游荡)。
在这种情况下,我会将caterpillar和butterfly都表示为一个类,并在其中隐藏它的当前状态。“毛毛虫状态”和“蝶形状态”都将包含转换后应更改的操作的不同实现。封闭的实例将把它的方法委托给当前状态。
class Butterfly implements Insect {
private Insect state = new CaterpillarState();
boolean fly() { return state.fly(); }
boolean walk() { return state.walk(); }
boolean sound() { return state.sound(); }
void transform() { state = new ButterflyState(); }
private class ButterflyState implements Insect {
boolean fly() { return true; }
boolean walk() { return true; }
boolean sound() { return false; }
}
private class CaterpillarState implements Insect {
boolean fly() { return false; }
boolean walk() { return true; }
boolean sound() { return true; }
}
}
transform
方法表示变形的触发器。
在这里,ButterflyState
和CaterpillarState
实现与外部类相同的Insect
接口。一般情况下,我可能会为内部状态定义一个不同的接口。
发布于 2018-09-29 12:24:37
一种方法是添加结合这两个接口的第三个契约。这是因为我相信无论是一只蝴蝶还是一只毛毛虫,它都应该是同一个Insect
实例。
下面是一个专门的合同,它将UnsupportedOperationException
作为选项添加:
interface FlyingGroundInsect extends FlyingInsect, GroundInsect {
boolean ableToFly();
boolean ableToWalk();
/**
* As per {@link GroundInsect#walk walk}. This may throw
* UnsupportedOperationException if the animal's stage doesn't allow flying
*
* @throws UnsupportedOperationException If animal is unable to walk
*/
@Override
boolean walk();
/**
* As per {@link FlyingInsect#fly fly}. This may throw
* UnsupportedOperationException if the animal's stage doesn't allow walking
*
* @throws UnsupportedOperationException If animal is unable to fly
*/
@Override
boolean fly();
}
这个单独的类是针对蝶形昆虫的,它被理解为表示一种昆虫,这种昆虫一开始是毛虫,后来变成了一只蝴蝶(根据age
的状态-它可以更精确或更复杂)。
class Butterfly implements FlyingGroundInsect {
private int age;
@Override
public boolean fly() {
if (!this.ableToFly())
throw new UnsupportedOperationException("Too early to fly");
return false;
}
@Override
public boolean walk() {
System.out.println("Walk method");
return true;
}
@Override
public boolean ableToFly() {
return this.age >= 28;
}
@Override
public boolean ableToWalk() {
return true;
}
}
https://stackoverflow.com/questions/52564762
复制相似问题