Почему экземпляр производного класса приводят к базовому абстрактному типу?

Говорят, что экземпляр производного класса, наследующийся от абстрактного (класса, интерфейса), принято приводить к базовому типу. Почти всегда.
Часто это объясняют тем, что так мы показываем суть нашего объекта.
Пример

Файл Interface1.cs
namespace Interfaces
{
interface Interface1
{
void Method1();
}
}


Файл Interface2.cs
namespace Interfaces
{
interface Interface2
{
void Method2();
}
}


Файл Program.cs
namespace Interfaces
{

class Program
{

class DerivedClass : Interface1, Interface2
{
public void Method1(){Console.WriteLine("Реализация Method1 из Interface1");}
public void Method2(){Console.WriteLine("Реализация Method2 из Interface2");}
}

static void Main()
{
Interface1 instance1 = new  DerivedClass();
Interface2 instance2 = new  DerivedClass();
//DerivedClass instance = new  DerivedClass();

instance1.Method1();
//instance1.Method2(); нельзя

instance2.Method2();
//instance1.Method1(); нельзя

Console.ReadKey(); 
}
}
}


В коде выше, из за приведения к базовому абстрактному типу, мы вынуждены создавать 2 экземпляра класса.
Что далее частично ограничивает наши возможности (вызов методов).

Если не приводить к базовому типу то: нам понадобится 1 экземпляр класса. Мы сможем вызывать 2 метода на 1 экземпляре класса. Не нужна "лишняя" операция приведения (апкаст).

Неужели реализация не показывает сути объекта? (Ведь это тоже объект.)
И поэтому мы должны делать апкаст, писать больше кода и вводить для себя ограничения?

Почему экземпляр производного класса приводят к базовому абстрактному типу?
  • Вопрос задан
  • 132 просмотра
Решения вопроса 3
@vabka Куратор тега C#
Токсичный

Говорят, что экземпляр производного класса, наследующийся от абстрактного (класса, интерфейса), принято приводить к базовому типу. Почти всегда.

Ни разу о таком не слышал. Мне кажется, это какой-то бред сумасшедшего, который ни разу не написал ни одной строчки кода.

На C# очень многие используют стиль VIP (var if possible), в таком стиле ваш код будет выглядеть так:
var instance = new  DerivedClass();
instance.Method1(); // Красиво, компактно, никаких проблем.
instance.Method2();


В коде выше, из за приведения к базовому абстрактному типу, мы вынуждены создавать 2 экземпляра класса.

Нет. Можно написать так:
DerivedClass instance= new DerivedClass(); // только 1 экземпляр
Interface1 instance1 = instance; // Но всё равно очень громоздко.
Interface2 instance2 = instance;


Не нужна "лишняя" операция приведения (апкаст).

Апкаст - это бесплатная операция.

Единтвенный лучай, когда нужно приводить класс к интерфейсу - это явная реализация интерфейса (без апкаста тупо не получится вызвать его методы)
PS: простой код лучше сложного.
Ответ написан
Griboks
@Griboks Куратор тега C#
Интерфейсы используются для организации взаимодействия между модулями. Модулю нет дела до реализации, ему важно лишь наличие определенных сигнатур. Поэтому он использует базовый тип интерфейса, необходимый только для работы модуля. Все остальное его не волнует.

Простой пример
IEnumerable<T> For(this IEnumerable<T> query, Action<T> action) {
foreach(var item in query) action(item) ;
return query;}


Тут нам наплевать на истинный класc запроса, нам важна лишь итерируемость. С программной точки зрения мы приводим массив, список, очередь.... к базе.
Ответ написан
mindtester
@mindtester Куратор тега C#
https://youtu.be/UtO6HIp1908?list=RDUtO6HIp1908
приведение к базовому типу имеет только один рациональный смысл - это дать возможность передавать различных потомков точка
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы