2009-03-02 122 views

回答

37

这取决于,如果你永远不希望能够实例化基类然后使其抽象。否则,请将其作为普通课程。

+1

确切地说,如果实例化基类没有意义,请将其抽象化。 – mbillard 2009-03-02 19:53:24

0

我会说如果你不打算自己调用基类,那么你应该把它定义为一个抽象类。

+0

我想说这还不够 - 如果直接实例化它是没有意义的,那么应该只声明一个类抽象。无论你是否打算是一个完全不同的问题。 – 2009-03-02 19:39:37

0

这取决于您是否希望基类自行实现。

作为一个抽象类,您无法从中创建对象。

6

这取决于它是否有意义的基础类有问题存在它自己而不是从派生?如果答案是肯定的,那么它应该是一个普通类,否则它应该是一个抽象类。

16

如果不应该实例化基类,那么将其设为抽象类 - 如果基类需要实例化,则不要将其抽象化。

在这个例子中是有意义的使基类的抽象基类没有任何具体的含义:

abstract class WritingImplement 
{ 
    public abstract void Write(); 
} 

class Pencil : WritingImplement 
{ 
    public override void Write() { } 
} 

然而,在接下来的例子中可以看到基类如何确实有具体的含义:

class Dog 
{ 
    public virtual void Bark() { } 
} 

class GoldenRetriever : Dog 
{ 
    public override void Bark() { } 
} 

这真的很主观 - 你应该能够根据你的特定领域的需求做出一个很好的判断呼叫。

0

抽象类对于预定义的功能非常适用,例如 - 知道类应该暴露的最小确切行为,但不知道应该使用哪些数据来执行它或确切的实现。

abstract class ADataAccess 
{ 
    abstract public void Save(); 
} 

正常(非抽象)类可以是伟大的类似的事情,但你必须知道的实现细节,能够给他们写。另外,您可以使用接口(单独或在类上,不论是否抽象)来定义相同类型的原型定义。

interface ISaveable 
{ 
    void Save(); 
    void Insert(); 
    void Update(); 
} 

class UserAccount : ISavable 
{ 
    void ISavable.Save() { ... } 
    void ISavable.Insert() { ... } 
    void ISavable.Update() { ... } 
} 

另一个选择,可以使用泛型

class GenDataAccess<T> 
{ 
    public void Save() 
    { 
     ... 
    } 
} 

所有这些方法都可以用来定义一个特定原型的类一起工作。如何确保代码A可以与代码B交谈。当然,您可以根据自己的喜好混合和匹配上述所有内容。没有确定的正确方法,但我喜欢定义接口和抽象类,然后引用接口。通过这种方式,可以在保持最大灵活性的同时,消除高层次中“管道”的一些思想要求。 (具有接口不需要使用抽象基类的要求,但将其作为选项)。

1

抽象类用于部分实现的类。

本身没有意义,有一个抽象类的实例,它需要派生。如果你想能够创建基类,它不能是抽象的。

我喜欢将抽象类视为接口,它有一些预定义的成员,因为它们对所有子类都是通用的。

1

想到这一种不同的方式

我是一个基类,它自己的一个完整的对象?

如果答案是否定的,则将其抽象化。如果是的话,那么你可能想把它变成一个具体的课程。

3

我建议:

  • 将界面。
  • 在您的基类中实现接口。
  • 使基类成为真正的类,而不是抽象的(请参阅下面的原因)。

我比较喜欢的,而不是抽象类真正的类的原因是抽象类不能被实例化,从而限制未来的选择不必要。例如,稍后我可能需要基类提供的状态和方法,但不能继承并且不需要实现接口;如果基类是抽象的,我运气不好,但如果基类是普通类,那么我可以创建一个基类的实例,并将其作为其他类的组件,并委派给实例以重用状态/方法提供。

是的,这并不经常发生,但重点是:当没有理由这样做时,使基类抽象防止这种重用/解决方案。

现在,如果实例化基类会以某种方式是危险的,然后使它抽象的 - 或者最好使它不那么危险,如果有可能;-)

3

认为像银行账户:

你可以创建一个名为“账户”的通用抽象基础账户,该账户拥有诸如客户详细信息等基本信息。

然后,您可以创建两个名为“SavingAccount”或“DebitAccount”的派生类,它们可以具有自己的特定行为,同时受益于基类行为。

这是一种客户必须拥有储蓄账户或借记账户的情况,不允许使用通用的“账户”,因为它在现实世界中不是非常受欢迎,只有账户没有描述。

如果您可以根据自己的需求创建类似的场景,那么摘要就是要走的路。

-8

我想很多人应该重新学习基本的OO课程。

OOA/OOD中的基本原理是抽象抽象抽象,直到你不能抽象。如果你看到的是一个抽象,那就这样吧,那就是你的OOA/OOD已经告诉你的。然而,如果你坐在那里想知道“代码”是否应该是抽象的,那么你显然不知道这个术语是什么意思,并应该再次学习基本的OOA/OOD/OOP :-)

更重要的是,你应该学习设计模式和谐波理论,这将非常有助于您的OO设计!

+8

我可以告诉你做了很多的阅读。花些精力去学习如何写作而不会冒犯他人。 – 2011-03-31 00:13:06