我正在创建一个抽象基类,其中包含由其他类实现的函数。我的怀疑如下
1)我是否需要在每个需要被子类覆盖的函数前面给出“虚拟”?我看到一些没有虚拟关键字的例子,但仍然可以覆盖它们。
2)我需要有一个将在基类中实现的函数,我不希望它被子类重写。我添加了该功能的“固定”关键字。编译器开始抱怨“成员”无法密封,因为它不是覆盖。我在这里做错了吗?
abstract public class ShapeBase
{
private ShapeDetails _shapedDetails;
public CampusCardBase(ShapeDetails shDetails)
{
_shapedDetails= shDetails;
}
public virtual void Draw();
public virtual float getWidth();
public virtual void Swap();
public virtual void Erase();
public sealed ShapeDetails getShapeDetails()
{
return _shapedDetails;
}
};
答案 0 :(得分:9)
对于在抽象类中没有实现的方法,也可以使用abstract
:
abstract public void Draw();
abstract public float getWidth();
abstract public void Swap();
abstract public void Erase();
默认情况下,方法不可覆盖;如果声明abstract
,virtual
或override
(但不是override sealed
),它们只允许派生类重写。
因此,除了getShapeDetails()
之外,您无需提供public
任何其他修饰符:
public ShapeDetails getShapeDetails()
{
return _shapedDetails;
}
另外,您应该坚持使用.NET命名约定并使用Pascal大小写方法名称,因此getWidth()
变为GetWidth()
而getShapeDetails()
变为GetShapeDetails()
。< / p>
事实上,您应该使用property getter来代替_shapedDetails
字段:
getShapeDetails()
答案 1 :(得分:1)
要覆盖,必须将成员标记为虚拟或抽象。如果是abstract,则该类也必须是抽象的,并且该成员在定义类中没有实现。虚拟成员必须提供实现。派生类必须覆盖抽象成员,并且可以覆盖虚拟成员。非虚拟成员可能不会被“密封”,因为无论如何它们都无法被覆盖。
答案 2 :(得分:1)
第1点:代替虚拟,你可以将这些功能抽象化。
public abstract void Draw();
public abstract float getWidth();
public abstract void Swap();
public abstract void Erase();
这意味着必须覆盖那些功能。目前,您可以创建抽象类的子类,而不包含任何定义,它仍然可以编译。通过说那些是抽象函数,必须覆盖它们。如果你不重写那么子类也将是抽象的。
关于第2点:你能添加使用固定字的代码吗?
答案 3 :(得分:1)
您无法覆盖非虚拟或 静态方法。被覆盖的基地 方法必须是虚拟的,抽象的或 覆盖。
您也可以使用密封修改器 在覆盖的方法或属性上 基础中的虚拟方法或属性 类。这使您可以允许 从你的班级派生的班级 防止他们压倒特定的 虚拟方法或属性。
答案 4 :(得分:0)
如果是抽象方法,则该方法默认为virtual,需要在继承类中实现。 否则,如果它不是抽象的,则需要使用virtual关键字。如果不这样,将使用编译时类型方法。
答案 5 :(得分:0)
只能覆盖虚方法,并且只能实现抽象方法(如接口方法)。否则,只有某人可以做的是声明一种新方法来“隐藏”旧方法,如下所示:
new public void getShapeDetails() {
// Hides base.getShapeDetails();
}
这是一个代码示例/解释。
//-----------------------------------------------------------------------------
// <copyright file="Program.cs" company="DCOM Productions">
// Copyright (c) DCOM Productions. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------
namespace AbstractClassExample {
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
class Program {
/// <summary>
/// Example abstract base class
/// </summary>
public abstract class FooClass {
/// <summary>
/// Abstract Method
/// </summary>
public abstract void abstractFoo();
/// <summary>
/// Virtual Method
/// </summary>
public virtual void virtualFoo() {
// Todo
}
/// <summary>
/// Normal Method
/// </summary>
public void Foo() {
// Todo
}
}
public class FooDeriver : FooClass {
/// <summary>
/// Implements base.abstractFoo
/// </summary>
public override void abstractFoo() {
throw new NotImplementedException();
}
/// <summary>
/// Overrides base.virtualFoo
/// </summary>
public override void virtualFoo() {
base.virtualFoo();
}
/// <summary>
/// Compiler ErrorError 1
/// cannot override inherited member 'ConsoleApplication1.Program.FooClass.Foo()' because it is not marked virtual, abstract, or override
/// </summary>
public override void Foo() {
throw new NotImplementedException();
}
}
static void Main(string[] args) {
// Program code
}
}
}
答案 6 :(得分:0)
virtual
关键字标记该函数;或者您可以将其标记为abstract
,将实现委派给派生类。virtual
或abstract
:只需像正常情况一样定义函数。