Интерфейс, абстрактные или просто виртуальные методы?
У меня есть куча систем, назовем их A, B, C, D, E, F, G, H, I, J
.
GetPropertyInformation()
, который определен для каждой системы. Я пытаюсь выяснить, какой метод был бы лучшим подходом для уменьшения дубликата кода, или, возможно, один из методов ниже не является способом go:
Интерфейс
public Interface ISystem
{
public void GetPropertyInformation();
//Other methods to implement
}
public class A : ISystem
{
public void GetPropertyInformation()
{
//Code here
}
}
Аннотация
public abstract class System
{
public virtual void GetPropertyInformation()
{
//Standard Code here
}
}
public class B : System
{
public override void GetPropertyInformation()
{
//B specific code here
}
}
Виртуальные методы в Супербазисном классе
public class System
{
public virtual void GetPropertyInformation()
{
//System Code
}
}
public class C : System
{
public override void GetPropertyInformation()
{
//C Code
}
}
Один вопрос, хотя это может быть глупо, давайте предположим, что я пошел с абстрактным подходом, и я хотел переопределить GetPropertyInformation
, но мне нужно было передать ему дополнительный параметр, возможно ли это или мне придется создать другой метод в абстрактном классе? Например, GetPropertyInformation(x)
6 ответов:
Ваш абстрактный и "супербазисный" подходы не слишком отличаются. Вы всегда должны делать базовый класс абстрактным, и вы можете предоставить реализацию по умолчанию (виртуальные методы) или нет (абстрактные методы). Решающим фактором является то, хотите ли вы когда-нибудь иметь экземпляры базового класса, я думаю, что нет.
Так что это между базовым классом и интерфейсом. Если существует сильная связь между вашими классами A, B C, то вы можете использовать базовый класс и, вероятно, общую реализацию.
Если классы A, B, C естественным образом не принадлежат к одному "семейству", то используйте интерфейс.
И
System
- не такое уж хорошее имя.И вы не можете изменить список параметров при переопределении. Возможно, параметры по умолчанию могут помочь, в противном случае вам просто нужно 2 перегрузки для GetPropertyInformation().
Обычно вы выбираете наследование объектов, когда хотите совместно использовать реализацию и уменьшить то, что в противном случае было бы дублированием. В противном случае интерфейсы выигрывают, потому что они более гибкие, так как нет необходимости в общем базовом классе.
Что касается переопределения метода и изменения списка параметров, то это просто невозможно. Представьте себе, как бы вы вызвали этот метод в базовом классе или ссылке на интерфейс?
Я бы выбрал что-то вроде того, что я добавил ниже. Вы по-прежнему получаете выгоду от контракта интерфейса и совместной реализации.
public Interface ISystem { public void GetPropertyInformation(); //Other methods to implement } public abstract class System : ISystem { public virtual void GetPropertyInformation() { //Standard Code here } } public class B : System { public string ExtendedSystemProp {get;set;} public override void GetPropertyInformation() { base.GetPropertyInformation(); var prop = "some extra calculating"; GetExtraPropertyInformation(prop); } public void GetExtraPropertyInformation(string prop) { ExtendedSystemProp = prop; } } ISystem genericSystem = new B(); genericSystem.GetPropertyInformation(); (genericSystem as B).ExtendedSystemProp = "value";
Вы не можете передать дополнительный параметр в переопределении. Когда вы переопределяете, вы переопределяете метод с точной сигнатурой. Я бы предложил вам передать параметр интерфейса, такой как
IPropertyInformation
, который может изменяться в каждой реализации.Решение использовать базовый класс или интерфейс для вашей реализации действительно зависит от вашего использования. Имеют ли
A-I
достаточно общего друг с другом, чтобы все они действительно были производными от одного и того же базового класса? Если да, то используйте базовый класс. Является это действительно то, что простоGetPropertyInformation
является общим, а в остальном системы полностью функционально различны? Тогда вы действительно просто хотите, чтобы у них был общий интерфейс.
Другие рассмотрели то, что было первоначально в моем ответе, но о пункте "Добавление параметра": не забывайте, что последний C# также позволяет вам иметь необязательные параметры в методах.
Если у вас нет веской причины иначе, я бы пошел с интерфейсом. Общедоступные виртуальные методы, хотя и сделаны много, не идеальны .