Have an implementation in your base class and declare methods virtual
if intended to be overridden. In this case you do not need the abstract
keyword as everything is defined for the base class.
namespace Chess
{
public class Figure
{
public virtual bool SomeMethod()
{
return true;
}
}
public class Pawn : Figure
{
public override bool SomeMethod()
{
return false;
}
public bool BaseMethod()
{
return base.SomeMethod();
}
}
public class Board
{
public void SomeBoardMethod()
{
Figure figure = new Pawn();
var result1 = figure.SomeMethod();
if (figure is Pawn pawn)
{
var result2 = pawn.BaseMethod();
}
}
}
}
Here the base functionality is exposed by the decedent classes with an additional method called BaseMethod()
. Then you can use pattern matching to get to the Pawn
specific methods.
I feel that you need to do some reading on how inheritance works.
Here is some test code with a base class containing 3 methods. One normal method CommonMethod()
, one virtual method SpecialMethod()
and one normal method, with the intent to hide in one derived class called FigureMethod()
.
The base class Figure
has two derived classes Pawn
and Queen
that either override
or re-define methods with the new
keyword.
namespace Chess
{
public class Figure
{
public int CommonMethod()
{
return 100;
}
public virtual int SpecialMethod()
{
return 1;
}
public int FigureMethod()
{
return -1;
}
}
public class Pawn : Figure
{
public override int SpecialMethod()
{
return 2;
}
}
public class Queen : Figure
{
public new int FigureMethod()
{
return 10;
}
}
static class Program
{
static void Main(string[] args)
{
Figure figure = new Figure();
Figure figurePawn = new Pawn();
Figure figureQueen = new Queen();
Pawn pawn = new Pawn();
Queen queen = new Queen();
Console.WriteLine($"{"Variable",12} {"Common",8} {"Special",8} {"Figure",8}");
Console.WriteLine($"{nameof(figure),12} {figure.CommonMethod(),8} {figure.SpecialMethod(),8} {figure.FigureMethod(),8}");
Console.WriteLine($"{nameof(figurePawn),12} {figurePawn.CommonMethod(),8} {figurePawn.SpecialMethod(),8} {figurePawn.FigureMethod(),8}");
Console.WriteLine($"{nameof(figureQueen),12} {figureQueen.CommonMethod(),8} {figureQueen.SpecialMethod(),8} {figureQueen.FigureMethod(),8}");
Console.WriteLine($"{nameof(pawn),12} {pawn.CommonMethod(),8} {pawn.SpecialMethod(),8} {pawn.FigureMethod(),8}");
Console.WriteLine($"{nameof(queen),12} {queen.CommonMethod(),8} {queen.SpecialMethod(),8} {queen.FigureMethod(),8}");
}
}
}
I call all three methods from 5 instances. Three instances of a base class Figure
variables, and Two instances
The results are as follows:
Variable Common Special Figure
figure 100 1 -1
figurePawn 100 2 -1
figureQueen 100 1 -1
pawn 100 2 -1
queen 100 1 10
- All ways of calling
CommonMethod()
result in the same result.
- The
SpecialMethod()
calls either use the base implementation or the specific one for Pawn
types.
- The
FigureMethod()
can only be called when the variable is scoped to a Queen
type and it re-defines what this method does for this specific type.
As a general rule, do not use the new
keyword unless absolutely necessary. This is because the re-defined method might have a completely different functionality than the general use one and can results in bugs and/or maintenance issues.