Java中从Caterpillar到Butterfly的模型
我最近在一次采访中被问到这个问题: 随时间改变行为的动物模型Java中从Caterpillar到Butterfly的模型,java,oop,inheritance,interface,model,Java,Oop,Inheritance,Interface,Model,我最近在一次采访中被问到这个问题: 随时间改变行为的动物模型 你会做蝴蝶模型吗 蝴蝶会飞,蝴蝶不会发出声音 你能优化你的模型来解释从毛虫到蝴蝶的蜕变吗 毛毛虫不能飞 毛毛虫会走路(爬行) 我创建了一个具有顶级接口(昆虫)的层次结构,该接口有两个扩展接口(地面昆虫&FlyingSect)。然后我有了Caterpillar执行groundfest和ButterFly执行flyingsect。然而,我无法为变形部分想出解决方案。下面是我的代码: 昆虫界面: public interface I
- 蝴蝶会飞,蝴蝶不会发出声音
- 毛毛虫不能飞
- 毛毛虫会走路(爬行)
昆虫
)的层次结构,该接口有两个扩展接口(地面昆虫
&FlyingSect
)。然后我有了Caterpillar
执行groundfest
和ButterFly
执行flyingsect
。然而,我无法为变形部分想出解决方案。下面是我的代码:
昆虫界面:
public interface Insect { }
public interface FlyingInsect extends Insect {
public boolean fly();
}
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;
}
}
FlyingSect界面:
public interface Insect { }
public interface FlyingInsect extends Insect {
public boolean fly();
}
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;
}
}
地面昆虫界面:
public interface Insect { }
public interface FlyingInsect extends Insect {
public boolean fly();
}
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;
}
}
Caterpillar类别:
public interface Insect { }
public interface FlyingInsect extends Insect {
public boolean fly();
}
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;
}
}
蝴蝶类:
public class Butterfly implements FlyingInsect {
@Override
public boolean fly() {
System.out.println("ButterFly Flying method");
return false;
}
}
一种方法是添加结合两个接口的第三个契约。这是因为我相信无论是蝴蝶还是毛毛虫,都应该是相同的昆虫 以下是一个专门的合同,其中添加了
不支持操作例外
,作为一个选项:
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();
}
这一类是蝴蝶类昆虫,它被理解为代表一种昆虫,最初是毛毛虫,后来变成蝴蝶(根据年龄状态-它可以更精确或更复杂)
真是个有趣的问题。我喜欢你创建界面地面昆虫
和FlyingSect
,但我会将昆虫
声明为一个抽象类,以及蝴蝶
,其子类将是蝴蝶(包括毛毛虫和成年蝴蝶)的发育阶段。无论如何,我没有写下所有的关系,这会让人困惑,而是画了一张图表。请看下面:
至于变态部分,我声明了一个名为变态
(请原谅这个奇怪的名字,但我想不出更好的方法!)的新接口,其中包含一个处理昆虫变态的方法。此外,Chrysalis
和AdultButterfly
的构造器接收到前一个开发阶段的实例作为参数。请参见下面的我的代码:
昆虫种类:
蝴蝶类:
可变形界面:
class Butterfly implements Insect {
boolean fly() { return true; }
boolean walk() { return true; }
boolean sound() { return false; }
}
让我们保持示例的简单性,并坚持您最初的方法
首先,我将介绍一个描述各种昆虫的通用界面:
interface Insect {
boolean fly();
boolean walk();
boolean 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
实现了与外部类相同的昆虫
接口。一般情况下,我可能会为内部状态定义一个不同的接口。很有趣。你认为当前昆虫的生命是一个<代码>状态<代码>吗?我可能会尝试使用状态设计模式。我很好奇其他人怎么想。你用毛毛虫“制造”一只蝴蝶,所以建模的一种方法是用c毛毛虫建造一只蝴蝶:新蝴蝶(毛毛虫)
。或者用一只Butterfly
执行flyingsect
和groundthread
并随着年龄的增长改变它的行为。@c0我认为你不是靠一只蝴蝶,而是靠自己,我更愿意看到这一点different@Sameervb,你对其中一个答案满意吗?如果没有,还缺少什么?