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,你对其中一个答案满意吗?如果没有,还缺少什么?