DO NOT define public or protected-internal constructors in
abstract types.
Constructors should be public only if users will need to create instances of
the type. Because you cannot create instances of an abstract type, an abstract
type with a public constructor is incorrectly designed and misleading to the
users.2
// bad design
public abstract class Claim {
public Claim (int number) {
}
}
// good design
public abstract class Claim {
// incorrect Design
protected Claim (int number) {
}
}
DO define a protected or an internal constructor on abstract
classes.
A protected constructor is more common and simply allows the base class to do
its own initialization when subtypes are created.
public abstract class Claim {
protected Claim() {
}
}
An internal constructor can be used to limit concrete implementations of the
abstract class to the assembly defining the class.
public abstract class Claim {
internal Claim() {
}
}
BRAD ABRAMS
Many languages (such as C#) will insert a
protected constructor if you do not. It is a good practice to define the
constructor explicitly in the source so that it can be more easily documented
and maintained over time.
DO provide at least one concrete type that inherits from
each abstract class that you ship.
This helps to validate the design of the abstract class. For example,
System.IO.FileStream is an implementation of the System.IO.Stream abstract
class.
BRAD ABRAMS
I have seen countless examples of a
"well-designed" base class or interface where the designers spent
hundreds of hours debating and tweaking the design only to have it blown out of
the water when the first real-world client came to use the design. Far too often
these real-world clients come too late in the product cycle to allow time for
the correct fix. Forcing yourself to provide at least one concrete
implementation reduces the chances of finding a new problem late in the product
cycle.