【发布时间】:2018-06-14 00:24:48
【问题描述】:
我以 Java 为例,但这更像是一个与 OOP 设计相关的一般问题。
让我们以 Java 中的IOExceptions 为例。例如,为什么会有 FileNotFoundException 类?这不应该是IOException 的一个实例,其中原因 是FileNotFound?我会说FileNotFoundException 是IOException 的一个实例。这在哪里结束? FileNotFoundButOnlyCheckedOnceException, FileNotFoundNoMatterHowHardITriedException..?
我还在我工作的项目中看到过代码,其中存在 FirstLineReader 和 LastLineReader 等类。对我来说,这样的类实际上代表了实例,但我在很多地方都看到了这样的设计。以 Spring Framework 源代码为例,它带有数百个这样的类,每次我看到一个类时,我看到的是一个实例而不是蓝图。类不就是蓝图吗?
我想问的是,如何在这两个非常简单的选项之间做出决定:
选项 1:
enum DogBreed {
Bulldog, Poodle;
}
class Dog {
DogBreed dogBreed;
public Dog(DogBreed dogBreed) {
this.dogBreed = dogBreed;
}
}
选项 2:
class Dog {}
class Bulldog extends Dog {
}
class Poodle extends Dog {
}
第一个选项要求调用者配置它正在创建的实例。在第二个选项中,该类已经代表了实例本身(如我所见,这可能是完全错误的......)。
如果您同意这些类代表实例而不是蓝图,您认为创建代表实例的类是一种好习惯还是我看待这个和我的陈述的方式完全错误“类代表实例” 只是一堆废话?
【问题讨论】:
-
您缺少的是,在选项 1 中,如果您希望 Bulldog 的行为与 Poodle 不同,您总是必须编写像
if( dogBreed == Bulldog) {} ...这样的代码,而在第二个中您可以覆盖方法。但仍然存在选项 1 非常适合的情况。只是不适用于问题中描述的语义。换句话说:选项 1 是“has-a”关系,而选项 2 是“is-a”关系。 -
顺便说一句:“我会说 FileNotFoundException 是 IOException 的一个实例” 它不是 instance 但它已经“是一个”,因为遗产。因此,如果您
catch(IOException ioe),您将捕获 FileNotFoundExceptions。 -
@Fildor 是的,也许我的例子不是一个好例子,但考虑到问题的其余部分,我认为它强化了我想问的问题。
-
让我们扭转局面:如果我听从您的建议,那么您将彻底消灭继承。任何类都只是一个带有字段的对象......因为最终任何类都只是“对象”类的一个“实例”......
-
@Fildor 是的,也许。我没有权利知道真的。只是想学习。也许答案很简单:
classes are sometimes instances really..