st4rdog
Создание абстрактного класса позволяет использовать абстрактные функции. Абстрактные функции позволяют гарантировать, что дочерние/подклассы будут иметь эти функции на них. Абстрактный класс не будет инстанцируемым (не может существовать "в мире").
Пример:
public abstract class Dog
не может существовать через
Dog dog = new Dog()
но это подкласс
public class GreatDane : Dog
может существовать в мире.
GreatDane greatDane = new GreatDane()
Почему? Нет смысла создавать в мире родовую "собаку". Будучи абстрактным, оно перестает быть созданным. Он также позволяет вам иметь абстрактные шаблоны функций/заглушки, которые должны иметь все дочерние/подклассы.
public abstract class Dog
{
public abstract void Bark(); // Note there is no code/implementation. I am just telling my children to have this function on them.
}
public class GreatDane : Dog
{
public override void Bark()
{
// Unique bark like a Great Dane
}
}
Почему бы не использовать такой интерфейс, как IBarkable?
Вы могли бы, но наличие базового класса "собака" допускает общее/общее поведение. У вас могут быть обычные функции, виртуальные функции или абстрактные функции.
Например, если 90% собак лают одинаково, вы можете сделать Bark() виртуальным, поэтому существует реализация default/shared/common.
public abstract class Dog // Abstract so it can't be instantiated, even though there are no abstract functions
{
public virtual void Bark()
{
// Default (but overridable) barking code. Some dogs use this code.
}
public void WagTail()
{
// Only code that exists to wag tail. All dogs use this code.
}
}
public class GreatDane : Dog
{
// I will be lazy and use the base class's Bark()
}
public class Rottweiler : Dog
{
public override void Bark()
{
// I will use this unique bark.
}
}
С интерфейсами каждый Bark() был бы уникален, что привело бы к копированию и вставке кода.