OriginalGriff
Абстрактные классы и интерфейсы очень различны и не могут быть заменены.
Мы используем абстрактные классы, чтобы обеспечить общую базу для конкретных классов - что не так уж много значит, но думайте об этом как о машинах.
Все автомобили являются членами абстрактного класса Car - они имеют общие свойства и методы, в которых вы можете научиться управлять автомобилем и применить это к любому экземпляру производного класса.
Но вы не можете управлять автомобилем - вы управляете "этой машиной" или "той машиной", "вашей машиной" или "моей машиной" - которые являются экземплярами автомобиля, но что более важно, "MyCar" - это конкретный экземпляр марки и модели: "Mercedes"."класс", в то время как "YourCar" - это конкретный экземпляр "Ford"."Feista"
Модель "А-класс" - это класс, производный от "Мерседеса", который происходит от "автомобиля". "Автомобиль" абстрактен, как и "Мерседес" и "Форд", но реальные модели конкретны: "а-класс", "Фиеста". Класс автомобилей предоставляет основы метода "драйв", но "Мерседес" уточняет, в какой гараж вам нужно зайти, чтобы купить его, - он добавляет коллекцию имущества "дилерского центра". "Класс а" уточняет "Мерседес" далее, говоря: "он такой длинный, такой широкий, имеет один из этих двигателей" и так далее.
Вы не можете купить "Мерседес" - это абстрактное понятие, - но вы можете купить "класс а", потому что это определяет, какие опции доступны в качестве экземпляра автомобиля.
Но ведь это все машины!
В то время как вы можете сделать это с неабстрактными классами, просто используя наследование, конкретный класс автомобиля означает, что вы можете сделать это:
Car myCar = new Car();
А что именно вы получаете в "микаре"? Какие части ему нужны? Какое топливо он использует? Какого размера это шины? Поскольку это "автомобиль", у вас нет никакой информации об этом или где-либо ее хранить.
Интерфейсы бывают разные: это вовсе не классы - это контракт. Вы не можете иметь никакого кода вообще в интерфейсе (в отличие от абстрактного класса, где вы можете), но вы должны реализовать каждый метод, свойство, событие и делегат, которые определены в интерфейсе. Если вы этого не сделаете, вы получите ошибку. Если вы это сделаете, то получите преимущества "пребывания в клубе", которые дает вам контракт интерфейса.
Например, посмотрите на интерфейс IEnumerable - добавление его к любому классу (и реализация методов) позволяет использовать ваш класс непосредственно в
foreach
петля. Только те, которые реализуют контракт IEnumerable, могут быть использованы с
foreach
, но все, что делает, может быть - независимо от базового класса, из которого они происходят. А поскольку вы можете получить только один класс (В C# нет множественного наследования!), отсутствие интерфейсов значительно ограничит то, что вы можете сделать с IEnumerable.