Object-Oriented Programming

Virtual members

In the preceding example, we have seen a virtual method. This is a method that has an implementation in a base class but can be overridden in derived classes, which is helpful for changing implementation details. Methods are non-virtual by default. A virtual method in a base class is declared with the virtual keyword. An overridden implementation of a virtual method in a derived class is defined with the override keyword, instead of the virtual keyword. The method signature of the virtual and overridden methods must match.

Methods are not the only class members that can be virtual. The virtual keyword can be applied to properties, indexers, and events. However, the virtual modifier cannot be used together with staticabstractprivate, or override modifiers.

A virtual member that is overridden in a derived class can be further overridden in a class derived from the derived class. This chain of virtual inheritance continues indefinitely unless explicitly stopped with the use of the sealed keyword

class GameUnit
{
    public Position Position { get; protected set; }
    public GameUnit(Position position)
    {
        Position = position;
    }
    public void Draw(Surface surface)
    {
        surface.DrawAt(Image, Position);
    }
    protected virtual char Image => ' ';
}
class Terrain : GameUnit
{
    public Terrain(Position position) : base(position) { }
}
class Water : Terrain
{
    public Water(Position position) : base(position) { }
    protected override char Image => '░';
}
class Hill : Terrain
{
    public Hill(Position position) : base(position) { }
    protected override char Image => '≡';
}

abstract classes and members

An abstract class is declared using the abstract keyword. An abstract class cannot be instantiated, which means we cannot create the object of an abstract class. 

abstract class GameUnit
{
    public Position Position { get; protected set; }
    public GameUnit(Position position)
    {
        Position = position;
    }
    public void Draw(Surface surface)
    {
        surface.DrawAt(Image, Position);
    }
    protected abstract char Image { get; }
}
abstract class Terrain : GameUnit
{
    public Terrain(Position position) : base(position) { }
}
class Water : Terrain
{
    public Water(Position position) : base(position) { }
    protected override char Image => '░';
}
class Hill : Terrain
{
    public Hill(Position position) : base(position) { }
    protected override char Image => '≡';
}
  • An abstract class can have both abstract and non-abstract members.
  • If a class contains an abstract member, then the class must be marked abstract.
  • An abstract member cannot be private.
  • An abstract member cannot have an implementation.
  • An abstract class must provide an implementation for all of the members of all of the interfaces it implements (if any).
  • An abstract method is implicitly a virtual method.
  • Members declared abstract cannot be static or virtual.
  • The implementation in a derived class must specify the override keyword in the declaration of the member.

Sealed classes and members

sealed class Water : Terrain
{
   public Water(Position position) : base(position) { }
   protected override char Image => '░';
}
class Lake : Water  // ERROR: cannot derived from sealed type
{
   public Lake(Position position) : base(position) { }
}
class Water : Terrain
{
    public Water(Position position) : base(position) { }
    protected sealed override char Image => '░';
}
      
class Lake : Water
{
    public Lake(Position position) : base(position) { }
    protected sealed override char Image => '░';  // ERROR
}

Hiding base class members

class Base
{
    public int Get() { return 42; }
}
class Derived : Base
{
    public new int Get() { return 10; }
}
Derived d = new Derived();
Console.WriteLine(d.Get()); // prints 10
Base b = d;
Console.WriteLine(b.Get()); // prints 42

Interfaces

  • An interface can contain only methods, properties, indexers, and events. They cannot contain fields.
  • If a type implements an interface, then it must provide an implementation for all of the members of the interface. The method signature and return type of the method of an interface cannot be altered by the type that is implementing the interface.
  • When an interface defines properties or indexers, an implementation can provide extra accessors for them. For instance, if a property in an interface has only the get accessor, the implementation can also provide a set accessor.
  • An interface cannot have constructors or operators.
  • An interface cannot have static members.
  • The interface members are implicitly defined as public. If you try to use an access modifier with a member of an interface, it will result in a compile-time error.
  • An interface can be implemented by multiple types. A type can implement multiple interfaces.
  • If a class is inheriting from another class and simultaneously implementing an interface, then the base class name must come before the name of the interface separated by a comma.
  • Typically, an interface name starts with the letter I, such as IEnumerableIList<T>, and so on.
interface ISurface
{
    void BeginDraw();
    void EndDraw();
    void DrawAt(char c, Position position);
}

class Surface : ISurface
{
    private int left;
    private int top;
    public void BeginDraw()
    {
        Console.Clear();
        left = Console.CursorLeft;
        top = Console.CursorTop;
    }
    public void EndDraw()
    {
        Console.WriteLine();
    }
    public void DrawAt(char c, Position position)
    {
        try
        {
            Console.SetCursorPosition(left + position.X, 
                                      top + position.Y);
            Console.Write(c);
        }
        catch (ArgumentOutOfRangeException e)
        {
            Console.Clear();
            Console.WriteLine(e.Message);
        }
    }
}
interface A
{
    public void fun1();
    int data { set; get; }
}
public class B :A{ 
    void A.fun1(){}
    public int data {set; get;}
}


B b=new B();
b.data = 12;
//b.fun1() error
(b as A).fun1();