C# tutorials > Core C# Fundamentals > Object-Oriented Programming (OOP) > How do you implement inheritance in C# using `:`?

How do you implement inheritance in C# using `:`?

Inheritance is a fundamental pillar of Object-Oriented Programming (OOP) that allows a class (derived class) to inherit properties and methods from another class (base class). In C#, inheritance is implemented using the colon (`:`) operator. This tutorial will guide you through the implementation of inheritance in C# with clear explanations and examples.

Basic Inheritance Syntax

The core syntax for inheritance involves placing a colon (`:`) after the derived class name, followed by the name of the base class. In this example, DerivedClass inherits from BaseClass. This means DerivedClass automatically has access to the public and protected members of BaseClass.

public class BaseClass
{
    public string BaseProperty { get; set; }

    public void BaseMethod()
    {
        Console.WriteLine("Base class method.");
    }
}

public class DerivedClass : BaseClass
{
    public string DerivedProperty { get; set; }

    public void DerivedMethod()
    {
        Console.WriteLine("Derived class method.");
    }
}

Example Usage

This code demonstrates how to use the derived class. An instance of DerivedClass is created. It can access and modify the BaseProperty inherited from BaseClass and call the BaseMethod, along with accessing its own DerivedProperty and DerivedMethod. This showcases that the derived class inherits and can use the members of the base class.

public static void Main(string[] args)
{
    DerivedClass derivedObject = new DerivedClass();
    derivedObject.BaseProperty = "Base property value";
    derivedObject.BaseMethod();
    derivedObject.DerivedProperty = "Derived property value";
    derivedObject.DerivedMethod();

    Console.WriteLine(derivedObject.BaseProperty);
}

Concepts Behind the Snippet

Inheritance promotes code reusability and reduces redundancy. It establishes an 'is-a' relationship between classes. For example, DerivedClass 'is-a' BaseClass. C# supports single inheritance, meaning a class can inherit from only one direct base class. However, a class can implement multiple interfaces. This snippet demonstrates the basic principle of creating a derived class that inherits attributes and behaviors from a base class.

Real-Life Use Case Section

Consider a scenario where you are building a game. You might have a Character class with common properties like health, position, and movement speed. You can then create derived classes like Player and Enemy that inherit from the Character class and add specific behaviors. For instance, Player might have methods for attacking and interacting with the environment, while Enemy might have methods for AI-controlled movement and attacking.

Best Practices

  • Favor composition over inheritance: While inheritance can be useful, overusing it can lead to tight coupling and the fragile base class problem. Consider using composition (where a class contains instances of other classes) for more flexibility.
  • Design for inheritance or prohibit it: Classes should either be designed to be inherited from (by providing virtual or abstract members) or sealed to prevent inheritance.
  • Use abstract classes for defining common interfaces: Abstract classes can provide a base implementation and define abstract methods that derived classes must implement.

Interview Tip

When asked about inheritance in an interview, be prepared to discuss its benefits, limitations, and alternatives (like composition). Explain the 'is-a' relationship and how inheritance supports polymorphism. Also, be prepared to discuss the difference between inheritance and interfaces.

When to Use Them

Use inheritance when you have a clear 'is-a' relationship between classes and you want to reuse code from a base class. Inheritance is particularly useful when you want to define a common interface or behavior that multiple classes should implement. Avoid inheritance when the relationship is more of a 'has-a' relationship, in which case composition is a better choice.

Memory Footprint

Inheritance can impact memory usage. Each instance of a derived class includes the memory required for its own members plus the members inherited from the base class. This means a derived class instance will generally be larger than a base class instance. However, the shared code is only stored once, reducing code duplication.

Alternatives

  • Composition: Classes can contain instances of other classes as members, allowing you to reuse functionality without inheritance.
  • Interfaces: Interfaces define a contract that classes must adhere to, allowing for polymorphism and loose coupling.
  • Mixins (using extension methods): Extension methods can add functionality to existing classes without modifying them, allowing for a form of 'behavior injection'.

Pros

  • Code reusability: Avoids code duplication by inheriting members from a base class.
  • Polymorphism: Allows treating objects of different classes in a uniform way through a common base class.
  • Extensibility: Easy to add new classes that extend the functionality of existing classes.

Cons

  • Tight coupling: Can lead to tight coupling between classes, making it harder to modify or reuse classes independently.
  • Fragile base class problem: Changes to the base class can have unintended consequences in derived classes.
  • Increased complexity: Can make the class hierarchy more complex and harder to understand.

FAQ

  • Can a class inherit from multiple classes in C#?

    No, C# supports single inheritance, meaning a class can only inherit directly from one base class. However, a class can implement multiple interfaces.
  • What happens if a derived class defines a method with the same name as a method in the base class?

    The derived class method can either override the base class method (if the base class method is virtual or abstract) or hide the base class method (using the 'new' keyword).
  • What is the difference between `virtual` and `abstract` methods?

    A `virtual` method in the base class has an implementation and can be overridden in the derived class. An `abstract` method in the base class has no implementation and must be implemented in the derived class (unless the derived class is also abstract).