CodeGym /Courses /C# SELF /Abstract Methods and Properties

Abstract Methods and Properties

C# SELF
Level 22 , Lesson 2
Available

1. Abstract Methods

In the previous lecture, we laid the foundation: we got to know abstract classes and saw that they can contain abstract methods and properties. We realized that this is a "contract" that forces child classes to provide their own implementation.

Now let's dig deeper and look at more complex and practical scenarios. In this lecture, we'll focus on syntax details, how abstraction works in multi-level hierarchies, and clearly separate when to use abstract and when to use virtual.

An abstract method is like a mysterious recipe from an old cookbook: "add a secret ingredient" — which one, it doesn't say, but all the following chefs have to come up with something!

An abstract method is always in an abstract class

Trying to declare an abstract method in a regular (non-abstract) class will cause a compiler error. Why? Because you can create a regular class directly, and what would happen if you tried to call an undefined method? Just a mysterious look from your IDE.


// This will cause a compile error:
public class WrongClass
{
    public abstract void Oops(); // You can't do this!
}

If a class has at least one abstract method, it must be marked as abstract!

Implementing abstract methods in derived classes

You implement them using the override keyword. A class that inherits from an abstract class and doesn't implement all abstract methods must also be abstract (otherwise the compiler will freak out).

Let's continue our app idea:

In previous lectures, we created a Shape class, where we declared an abstract method for calculating area. Now let's make some concrete shapes:


public class Rectangle : Shape
{
    public double Width { get; }
    public double Height { get; }

    public Rectangle(double width, double height)
    {
        Width = width;
        Height = height;
    }

    public override double CalculateArea()
    {
        return Width * Height;
    }
}

public class Circle : Shape
{
    public double Radius { get; }

    public Circle(double radius)
    {
        Radius = radius;
    }

    public override double CalculateArea()
    {
        return Math.PI * Radius * Radius;
    }
}

Why are abstract methods so important?

Abstract methods are your way of saying: "Guys, if you inherit from this class, figure out how this should work!" This makes your program's architecture clearer, protects you from accidental omissions, and most importantly, lets you use polymorphism to the max.

2. Abstract Properties

What is an abstract property

An abstract property is just like a contract, just for a property (property). For C#, this is super natural, because properties are one of the main ways to encapsulate data. An abstract property says: "Let the children decide for themselves where to get (and maybe how to set) the value of this property."

Example:
Let's add a Name property for a shape — every child should have it, but let each one decide what to return.


public abstract class Shape
{
    public abstract string Name { get; }

    public abstract double CalculateArea();
}

Now every child must implement this property:


public class Rectangle : Shape
{
    public double Width { get; }
    public double Height { get; }
    public override string Name => "Rectangle";

    public Rectangle(double width, double height)
    {
        Width = width;
        Height = height;
    }

    public override double CalculateArea()
    {
        return Width * Height;
    }
}

public class Circle : Shape
{
    public double Radius { get; }
    public override string Name => "Circle";

    public Circle(double radius)
    {
        Radius = radius;
    }

    public override double CalculateArea()
    {
        return Math.PI * Radius * Radius;
    }
}

Syntax features

An abstract property is kinda like an interface property: you declare it without a body, but you specify whether it will have only a getter, or also a setter.


public abstract class Creature
{
    // read-only property
    public abstract string Species { get; }

    // read-write property
    public abstract int Age { get; set; }
}

In the implementing class, you can define the logic for getting (and if needed — setting) the value.

Why use abstract properties

An abstract property is a great tool when you want every child to decide how to get or store the value. This is often needed in modeling, working with business models, view models, and basically anywhere the logic for a property is more complex than just returning a field.

For example, if one shape's name is calculated by a formula, and another just returns a constant, you can nicely "hide" all that behind an abstract property.

3. Diagram: how abstract class, methods, and properties are connected

Let's check out this diagram to see how it works:


┌─────────────┐
│ abstract    │
│   Shape     │
│-------------│
│ +Name: str  │  <-- abstract property
│ +Area(): dbl│  <-- abstract method
└─────┬───────┘
      │
 ┌────▼────┐      ┌───────┐
 │Rectangle│      │ Circle│
 │........ │ .... │ ......│
 │+Name    │      │+Name  │
 │+Area()  │      │+Area()│
 └─────────┘      └───────┘

This way we guarantee ONE interface for working with any child of the Shape class, but each child can do whatever it wants "under the hood".

UML diagram for abstract method and property:


┌────────────────────────────┐
│        abstract class      │
│           Animal           │
│────────────────────────────│
│+ Name: string {abstract}   │
│+ MakeSound(): void {abstract}│
└─────────────┬──────────────┘
              │
     ┌────────┴──────────┐
     │                   │
┌────────────┐     ┌─────────────┐
│    Cat     │     │    Dog      │
│────────────│     │─────────────│
│+ Name      │     │+ Name       │
│+ MakeSound()│    │+ MakeSound()│
└────────────┘     └─────────────┘

4. Practical scenarios and why this rocks for real projects

Abstract methods and properties are your tool if you're designing class hierarchies that should evolve. It's the foundation for big business apps, multi-level domain models, plugin systems, UI frameworks, where the system's base sets a "law" that all children must follow.

In real projects, these "clean" architectural solutions let you confidently add new entities and features months or years later, knowing the old code already covers all the behavior options.

The "why" question and back to polymorphism

Polymorphism seems like magic, but really it's just a contract: "you can call a certain method on any object in the family, and you'll always get the right result." Abstract methods and properties are a way to make the whole hierarchy speak the same language, but without a rigid "default" implementation.

This approach is used a lot in plugin systems (IDEs, graphic editors, CRM systems), when third-party devs make their own extensions but have to implement a minimum set of functions required by the platform. For example, if you're writing a file handler module, the base class might have an abstract property FileExtension and an abstract method Open(), so any plugin can properly handle files of its type.

Differences between abstract, virtual, and regular class members

Feature Regular method/property virtual abstract
Has implementation Yes Yes No
Override required No No (you can override) Yes (must in child)
Can call directly Yes Yes No
Can be in regular class Yes Yes No
Can be sealed No Yes No

5. Using this in our learning app

Now, armed with new knowledge, let's get back to our shapes app and see how abstract properties and methods work together to create a flexible and understandable system.


// For example, in the main method of the program
List<Shape> shapes = new List<Shape>
{
    new Rectangle(4, 5),
    new Circle(2.5)
};

foreach (Shape shape in shapes)
{
    // Thanks to the abstract Name property and CalculateArea method,
    // we don't care about the specific shape type
    Console.WriteLine($"{shape.Name}, Area: {shape.CalculateArea():F2}");
}

Result:

Rectangle, Area: 20.00
Circle, Area: 19.63

Beautiful: the code doesn't know or care what the shape actually is — it just calls the needed properties and methods, and .NET CLR will take care of the right implementation!

6. Common mistakes and implementation quirks

Mistake #1: didn't implement parent's abstract method.
If a derived class leaves even one abstract method or property unimplemented, and the class itself isn't marked abstract, the compiler won't let you build the project. That's a handy safety: you can't create an object with "holes" in its logic — like a shape without a CalculateArea() method.

Mistake #2: method is abstract, but class isn't.
This code won't compile either. If you add an abstract method to a class, the class itself must be abstract:


public abstract class Polygon : Shape
{
    // Don't implement CalculateArea(), class stays abstract
}

Mistake #3: trying to implement an abstract method with virtual.
An abstract method must be implemented with the override keyword, not virtual. But if you want the implementation to be overridable further down the hierarchy, you can first override the method, then declare it virtual in the child class:


public override double CalculateArea()
{
    // Default implementation...
}

In a deeper child, you can override this method again. But you can't make it abstract again, since it already has an implementation.

2
Task
C# SELF, level 22, lesson 2
Locked
Declaring an abstract class and method
Declaring an abstract class and method
2
Task
C# SELF, level 22, lesson 2
Locked
Abstract Methods and Properties
Abstract Methods and Properties
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION