简体   繁体   English

C# inheritance 问题

[英]C# inheritance questions

I am creating an abstract base class which have functions implemented by other classes.我正在创建一个抽象基础 class ,它具有由其他类实现的功能。 My doubts are as follows我的疑惑如下

1) Do i need give 'virtual' in front of every function which need to be overridden by the child classes? 1)我是否需要在每个需要被子类覆盖的 function 前面给出“虚拟”? I see some examples without the virtual keyword and still they are open to be overridden.我看到一些没有 virtual 关键字的示例,它们仍然可以被覆盖。

2) I need to have a function which will be implemented in the base class and i dont want it to be overridden by the child classes. 2)我需要一个 function 将在基础 class 中实现,我不希望它被子类覆盖。 I added the 'fixed' keyword infront of that function.我在 function 前面添加了“固定”关键字。 Compiler start complaining 'member' cannot be sealed because it is not an override.编译器开始抱怨“成员”不能被密封,因为它不是覆盖。 Am i doing any wrong here?我在这里做错了吗?

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;
        }


    };
  1. For methods without implementations in an abstract class, use abstract as well:对于在抽象 class 中没有实现的方法,也使用abstract

     abstract public void Draw(); abstract public float getWidth(); abstract public void Swap(); abstract public void Erase();
  2. Methods aren't overridable by default;默认情况下方法是不可覆盖的; they only allow derived classes to override if declared abstract , virtual or override (but not override sealed ).它们只允许在声明为abstractvirtualoverride时覆盖派生类(但不允许override sealed )。

    Therefore you don't need to give getShapeDetails() any other modifiers than public :因此,除了public之外,您不需要给getShapeDetails()任何其他修饰符:

     public ShapeDetails getShapeDetails() { return _shapedDetails; }

On a side note, you should stick with .NET naming conventions and capitalize method names using Pascal case, so getWidth() becomes GetWidth() and getShapeDetails() becomes GetShapeDetails() .附带说明一下,您应该坚持 .NET 命名约定并使用 Pascal 大小写大写方法名称,因此getWidth()变为GetWidth()并且getShapeDetails()变为GetShapeDetails()

In fact you should be using a property getter for your _shapedDetails field instead of a getShapeDetails() method:实际上,您应该为_shapedDetails字段使用属性获取器,而不是getShapeDetails()方法:

private ShapeDetails _shapedDetails;

public ShapeDetails ShapedDetails
{
    get { return _shapedDetails; }
}

To be overrideable, a member must be marked virtual or abstract.要被覆盖,必须将成员标记为虚拟或抽象。 If abstract, the class must also be abstract, and the member has no implementation in the defining class.如果是抽象的,则 class 也必须是抽象的,并且该成员在定义的 class 中没有实现。 A virtual member must provide an implementation.虚拟成员必须提供实现。 Derived classes must override abstract members and may override virtual members.派生类必须覆盖抽象成员并且可以覆盖虚拟成员。 Non-virtual members may not be "sealed" because they can't be overridden anyway.非虚拟成员可能不会被“密封”,因为它们无论如何都不能被覆盖。

point 1: instead of virtual you can make those functions abstract.第 1 点:您可以将这些函数抽象为虚拟函数,而不是虚拟函数。

public abstract void Draw();
public abstract float getWidth();
public abstract void Swap();
public abstract void Erase();

This meaning that those function MUST be overridden.这意味着必须覆盖那些 function。 Currently you can create a subclass of your abstract class without any definitions in it and it would still compile.目前,您可以在没有任何定义的情况下创建抽象 class 的子类,它仍然可以编译。 By saying those are abstract functions those must be overridden.通过说这些是必须被覆盖的抽象函数。 If you dont override then the sub class will also be abstract.如果您不覆盖,则子 class 也将是抽象的。

And about point 2: can you add the code in which the fixed word is used?关于第2点:您可以添加使用固定词的代码吗?

1- Refering to override (C# Reference) 1-引用覆盖(C# 参考)

You cannot override a non-virtual or static method.您不能覆盖非虚拟或 static 方法。 The overridden base method must be virtual, abstract, or override.被覆盖的基方法必须是虚拟的、抽象的或覆盖的。


2- Refering to sealed (C# Reference) 2-引用密封(C# 参考)

You can also use the sealed modifier on a method or property that overrides a virtual method or property in a base class.您还可以在覆盖基础 class 中的虚拟方法或属性的方法或属性上使用密封修饰符。 This enables you to allow classes to derive from your class and prevent them from overriding specific virtual methods or properties.这使您能够允许类从 class 派生,并防止它们覆盖特定的虚拟方法或属性。

If it is an abstract method, the method is by default virtual, and needs to be implemented in inheriting class.如果是抽象方法,默认为虚方法,需要在继承class中实现。 Otherwise if it is not abstract,you need to have the virtual keyword.否则,如果它不是抽象的,你需要有 virtual 关键字。 If you don't the compile time type method will be used.如果您不这样做,将使用编译时类型方法。

Only a virtual method can be overriden, and only an abstract method can be implemented (like interface methods).只能重写虚方法,只能实现抽象方法(如接口方法)。 Otherwise, the only the someone can do is declare a new method to 'hide' the old one as follows:否则,唯一能做的就是声明一种新方法来“隐藏”旧方法,如下所示:

new public void getShapeDetails() {
    // Hides base.getShapeDetails();
}

Here is an code example/explanation.这是一个代码示例/说明。

//-----------------------------------------------------------------------------
// <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
        }
    }
}
  1. You can mark the function with virtual keywork if you want to provide a default implementation in your base class that can be overridden in derived classes;如果你想在你的基础 class 中提供一个可以在派生类中被覆盖的默认实现,你可以用virtual键标记 function; or you can mark it as abstract , delegating implementation to derived classes.或者您可以将其标记为abstract ,将实现委托给派生类。
  2. If you want a function NOT to be overrided in child implementations, DO NOT mark it as either virtual or abstract : simply define the function as you would do normally.如果您希望 function 不在子实现中被覆盖,请不要将其标记为virtualabstract :只需像往常一样定义 function 即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM