SoFunction
Updated on 2025-03-07

C# object-oriented design principle: Liszc replacement principle

Lisch Replacement Principle (LSP)

Definition: Any parent class that appears can be replaced with its subclass without affecting the function.
Explanation:
In fact, LSP is an extension to the principle of opening and closing. In OO's idea, we know that objects are composed of a series of states and behaviors. The Rich substitution principle means that in an inheritance system, objects should have common external characteristics. When using LSP, if we want our program to reach the point where a parent class appears, it can be replaced with its subclass without affecting the function, then the parent class should also try to declare some common methods required by the subclass. After the parent class is replaced by the child class, it will be smoother. So why is it an extension to the principle of opening and closing? Because in the opening and closing principle, we say that we should try to use interfaces and abstract classes, of course, this abstract class and interface should also be defined as completely, so that our interfaces and abstract classes will be relatively stable, which not only conforms to the opening and closing principle but also meets the Richter replacement principle.

Error Case 1:

using System;
using ;
using ;
using ;
using ;

namespace Lisch replacement principle
{
    /// <summary>
    /// Birds    /// </summary>
    public class Bird
    {
        /// <summary>
        /// How to eat        /// </summary>
        public void Eat()
        { }

        /// <summary>
        /// How to fly        /// </summary>
        public void Fly()
        { }
    }

    /// <summary>
    /// Define a penguin inherits birds    /// </summary>
    public class Penguin : Bird
    {

    }

    public class Test
    {
        public static void ShowFly(Bird bird)
        {
            ();
        }

        public static void Main()
        {
            ShowFly(new Penguin());
        }
    }
}

Explanation:

In the above code, a bird is defined, and the penguin inherits from birds. There are methods for flying in birds, but penguins cannot fly, so the above code violates the principle of Richter replacement.

Error Case 2:

using System;
using ;
using ;
using ;
using ;

namespace Lisch replacement principle
{
    /// <summary>
    /// Define a parent pet class    /// </summary>
    public  class Pet
    {
    }

    /// <summary>
    /// Define a penguin class inherits from a pet class    /// </summary>
    public class PenguinDemo : Pet
    {
        /// <summary>
        /// How to swim        /// </summary>
        public void Swiming()
        {
            ("Cute penguin swimming");
        }
    }

    /// <summary>
    /// Define a dolphin class inherits from a pet class    /// </summary>
    public class Dolphin : Pet
    {
        /// <summary>
        /// How to play games        /// </summary>
        public void PlayGame()
        {
            ("Magic bubble bubble bricks");
        }
    }

    /// <summary>
    /// Test class    /// </summary>
    public class Test
    {
        public static void ShowPlay(Pet pet)
        {
            if (pet is PenguinDemo)
            {
                //Type conversion                PenguinDemo pen = (PenguinDemo)pet;
                ();
            }
            if (pet is Dolphin)
            {
                //Type conversion                Dolphin dol = (Dolphin)pet;
                ();
            }
        }
    }
}

Explanation:

If we treat puffer fish and penguins as pets, we can define a pet class, and then let these pets inherit this class. We know that the way we play with each pet is different from that of him. for example. Penguins have methods to swim, and puffer fish have methods to play. According to this requirement, we design a system to write a pet class, so that penguins can inherit this pet class and create a swimming method in the penguin class. This method cannot be placed in the pet class, because not all pets can swim. When writing pufferfish, it is also asked to inherit the pet class and write a game method in the pufferfish. At this time, when the client program uses the pet class and its subclass, it needs to make a judgment. We cannot call specific methods through the pet class. We need to make a judgment and transformation. If we add a dog, the dog will also have an independent method. We need to modify the previous code (when using the pet class and its subclass, we need to add the judgment to be a dog). This is obviously not in line with the principle of opening and closing, and it is also impossible to comply with the principle of Rich replacement, because no pet here can replace his parent class because their behavior is different, and the code maintainability and reusability are very poor!

Code download link:Click here to download

This is what this article about the Lisch replacement principle of C# object-oriented design principle. I hope it will be helpful to everyone's learning and I hope everyone will support me more.