简体   繁体   中英

C# inheritance questions

I am creating an abstract base class which have functions implemented by other classes. 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? I see some examples without the virtual keyword and still they are open to be overridden.

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. I added the 'fixed' keyword infront of that 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:

     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 ).

    Therefore you don't need to give getShapeDetails() any other modifiers than public :

     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() .

In fact you should be using a property getter for your _shapedDetails field instead of a getShapeDetails() method:

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. 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.

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

This meaning that those function MUST be overridden. Currently you can create a subclass of your abstract class without any definitions in it and it would still compile. By saying those are abstract functions those must be overridden. If you dont override then the sub class will also be abstract.

And about point 2: can you add the code in which the fixed word is used?

1- Refering to override (C# Reference)

You cannot override a non-virtual or static method. The overridden base method must be virtual, abstract, or override.


2- Refering to sealed (C# Reference)

You can also use the sealed modifier on a method or property that overrides a virtual method or property in a base class. This enables you to allow classes to derive from your class and prevent them from overriding specific virtual methods or properties.

If it is an abstract method, the method is by default virtual, and needs to be implemented in inheriting class. Otherwise if it is not abstract,you need to have the virtual keyword. 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; or you can mark it as abstract , delegating implementation to derived classes.
  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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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