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 dog
和instanceOf lion
的情况下,我将如何确保它可以执行任何动物。
这个问题是不切实际的(实际上是在其中一次采访中被问到我),因为你不会传递类型猫(比如我们还有一个接口)来输入狗。
但是,如果我们这样做:
a.fight(b);
并希望它能正常运作。
采访者暗示这与设计模式有关。 我真的不确定这是否会产生建设性的问题。
答案 0 :(得分:2)
我不确定通过暗示这与设计模式有关而采访你的人是什么意思。如果我正确理解了这个问题,它与设计模式无关。此外,您的代码已经按照您的意愿行事:任何实现的东西动物将能够对抗任何其他类型的实施动物的东西。这就是你想要的,对吧?你已经在那里了。您所要做的就是进行一些修正以使其编译(战斗方法需要返回类型,如void)。
由于fight
中的Animal
方法将另一个Animal
作为参数,因此扩展Animal
(Cat
,Dog
的所有内容也会如此,Duck
,Goose
,Lion
,Tiger
,Bear
,哦,我的!) - 你写的方式,它已经达到你的目标。战斗方法并不关心它是什么类型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);
}