![](/img/trans.png)
[英]Inheritance Variable Questions (Changing inherited variables) in Unity (C#)
[英]C# inheritance questions
我正在創建一個抽象基礎 class ,它具有由其他類實現的功能。 我的疑惑如下
1)我是否需要在每個需要被子類覆蓋的 function 前面給出“虛擬”? 我看到一些沒有 virtual 關鍵字的示例,它們仍然可以被覆蓋。
2)我需要一個 function 將在基礎 class 中實現,我不希望它被子類覆蓋。 我在 function 前面添加了“固定”關鍵字。 編譯器開始抱怨“成員”不能被密封,因為它不是覆蓋。 我在這里做錯了嗎?
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;
}
};
對於在抽象 class 中沒有實現的方法,也使用abstract
:
abstract public void Draw(); abstract public float getWidth(); abstract public void Swap(); abstract public void Erase();
默認情況下方法是不可覆蓋的; 它們只允許在聲明為abstract
、 virtual
或override
時覆蓋派生類(但不允許override sealed
)。
因此,除了public
之外,您不需要給getShapeDetails()
任何其他修飾符:
public ShapeDetails getShapeDetails() { return _shapedDetails; }
附帶說明一下,您應該堅持 .NET 命名約定並使用 Pascal 大小寫大寫方法名稱,因此getWidth()
變為GetWidth()
並且getShapeDetails()
變為GetShapeDetails()
。
實際上,您應該為_shapedDetails
字段使用屬性獲取器,而不是getShapeDetails()
方法:
private ShapeDetails _shapedDetails;
public ShapeDetails ShapedDetails
{
get { return _shapedDetails; }
}
要被覆蓋,必須將成員標記為虛擬或抽象。 如果是抽象的,則 class 也必須是抽象的,並且該成員在定義的 class 中沒有實現。 虛擬成員必須提供實現。 派生類必須覆蓋抽象成員並且可以覆蓋虛擬成員。 非虛擬成員可能不會被“密封”,因為它們無論如何都不能被覆蓋。
第 1 點:您可以將這些函數抽象為虛擬函數,而不是虛擬函數。
public abstract void Draw();
public abstract float getWidth();
public abstract void Swap();
public abstract void Erase();
這意味着必須覆蓋那些 function。 目前,您可以在沒有任何定義的情況下創建抽象 class 的子類,它仍然可以編譯。 通過說這些是必須被覆蓋的抽象函數。 如果您不覆蓋,則子 class 也將是抽象的。
關於第2點:您可以添加使用固定詞的代碼嗎?
您不能覆蓋非虛擬或 static 方法。 被覆蓋的基方法必須是虛擬的、抽象的或覆蓋的。
您還可以在覆蓋基礎 class 中的虛擬方法或屬性的方法或屬性上使用密封修飾符。 這使您能夠允許類從 class 派生,並防止它們覆蓋特定的虛擬方法或屬性。
如果是抽象方法,默認為虛方法,需要在繼承class中實現。 否則,如果它不是抽象的,你需要有 virtual 關鍵字。 如果您不這樣做,將使用編譯時類型方法。
只能重寫虛方法,只能實現抽象方法(如接口方法)。 否則,唯一能做的就是聲明一種新方法來“隱藏”舊方法,如下所示:
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
}
}
}
virtual
鍵標記 function; 或者您可以將其標記為abstract
,將實現委托給派生類。virtual
或abstract
:只需像往常一樣定義 function 即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.