抽象基类与具体类作为超类

Ton*_*y D 12 c# java architecture design-patterns abstract-base-class

在阅读了最优秀的"Head First Design Patterns"一书之后,我开始向同事们传播模式和设计原则的好处.在颂扬我最喜欢的模式的优点 - 策略模式 - 我被问到一个让我停顿的问题.当然,策略使用继承和组合,当我的同事问"为什么使用抽象基类而不是具体的类?"时,我在其中一个关于"程序到接口(或超类型)而不是实现"的长篇大论. .
我只能提出"你强迫你的子类实现抽象方法并阻止它们实例化ABC".但说实话,这个问题让我想起了gaurd.

Ner*_*ury 22

如果需要实现特定方法,请使用接口.如果存在可以拉出的共享逻辑,请使用抽象基类.如果基本功能集完全独立,那么您可以使用concreate类作为基础.抽象基类和接口不能直接实例化,这是其中一个优点.如果您可以使用具体类型,那么您需要执行覆盖方法,并且它具有"代码味道".

  • 在不破坏某些隐含的行为合同的情况下,使用虚拟方法的代码将来更难以改变.所以在.NET中,他们认为制作一个可覆盖的方法必须是一个有意识的决定,应该仔细考虑.因此,没有实现者指令的任何可覆盖方法都是"代码味道". (5认同)
  • 如果你有一个班级,并且你以某种方式对行为进行编码.然后,从该类继承,并决定你要改变行为,IMO,有一种气味.我认为开发人员应该重构行为契约(接口或抽象基类)并创建两个具有明确定义原因的具体实现.拥有抽象基类或接口使得扩展在更改或替换行为方面更加明确.覆盖感觉更像是蛮力. (2认同)

Boz*_*zho 5

接口的程序,而不是实现与抽象和具体的类几乎没有关系.还记得模板方法模式吗?类,抽象或具体,是实现细节.

使用抽象类而不是具体类的原因是,您可以在不实现方法的情况下调用方法,而是将它们实现为子类.

面向接口编程是一个不同的东西-它是定义什么你的API呢,不是怎么它做它.这由接口表示.

注意一个关键区别 - 您可以拥有protected abstract方法,这意味着这是实现细节.但是所有接口方法都是公共的 - 这是API的一部分.