多态的想法听起来很棒。在现实生活中,有人加入了一个新项目并开始研究这个代码:
class Tom extends Cat implements Male {
temperature temperature = Tom.getTemperature();
..............
class Cat extends Feline{
..............
class Feline extends Mammals{
..............
class Mammals extends Animals implements WarmBlooded{
.......
interface WarmBlooded{
int temperature=96; //In case they forget to set the right temperature...
public int getTemperature(){
return temperature;
}
与
比较Cat cat = new Cat(Tom, m, 96);
和
class Cat(Stiing name, char gender, int temperature){
....
}
当然,我们通过实施WarmBlooded
保存了几行代码,但代价是什么?我们必须查看多个类才能找出getTemperature()
正在做什么 - 这不是意大利面条代码的一个例子吗?数百万编程人员选择了Java。必须有多态性的原因。无论如何,我必须记住我正在创造的猫的名字,性别和温度。实施Male
与传递" m"没有什么不同。作为创建Tom时的参数。为什么不捆绑Cat
中的所有内容?
这是否意味着我应该阅读并理解整个项目开始受益于多态?是否有任何方法可以更轻松地浏览扩展/实现?
有效浏览扩展/实现意味着什么?
这意味着"可以在合理的时间内找出这种方法正在做什么"。
答案 0 :(得分:1)
使用IDE。例如NetBeans或Eclipse。另外,使用UML。否则很难遵循代码。它允许您单击getTemperature()以查看实现。
Class Feline is useless if it only holds
Boolean isFeline = true;
然而,如果它有多种方法,它可以让生活更轻松 - 你不必记住所有这些方法。
Java最适合大型项目。加入这些项目可能会更加困难。
答案 1 :(得分:1)
首先:WarmBlooded
是一个抽象类;你应该extend
,而不是implement
。
继承和多态的要点是创建一个更容易扩展的项目。如果您发现自己只是为了这样做而创建父类和接口,那么是的,这是意大利面条代码。
但是当一个项目涉及许多不同的类别(在你的例子中,动物),然后有一个预定义的合同,动物必须履行或已经实施的行为非常有用,因为它:
eat()
方法getTemperature
,你更容易出错 - 如果你想改变行为,你必须在几个地方改变它。 / LI>
醇>
正如其他人所说,一个好的IDE(甚至熟悉你的文本编辑器)使得使用这个范例变得相当容易。
答案 2 :(得分:1)
你所描述的是继承之初的经典继承(动物,猫,狗)。但是,继承并不适合所有方面,例如你的多态性。
替代方案:
interface Swimming {
double getSwimmingSpeed();
void swim();
}
interface Flying {
void fly();
}
class Animal {
public <T> Optional<T> lookup(Class<T> type);
}
// Class or instance:
Animal pelikan = ...
Optional<Swimming> swimming = pelikan.lookup(Swimming.class);
swimming.ifPresent(::swim);
Animal flyingFish = ...
Optional<Flying> flying = flyingFish.lookup(Flying.class);
// lookup might use a Map<Class<?>, ?>.
此方法使用发现机制来查找功能和功能。这比上面的多态更好,实现了几个接口,因为它解耦了类,并且可以重用实现代码(类)。
然而,它也隐藏了这些功能,因为它们是动态的。通过阅读课程,你不会知道有些鱼可以飞。
但最重要的是,它可以减少仅存在以表示具有不同功能的实例的类的数量。通常不需要一个单独的类FlyingFish,带有一些特定的构造函数。