如何在设计模式的帮助下使用继承

时间:2015-02-19 15:08:24

标签: java inheritance

public interface Animal{
    public fight(Animal a){
    }  
}

//this interface is not accessible but exists somewhere in some other package and we are unaware about its exact location 
public class Tiger implements Animal{
    public fight(Animal a){
    } 
} 

//this interface is not accessible but exists somewhere in some other package and we are unaware about its exact location
public class Lion implements Animal{
    public fight(Animal a){
    }
} 

public testClass{
    public static void main(String[] args){
        Animal a = factoryMethodToReturnTigerObject();//because we don't know how to create object directly.
        Animal b = factoryMethodToReturnLionObject();
    }
}

我如何概括为虎内任何动物制作战斗的实施? 由于a.fight(animal)不仅接受狗类型,还接受动物类型。 在不使用instanceOf doginstanceOf lion的情况下,我将如何确保它可以执行任何动物。

这个问题是不切实际的(实际上是在其中一次采访中被问到我),因为你不会传递类型猫(比如我们还有一个接口)来输入狗。

但是,如果我们这样做: a.fight(b);并希望它能正常运作。

采访者暗示这与设计模式有关。 我真的不确定这是否会产生建设性的问题。

3 个答案:

答案 0 :(得分:2)

我不确定通过暗示这与设计模式有关而采访你的人是什么意思。如果我正确理解了这个问题,它与设计模式无关。此外,您的代码已经按照您的意愿行事:任何实现的东西动物将能够对抗任何其他类型的实施动物的东西。这就是你想要的,对吧?你已经在那里了。您所要做的就是进行一些修正以使其编译(战斗方法需要返回类型,如void)。

由于fight中的Animal方法将另一个Animal作为参数,因此扩展AnimalCatDog的所有内容也会如此,DuckGooseLionTigerBear,哦,我的!) - 你写的方式,它已经达到你的目标。战斗方法并不关心它是什么类型Animal,只要它是Animal

public interface Animal {
    void fight(Animal otherAnimal);
}

public class Tiger implements Animal {
    @Override
    public void fight(Animal otherAnimal) {
        //Do Stuff
    } 
} 

public class Lion implements Animal {
    @Override
    public fight(Animal otherAnimal) {
       //Do Stuff
    }
} 

public class Dog implements Animal {
    @Override
    public fight(Animal otherAnimal) {
       //Do Stuff
    }
} 

public class TestClass{
    public static void main(String[] args){
        Animal a = factoryMethodToReturnTigerObject();
        Animal b = factoryMethodToReturnLionObject();
        a.fight(b); // This works
        b.fight(a); // This also works

        Dog dog = factoryMethodToReturnDogObject();
        Tiger tiger = factoryMethodToReturnTigerObject();
        dog.fight(tiger); // This works.
        tiger.fight(dog); // This also works.  You're good to go!

    }
}

事实上,如果你想要反过来那么动物只能与其他类型的动物搏斗,你就不得不走开,并使用这样的仿制药:

动物

public interface Animal<A extends Animal<A>> {
    void fight(A otherAnimal);
}

虎:

public class Tiger implements Animal<Tiger>{
    @Override
    public void fight(Tiger otherAnimal) {
        //Do Stuff
    } 
}

狮子:

public class Lion implements Animal<Lion> {
    @Override
    public void fight(Lion otherLion) {
        //Do Stuff
    }
}

答案 1 :(得分:1)

这是一个例子的设计模式是编程到接口。这允许您将代码分成不同的层,这些接口的使用者不需要知道任何实际的实现(因为它不应该关心)。这种理念开启的重点是依赖注入

您正在编写的代码将具有接口知识。然后你可以拥有一个完全不同的项目,其中包含这些接口的具体实现。它们在哪里或它们的作用并不重要。您的所有代码都需要知道的是,无论对象是什么,都知道如何使用它来做你需要的东西。

在您的示例中,您不会像在那里Main那样设置它。它更像是这样的东西:

public class RumbleInTheJungle {
    public Animal Match(Animal animal1, Animal animal2) {
        animal1.fight(animal2);
    }
}

public testClass{
    public static void main(String[] args){
        Tiger tiger = new Tiger();
        Lion lion = new Lion();
        RumbleInTheJungle jungle = new RumbleInTheJungle();

        Animal winner = jungle.Match(tiger, lion);
    }
}

这是一个高度简化的示例,但希望能帮助您了解更多。我没有设置任何依赖注入,因为我不确定它是如何用Java完成的,但这并不是理解模式所必需的。

答案 2 :(得分:0)

这应该有效:

public interface Animal {
    public <T extends Animal> fight(T a);
}