C#面向对象编程中开闭原则的示例详解

C#面向对象编程中开闭原则的示例详解

什么是开闭原则

开闭原则(Open-Closed Principle)是面向对象编程中的一个重要原则,其定义如下:

软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。

也就是说,在软件设计的过程中,可以通过扩展已有的代码来增加新的功能,而不需要修改原有的代码。

如何实现开闭原则

使用抽象类或接口

使用抽象类或接口可以实现对扩展开放,对修改关闭的原则。这是因为抽象类或接口定义的方法、属性是抽象的,具体的实现是在子类中实现的,这样子类就可以根据需要自定义实现方法,而不需要修改父类或接口的实现。

利用多态性

利用多态性也可以实现对扩展开放,对修改关闭的原则。多态性的实现是通过父类或接口引用子类对象的方式来实现的,这样可以实现代码的灵活性和可扩展性。

示例说明1:汽车品牌展示

假设现在需要在一个网站上展示不同品牌的汽车,并需支持新增车型。如果按照开闭原则的设计思想,可以使用抽象类或接口来定义汽车和品牌,并利用多态性来实现对扩展开放,对修改关闭的原则。具体实现如下:

public abstract class Car
{
    public abstract string Brand { get; }
    public abstract string Model { get; }
    public abstract double Price { get; }
}

public class BMW : Car
{
    public override string Brand => "BMW";
    public override string Model => "X5";
    public override double Price => 300000;
}

public class Benz : Car
{
    public override string Brand => "Benz";
    public override string Model => "S600";
    public override double Price => 400000;
}

public interface ICarFactory
{
    Car CreateCar();
}

public class BMWFactory : ICarFactory
{
    public Car CreateCar()
    {
        return new BMW();
    }
}

public class BenzFactory : ICarFactory
{
    public Car CreateCar()
    {
        return new Benz();
    }
}

public class CarShop
{
    private List<ICarFactory> factories = new List<ICarFactory>();

    public CarShop()
    {
        factories.Add(new BMWFactory());
        factories.Add(new BenzFactory());
    }

    public void DisplayCars()
    {
        foreach (var factory in factories)
        {
            var car = factory.CreateCar();
            Console.WriteLine("Brand: {0}, Model: {1}, Price: {2}", car.Brand, car.Model, car.Price);
        }
    }
}

这里定义了一个抽象类Car和两个实现类BMWBenz,同时定义了一个工厂接口ICarFactory,以及两个工厂类BMWFactoryBenzFactory,通过实现工厂类的CreateCar()方法返回对应的汽车对象。最后在CarShop中使用工厂类来展示汽车信息。

如果新增一个品牌比如Audi,只需要新增一个类AudiFactory实现ICarFactory接口即可,而不需修改已有的代码。

示例说明2:图标组件功能扩展

假设现在需要开发一个图标组件,支持多种类型的图标,如圆形、矩形、三角形等,并且需要支持新增图标类型。按照开闭原则的设计思想,可以使用抽象类或接口来定义图标和图标类型,并利用多态性来实现对扩展开放,对修改关闭的原则。具体实现如下:

public abstract class Shape
{
    public abstract void Draw();
}

public class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Draw a circle.");
    }
}

public class Rect : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Draw a rectangle.");
    }
}

public interface IShapeFactory
{
    Shape CreateShape();
}

public class CircleFactory : IShapeFactory
{
    public Shape CreateShape()
    {
        return new Circle();
    }
}

public class RectFactory : IShapeFactory
{
    public Shape CreateShape()
    {
        return new Rect();
    }
}

public class Component
{
    private List<IShapeFactory> factories = new List<IShapeFactory>();

    public Component()
    {
        factories.Add(new CircleFactory());
        factories.Add(new RectFactory());
    }

    public void AddShapeFactory(IShapeFactory factory)
    {
        factories.Add(factory);
    }

    public void DrawShapes()
    {
        foreach (var factory in factories)
        {
            var shape = factory.CreateShape();
            shape.Draw();
        }
    }
}

这里定义了一个抽象类Shape和两个实现类CircleRect,同时定义了一个工厂接口IShapeFactory,以及两个工厂类CircleFactoryRectFactory,通过实现工厂类的CreateShape()方法返回对应的图标对象。最后在Component组件中使用工厂类来展示图标信息。

如果新增一个图标类型比如Triangle,只需要新增一个类TriangleFactory实现IShapeFactory接口即可,而不需修改已有的代码。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#面向对象编程中开闭原则的示例详解 - Python技术站

(0)
上一篇 2023年5月31日
下一篇 2023年5月31日

相关文章

  • C#使用Socket快速判断数据库连接是否正常的方法

    以下是C#使用Socket快速判断数据库连接是否正常的方法的详细攻略。 为什么需要使用Socket来判断数据库连接是否正常 在开发应用程序时,我们通常需要将数据库与应用程序进行连接,以提供数据的读写操作。但是,有时候我们需要判断数据库连接是否正常,以避免在后期出现一些问题。而使用Socket来判断数据库连接是否正常,则可以在较短的时间内,得出结论,并提供更好…

    C# 2023年6月2日
    00
  • 原生JS实现加载进度条

    原生JS实现加载进度条 在Web开发中,加载进度条是一个非常常见的功能。本文将介绍如何使用原生JS实现加载进度条。 步骤1:HTML结构 首先,我们需要在HTML中添加进度条的结构。可以在HTML文件中添加以下代码: <div id="progress-bar"> <div id="progress"…

    C# 2023年5月15日
    00
  • asp.net文件上传示例分享

    我来为您详细讲解“asp.net文件上传示例分享”的完整攻略。 一、背景介绍 在网站开发中,文件上传功能是比较常用的功能,ASP.NET也提供了方便的文件上传类供我们使用。本攻略将分享ASP.NET文件上传的示例代码,以帮助大家快速了解ASP.NET文件上传功能的实现过程。 二、示例一 2.1 前端页面 在网站的前端页面中,我们需要添加文件上传的控件,以下是…

    C# 2023年5月31日
    00
  • C#使用foreach语句搜索数组元素的方法

    当我们需要搜索一个数组中的元素时,可以使用C#中的foreach语句来实现。以下是使用foreach语句搜索数组元素的步骤: 1. 创建一个数组 在开始搜索数组元素之前,需要先创建一个数组,并向其中添加元素。例如,我们要创建一个包含数字1到5的数组,可以使用以下代码: int[] numArray = new int[] {1, 2, 3, 4, 5}; 2…

    C# 2023年6月8日
    00
  • C#用委托BeginInvoke做异步线程

    下面是C#用委托BeginInvoke做异步线程的完整攻略: 委托和异步线程 委托(Delegate)是C#中非常重要的概念之一。它是一种类型,允许我们在定义方法的时候,把该方法的引用传递给其他的方法,这样其他的方法就可以“调用”该方法了。委托本身就是一个指针,只不过是用来指向方法的,因此有时候也称之为“方法指针”。 异步线程指的是,我们在执行某些任务时,不…

    C# 2023年6月7日
    00
  • C# Linq的OrderByDescending()方法 – 根据指定的键按降序对序列的元素进行排序

    当使用C#Linq时,我们常常需要在对数据进行排序时使用OrderByDescending()方法。这个方法可以根据指定的条件对数据进行降序排序。 下面是使用OrderByDescending()方法的完整攻略: 格式 var result = collection.OrderByDescending(item => item.Property); 其…

    C# 2023年4月19日
    00
  • 在C#及.NET框架中使用StringBuilder类操作字符串的技巧

    在 C# 和 .NET 框架中,操作字符串时,使用 StringBuilder 类会比字符串连接或操作符等方式更高效。在本攻略中,我将介绍如何使用 StringBuilder 类来更有效地操作字符串。以下是几个技巧: 1. 使用 StringBuilder 类的优点 StringBuilder 是字符串处理中的一种优化方式。在对字符串进行拼接、插入和删除等操…

    C# 2023年5月31日
    00
  • c#基础系列之值类型和引用类型的深入理解

    C#基础系列之值类型和引用类型的深入理解 值类型和引用类型 C#中的变量可以分为值类型和引用类型两种。所谓值类型,就是它们在内存中直接存储它们的值,而引用类型则存储对象在内存中的地址。常见的值类型包括整型、浮点型、布尔型和枚举类型,而常见的引用类型包括类、接口、数组和委托等。 值类型使用堆栈空间存储,可以直接访问,速度较快,但是数据量较小,一般在32位系统中…

    C# 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部