可重用库的“抽象类”与“普通类”

时间:2010-05-11 02:18:08

标签: c# .net abstract-class base-class

我正在开发一个可重用的库并且一直在创建抽象类,因此客户端可以从这些扩展。

问题:有没有理由我应该在这里使用抽象类而不仅仅是普通类?

注意 - 已经决定我不想使用接口,因为我想在我的库中包含实际的默认方法,因此使用它的客户端不必编写代码。

编辑:所以我正在捕捉任何我想不到的优势。例如,当升级库时,会使用抽象类减少对客户端代码的影响 - 在这种情况下,我看不到它会不会?

4 个答案:

答案 0 :(得分:3)

抽象类的动机是要求客户端覆盖该类。您对该类是否应该是抽象的决定主要取决于摘要是否缺少一些只有该类用户才能提供的基本行为。

如果你使用某种类型的模板方法,你通常可以告诉你需要你的类是抽象的,其中“插入这种行为的漏洞”完成了他的类的逻辑。如果您的类在没有用户提供的逻辑的情况下很有用,那么您可能不需要该类是抽象的。

作为一个例子,框架通常不能代表用户在对象状态验证,打印,显示等方面做出决策,他们需要遵循客户的具体实现。 / p>

答案 1 :(得分:2)

除非您想强制最终用户继承您的类,否则没有理由使用 abstract

如果要使类可继承且易于扩展,请在方法上使用虚拟,并确保您具有可用的 protected 构造函数。

答案 2 :(得分:1)

抽象类和非抽象类之间的区别在于,您无法实例化前者,必须覆盖它。您可以自行决定基类的实例是否有意义。

让我告诉你两个案例。一个是抽象类有意义的地方,另一个是没有的地方。

public abstract class Animal {
  public string Name {get;set;}
}

public class Dog : Animal {
  public Bark(){}
}

public class Cat : Animal {
  public Meaow(){}
}

在这种情况下,我们有一个公共基础Animal,它为Name属性提供了实现。将动物本身实例化是没有意义的,因为世界上没有动物只是动物,它们是枯萎的狗或猫或其他东西。

这是一个有非抽象基础的情况。

class Path {
  public Path(IList<Point> points) {
    this.Points = new ReadOnlyCollection<Point>(points);
  }
  public ReadOnlyCollection<Point> Points {get;}
}

class RectanglePath : Path{
  public SquarePath (Point origin, int height, int width) : 
   base(new List<Point>{origin, new Point(origin.X + width, point.Y}, ....){

  }
}

这里没有子类化的路径是有道理的,我们可以创建任意形状,但是使用子类来获得更具体的形状可能会更方便。

答案 3 :(得分:1)

听起来你对虚拟方法和抽象类之间的区别有点困惑。除非您确定它本身没有意义,否则您不需要将您的类标记为抽象类。这在您可能在多个类之间共享行为的区域中非常有用。

听起来像你只需要一个普通的课程和一些虚拟的方法。