In depth analysis of abstract abstract class in C

  • 2021-09-05 00:41:20
  • OfStack

Abstract classes and class members
You can declare a class as an abstract class by placing the keyword abstract before the class definition. For example:


public abstract class A
{
  // Class members here.
}

Abstract classes cannot be instantiated. The purpose of abstract classes is to provide a common base class definition that can be shared by multiple derived classes. For example, a class library can define an abstract class, use it as an argument to multiple class library functions, and require programmers using the library to provide their own class implementation by creating derived classes.
Abstract classes can also define abstract methods. The method is to add the keyword abstract before the return type of the method. For example:


public abstract class A
{
  public abstract void DoWork(int i);
}

Abstract methods are not implemented, so the method definition is followed by a semicolon instead of a regular method block. Derived classes of abstract classes must implement all abstract methods. When an abstract class inherits a virtual method from a base class, the abstract class can override the virtual method using the abstract method. For example:


// compile with: /target:library
public class D
{
  public virtual void DoWork(int i)
  {
    // Original implementation.
  }
}

public abstract class E : D
{
  public abstract override void DoWork(int i);
}

public class F : E
{
  public override void DoWork(int i)
  {
    // New implementation.
  }
}

If an virtual method is declared as abstract, it is still a virtual method for all classes that inherit from an abstract class. A class that inherits an abstract method cannot access the original implementation of the method. In the previous example, DoWork in class F could not call DoWork in class D. In this way, abstract classes can force derived classes to provide new method implementations for virtual methods.

Define abstract attributes

The following example demonstrates how to define abstract properties. An abstract property declaration does not provide an implementation of the property accessor; It only declares that the class supports properties, leaving the accessor implementation to the derived class. The following example demonstrates how to implement abstract properties inherited from the base class.
This example consists of three files, each of which is compiled separately, and the resulting assembly is referenced by the next compilation:

abstractshape. cs: An Shape class that contains abstract Area attributes. shapes. cs: A subclass of the Shape class. shapetest. cs: Test program that displays the area of some Shape derived objects.

To compile the example, use the following command:


csc abstractshape.cs shapes.cs shapetest.cs

This generates the executable shapetest. exe.
The Shape class declared by this file contains the Area attribute of type double.


// compile with: csc /target:library abstractshape.cs
public abstract class Shape
{
  private string name;

  public Shape(string s)
  {
    // calling the set accessor of the Id property.
    Id = s;
  }

  public string Id
  {
    get
    {
      return name;
    }

    set
    {
      name = value;
    }
  }

  // Area is a read-only property - only a get accessor is needed:
  public abstract double Area
  {
    get;
  }

  public override string ToString()
  {
    return Id + " Area = " + string.Format("{0:F2}", Area);
  }
}

Property modifiers are placed in the property declaration. For example:


public abstract double Area

When declaring abstract properties (such as Area in this example), indicate which property accessors are available and do not implement them. In this example, only one get accessor is available, so the property is read-only.
The following code demonstrates the three subclasses of Shape and how they override the Area property to provide their own implementation.


// compile with: csc /target:library /reference:abstractshape.dll shapes.cs
public class Square : Shape
{
  private int side;

  public Square(int side, string id)
    : base(id)
  {
    this.side = side;
  }

  public override double Area
  {
    get
    {
      // Given the side, return the area of a square:
      return side * side;
    }
  }
}

public class Circle : Shape
{
  private int radius;

  public Circle(int radius, string id)
    : base(id)
  {
    this.radius = radius;
  }

  public override double Area
  {
    get
    {
      // Given the radius, return the area of a circle:
      return radius * radius * System.Math.PI;
    }
  }
}

public class Rectangle : Shape
{
  private int width;
  private int height;

  public Rectangle(int width, int height, string id)
    : base(id)
  {
    this.width = width;
    this.height = height;
  }

  public override double Area
  {
    get
    {
      // Given the width and height, return the area of a rectangle:
      return width * height;
    }
  }
}

The following code demonstrates a test program that creates several Shape derived objects and outputs their areas.


// compile with: csc /reference:abstractshape.dll;shapes.dll shapetest.cs
class TestClass
{
  static void Main()
  {
    Shape[] shapes =
    {
      new Square(5, "Square #1"),
      new Circle(3, "Circle #1"),
      new Rectangle( 4, 5, "Rectangle #1")
    };

    System.Console.WriteLine("Shapes Collection");
    foreach (Shape s in shapes)
    {
      System.Console.WriteLine(s);
    }
  }
}

Output:


  Shapes Collection
  Square #1 Area = 25.00
  Circle #1 Area = 28.27
  Rectangle #1 Area = 20.00


Related articles: