They are certainly similar and many things can be accomplished by using both.
Consider following classes:
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);
}
}
This sample uses abstract base class for providing some common properties while allowing derived classes to declare their own properties too. The solution enforces derived classes to implement DisplayData() method that shows the contents of the class to outside world - as they please of course.
Testing out the code:
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());
Gives following output:
Name:Joanne Age:13 Health record: BFF:Julia
Name:Mike Age:53 Health record:2003 - Heart Bypass
The options to work with abstract classes are limitless and I certainly think of them as more versatile as interfaces. The disadvantage with abstract classes of course is that since C# doesn't have multi-inheritance then your one shot at inheritance is already used with an abstract class.
PS: Just notices that my age calculation sucks, might be better off using timespan. :)