这里的第一个问题,所以希望你们都会轻轻地对我说话!
过去几天我一直在阅读关于多态性的大量内容,并尝试将其应用于我在c#中所做的事情,似乎有几种不同的方法来实现它。我希望我已经掌握了这一点,但即使我没有澄清,我也会很高兴。
从我所看到的,我有3个选择:
virtual
'
想要我的派生类
覆盖。 从我所看到的,如果我不需要基础中的任何实现逻辑,那么一个接口给了我最大的灵活性(因为我当时并没有限制自己关于多重继承等),但如果我要求基础能够在派生类正在做的事情之上做一些事情,那么使用1或2将是更好的解决方案吗?
感谢您对这些人的任何意见 - 本周末我已经阅读了很多内容,无论是在本网站还是其他地方,我想我现在理解这些方法,但我只想澄清一下如果我在正确的轨道上,语言特定的方式。希望我也正确标记了这一点。
干杯, 特里
答案 0 :(得分:6)
界面提供最多的抽象;您不依赖于任何特定的实现(如果由于其他原因,实现必须具有不同的基类,则非常有用)。
对于真正的多态性,virtual
是必须的;多态性最常与类型子类化相关联......
你当然可以混合两者:
public interface IFoo {
void Bar();
}
class Foo : IFoo {
public virtual void Bar() {...}
}
class Foo2 : Foo {
public override ...
}
abstract
是一个单独的问题; abstract
的选择确实是:它可以由基类理智地定义吗?如果没有默认实现,则必须为abstract
。
当存在许多常见的实现细节时,常见的基类可能很有用,并且纯粹通过接口复制是没有意义的;但有趣的是 - 如果实现永远不会每个实现不同,扩展方法提供了一种在interface
上公开它的有用方法(这样每个实现都不必这样做):< / p>
public interface IFoo {
void Bar();
}
public static class FooExtensions {
// just a silly example...
public static bool TryBar(this IFoo foo) {
try {
foo.Bar();
return true;
} catch {
return false;
}
}
}
答案 1 :(得分:2)
以上三种都是有效的,并且本身有用。 没有“最好”的技术。只有编程实践和经验才能帮助您在合适的时间选择合适的技术。
所以,现在选择一个看似合适的方法,并实施。 观察有效的方法,失败的方法,吸取教训,然后再试一次。
答案 2 :(得分:2)
接口通常受到青睐,原因如下:
也就是说,如果你想利用常见的功能,你可以使用接口来实现多态(让你的方法接受接口),但是使用抽象基类来分享一些行为。
public interface IFoo
{
void Bar();
enter code here
}
将是您的界面
public abstract class BaseFoo : IFoo
{
void Bar
{
// Default implementation
}
}
将是您的默认实现
public class SomeFoo : BaseFoo
{
}
是一个重用您的实现的类。
但是,你将使用接口来实现多态:
public class Bar
{
int DoSometingWithFoo(IFoo foo)
{
foo.Bar();
}
}
注意我们正在使用方法中的接口。
答案 3 :(得分:1)
你应该问的第一件事是“我为什么需要使用多态?”,因为多态性本身并不是结束,而是达到目的的意思。一旦您明确定义了问题,就应该更清楚地使用哪种方法。
无论如何,你评论过的那三个aproach并不是独占的,如果你需要在一些类之间重用逻辑而不是其他类,或者需要一些不同的接口,你仍然可以混合它们......
答案 4 :(得分:1)
答案 5 :(得分:0)
这实际上取决于您希望如何构建代码以及您希望如何使用它。
从测试的角度来看,具有Interface类型的基类是很好的,因为您可以使用模拟对象来替换它。
如果您希望在某些函数中实现代码而不是其他函数,那么抽象类就是如此,就像抽象类只有抽象函数一样,它实际上是一个接口。
请记住,抽象类无法实例化,因此对于工作代码,您必须具有从中派生的类。
在实践中,所有都是有效的。
我倾向于使用抽象类,如果我有很多类派生它,但是在浅层(比如说只有1个类)。
如果我期待深层次的继承,那么我使用具有虚函数的类。
无论如何,最好保持课程简单,以及他们的继承性,因为越复杂,他们就越有可能引入错误。