它们当然是相似的,并且可以通过使用两者来完成许多事情。
考虑以下课程:
public abstract class PersonBase
{
public string Name { get; set; }
public DateTime BirthDate { get; set; }
public PersonBase(string name, DateTime bd)
{
this.Name = name;
this.BirthDate = bd;
}
public int CalculateAge()
{
return DateTime.Now.Year - BirthDate.Year;
}
public abstract string HealthRecord { get; set; }
public abstract string DisplayData();
}
public class TeenagerPerson : PersonBase
{
public PersonBase BestFriendForever { get; set; }
public override string HealthRecord { get; set; }
public TeenagerPerson(string name, DateTime bd)
: base(name, bd)
{
}
public override string DisplayData()
{
return string.Format("Name:{0} Age:{1} Health record:{2} BFF:{3}", Name, CalculateAge(), HealthRecord, BestFriendForever.Name);
}
}
public class AdultPerson : PersonBase
{
public override string HealthRecord { get; set; }
public AdultPerson(string name, DateTime bd)
: base(name, bd)
{
}
public override string DisplayData()
{
return string.Format("Name:{0} Age:{1} Health record:{2}", Name, CalculateAge(), HealthRecord);
}
}
该示例使用抽象基类来提供一些通用属性,同时允许派生类声明自己的属性。该解决方案强制派生类实现 DisplayData() 方法,该方法将类的内容显示给外部世界 - 当然是他们喜欢的。
测试代码:
var teenager = new TeenagerPerson("Joanne", new DateTime(2000, 11, 05));
teenager.BestFriendForever = new TeenagerPerson("Julia", new DateTime(2000, 10, 05));
Console.WriteLine(teenager.DisplayData());
var adult = new AdultPerson("Mike", new DateTime(1960, 01, 03));
adult.HealthRecord = "2003 - Heart Bypass";
Console.WriteLine(adult.DisplayData());
给出以下输出:
姓名:Joanne 年龄:13 健康记录:BFF:Julia
姓名:迈克 年龄:53 健康记录:2003 - 心脏搭桥
使用抽象类的选项是无限的,我当然认为它们与接口一样通用。抽象类的缺点当然是,由于 C# 没有多重继承,因此您的一次继承已经与抽象类一起使用。
PS:只是注意到我的年龄计算很糟糕,使用时间跨度可能会更好。:)