定义接口,在基本抽象类中实现接口,给它默认行为然后从基类继承是不错的做法?
或者那太过分了?
答案 0 :(得分:4)
是使用接口还是抽象类是两个完全不同的问题。可能会发生两者的答案都是是,但一个与另一个无关。
除非您完全确定您将需要从基类继承并共享某些方法的多个类,否则我不会预先计划使用继承。当我们开始设想一些完美的教科书类层次结构时,它往往变得复杂并且无法解决问题。当你进行重构或者你发现自己编写类似的类并且不想重复代码时,它通常会更有意义。
编写一个接口然后实现它是一个很好的做法,当你创建另一个类将要依赖的东西时(通常是这样)。例如,如果你知道你的类将依赖于另一个“做某事”的类然后你可以暂时停止在第一个类上编写IDoesSomething
接口,并完成依赖于IDoesSomething
的第一个类。你还没有弄清楚实现是什么,但这并不重要,因为你已经编写的类只取决于接口。 (控制反转 - 良好实践。)然后你可以编写一个实现IDoesSomething
的类。
用一个例子来说明。假设我正在编写一个提供Menu
对象的类,该对象包含MenuItem
个对象的嵌套列表:
public class MenuProvider
{
public Menu GetMenu(string menuId)
{
//code that gets the menu
return menu;
}
}
然后我意识到在返回之前我需要过滤掉某些菜单项。这可能基于配置设置,特定用户或其他任何内容。
我可能会写这个界面:
public interface IMenuFilter
{
void FilterMenu(Menu menu);
}
然后像这样修改我的原始类:
public class MenuProvider
{
private readonly IMenuFilter _menuFilter;
public MenuProvider(IMenuFilter menuFilter)
{
_menuFilter = menuFilter;
}
public Menu GetMenu(string menuId)
{
//code that gets the menu
//filter the menu
_menuFilter.FilterMenu(menu);
return menu;
}
}
我不知道IMenuFilter
的实现是什么。在实践中,它可能最终成为一组独立的类的组合,每个类执行一种类型的过滤。但问题是,我不需要停止我在MenuProvider
上做的事情来解决这个问题。我可以编写这个类,甚至用模拟IMenuFilter
测试它,然后继续编写该过滤器的细节。
答案 1 :(得分:2)
您是否有要在此界面的实现中共享的常用功能?如果是,则创建一个抽象基类。否则,现在不用担心。您可以随时添加一个。但是编程到接口几乎总是一个好主意。
答案 2 :(得分:1)
通常,您将使用 接口或继承。我通常不会同时使用同一个班级。
如果要从基类继承功能,请使用继承。
当您希望不同的类实现某些相同的核心功能但不一定共享代码时,请使用接口。