为什么我不选择抽象?声明类成员虚拟的限制是什么?只能将方法声明为虚拟吗?何时应该将类成员声明为虚拟(C#)/ Overridable(VB.NET)?
回答
抽象方法或属性(都可以是虚拟的或抽象的)只能在抽象类中声明,并且不能有正文,即不能在抽象类中实现它。
虚拟方法或属性必须有一个主体,即您必须提供一个实现(即使主体为空)。
如果有人想使用你的抽象类,他将不得不实现一个继承它的类,并显式实现抽象方法和属性,但可以选择不覆盖虚方法和属性。
例:
using System;
using C=System.Console;
namespace Foo
{
public class Bar
{
public static void Main(string[] args)
{
myImplementationOfTest miot = new myImplementationOfTest();
miot.myVirtualMethod();
miot.myOtherVirtualMethod();
miot.myProperty = 42;
miot.myAbstractMethod();
}
}
public abstract class test
{
public abstract int myProperty
{
get;
set;
}
public abstract void myAbstractMethod();
public virtual void myVirtualMethod()
{
C.WriteLine("foo");
}
public virtual void myOtherVirtualMethod()
{
}
}
public class myImplementationOfTest : test
{
private int _foo;
public override int myProperty
{
get { return _foo; }
set { _foo = value; }
}
public override void myAbstractMethod()
{
C.WriteLine(myProperty);
}
public override void myOtherVirtualMethod()
{
C.WriteLine("bar");
}
}
}
如果你想在你的基类中给它一个实现,你可以使它成为虚拟的,如果你不把它抽象化。
是的,只有方法可以声明为虚方法。
如果您不想在基类中定义任何实现并且想强制它在任何派生类中定义,那么您会使用抽象。如果要提供可由派生类重写的默认实现,请将其定义为虚拟。
是的,只有方法可以是虚拟的。
摘要表示您无法提供默认实现。这又意味着所有的子类都必须提供抽象方法的实现,以便实例化(具体)。
我不确定'限制'是什么意思,所以不能回答这个问题。
属性可以被声明为虚拟的,但是你可以在概念上将它们视为方法。
如果存在基本实现,则应该声明一个虚拟成员,但是在子类中可能会覆盖该功能。虚拟也可以用来代替抽象以允许方法实现是可选的(即,基本实现是空的方法)
当将成员设置为虚拟,但虚拟成员比非虚拟成员慢时没有限制,虚拟方法。
这两种方法和属性都可以标记为虚拟。
首先,我会回答你第二个问题。只有方法可以被声明为虚拟的。 当你希望在你的基类中有一些默认的功能时,你会选择虚拟而不是抽象的,但是你希望保留通过继承你的基类的类来覆盖这个功能的选项。 为例子:
如果要实现的形状类,你可能有一个名为的getArea()返回你的形状的面积法。在这种情况下,Shape类中的getArea()方法没有默认行为,因此您可以将其实现为abstract。将方法实现为抽象将会阻止您实例化对象的形状对象。
在另一方面,如果实现了类狗,你可能要实现在这种情况下,方法树皮(),你可能想实现一个默认的吠叫声,并把它在狗类,而一些继承类,如类Chiwawa可能想重写此方法并实现特定的吠叫声。在这种情况下,方法树皮将被实现为虚拟,您将能够实例化狗以及Chiwawas。
有一个疑难杂症在这里要注意的Windows窗体。
如果你想要一个可以继承的Control/UserControl,即使你在基类中没有逻辑,你也不希望它是抽象的,否则你将无法使用Designer中的派生类: http://www.urbanpotato.net/default.aspx/document/2001
你的问题比技术更关系到风格。我认为,这本书 http://www.amazon.com/Framework-Design-Guidelines-Conventions-Development/dp/0321246756 围绕你的问题和其他很多人讨论很多。
我个人将大多数方法和属性标记为虚拟。我使用代理和延迟加载很多,所以我不想担心以后改变的东西。
- 1. 将指针声明为类成员C++
- 2. C++:将模板声明为类成员
- 3. 何时应该将子对象声明为qt中父类的成员变量?
- 4. VB.net Overridable属性不同于C#虚拟属性?
- 5. 为了模拟对象,我们是否应该声明所有成员函数是虚拟的(C++)?
- 6. C++继承:虚拟成员需要重新声明?
- 7. 将对象声明为类成员
- 8. C++声明类成员以外的类
- 9. C++从父虚拟成员调用子虚拟成员
- 10. 私人成员应该明确声明为私人的惯用C#吗?
- 11. 我应该声明这是const int成员变量的类吗?
- 12. 在运行时声明类成员D
- 13. C++如何声明对象的向量作为类的成员
- 14. 将一个类的数组声明为该类的私有成员?
- 15. C++虚拟函数的前向声明
- 16. 被声明为静态类成员的C++类
- 17. 如何将unique_ptr的向量声明为类数据成员?
- 18. 为什么C++模板参数应该声明为类类型?
- 19. 声明前向声明的类的成员函数为朋友
- 20. 在C++中模拟一个类的虚拟静态成员?
- 21. 设置虚拟函数声明为零?
- 22. PHP如何声明一个类成员?
- 23. 继承基类成员函数的虚拟说明符
- 24. C++:重写纯虚拟成员变量?
- 25. 虚拟基类数据成员
- 26. 虚拟成员调用抽象类
- 27. 未声明类的类成员
- 28. 为什么这个类没有声明任何纯粹的虚拟成员函数abstract?
- 29. 将接口声明为类成员有什么用处?
- 30. 错误TS1112:不能将一个类成员声明为可选