我有这个界面
public interface IColumn
{
bool IsVisible {get;set;}
bool IsGroupBy { get; set; }
Type CLRType { get; set; }
string GetGroupByString();
string GetFilterString();
}
并且我有从其继承的类,对于前3个属性,实现完全相同。
对于string GetGroupByString();
,除了2
所以我创建了一个名为ColumnBase
的抽象类,它继承了IColumn
接口并实现了所有成员并添加了支持字段,因为我需要实现INotifyPropertyChanged
。
并使我的类继承自ColumnBase,并且我确实覆盖了不一定相同的意图。
我对Interfaces和Abstract类的经验非常有限,我的问题是如果你有一个接口和一些将继承它的类,你意识到某些但不是所有属性和函数的实现是相同的,你创建一个抽象类并放置默认实现并将其覆盖在具有特殊实现的类中?
答案 0 :(得分:1)
您是否创建了一个抽象类并将默认实现覆盖在具有特殊实现的类中?
是的,我会完全这样做。实际上它是abstract
类和virtual / override
功能的目的。在你的情况下我认为你不需要IColumn
接口,你可以使用抽象类。并实现其中的所有常用方法,然后如果要更改方法的行为,请在嵌套类中覆盖它。
如果使用virtual
标记方法,则可以在嵌套类中覆盖它,并且可以根据当前类更改此方法的行为。您可能需要查看documentation更多细节。
答案 1 :(得分:1)
这将根据意见和偏好为您提供答案。
恕我直言,我认为这最适合抽象类,这两个方法要求将不同的实现声明为抽象方法;在方法上使用抽象意味着实现必须具有该方法的实现。
public abstract class ColumnBase
{
public bool IsVisible { get; set; }
public bool IsGroupBy { get; set; }
public Type CLRType { get; set; }
public virtual string GetGroupByString()
{
return "base string";
}
public abstract string GetFilterString();
}
public class ConcreteColumn : ColumnBase
{
public override string GetGroupByString()
{
return "concrete string";
}
public override string GetFilterString()
{
return "who owns the filter string?";
}
}
答案 2 :(得分:1)
如果派生类是基类的某个专用版本,那么从基类继承它是个好主意,比如class Rectangle : Shape
。这就是为什么派生类都是同一个东西的专用版本。例如,矩形和圆形实际上是一种形状。但是,如果您有不同的对象并且想要一些类似的行为,请考虑使用接口。例如,您可以序列化Bird
对象和Chair
对象,即使它们只有Name
和Age
属性,从它们派生出来也不是一个好主意具有Name
和Age
属性以及Serialize()
方法的基类,因为它们是不同的东西。虽然Serialize()
方法的实现在两者中都是相同的,但最好有一个ISerializable
接口并在两个类中实现它。