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#的静态工厂方法与构造函数相比有哪些优缺点

    C#中的静态工厂方法与构造函数相比,有以下优缺点: 优点 更具有表现力:静态工厂方法可以有任意的返回类型,它们的函数名可以更好地反映其作用,可以将多个构造函数重载的实现合并为一个方法。 更加可读性:静态工厂方法可以通过名称来描述对象的创建语义,比如CreateInstance、FromValue、CreateValidator等等,让用户更容易理解对象的含义…

    C# 2023年6月3日
    00
  • Android仿微信菜单(Menu)(使用C#和Java分别实现)

    Android仿微信菜单(Menu)攻略 1. 简介 本攻略旨在介绍如何使用C#和Java分别实现Android仿微信菜单。该菜单在Android应用开发领域中较为常见,本攻略将从以下几个方面进行讲解: 什么是Android仿微信菜单? C#实现Android仿微信菜单的步骤及示例 Java实现Android仿微信菜单的步骤及示例 2. Android仿微信…

    C# 2023年5月15日
    00
  • C#使用winform实现进度条效果

    下面我将详细讲解“C#使用winform实现进度条效果”的完整攻略。 1. 确定进度条控件 首先,我们需要确定要使用哪种进度条控件。WinForm提供了两种不同风格的进度条控件:ProgressBar和TrackBar。其中,ProgressBar控件是一个水平或垂直的进度条,它通常用于向用户报告操作的进度。TrackBar控件则允许用户在一个给定范围内拖拽…

    C# 2023年6月6日
    00
  • 基于AForge实现C#摄像头视频录制功能

    基于AForge实现C#摄像头视频录制功能攻略 1. 背景介绍 AForge是一款基于C#的开源机器视觉框架,支持多种图像处理和机器学习算法。除此之外,AForge还提供了许多常用的工具类,如IO、数字信号处理、多媒体等。本文将介绍如何使用AForge框架实现C#摄像头视频录制功能。 2. 实现步骤 2.1 引用AForge框架 在Visual Studio…

    C# 2023年6月3日
    00
  • 区分WCF与WebService的异同、优势

    区分WCF与WebService的异同、优势 WCF(Windows Communication Foundation)和WebService都是用于构建分布式应用程序的技术。它们都可以实现跨平台、跨语言的通信,但在实现方式、功能和性能等方面存在一些差异。本文将详细讲解WCF和WebService的异同、优势,并提供两个示例。 WCF与WebService的…

    C# 2023年5月15日
    00
  • NetCore 使用 Swashbuckle 搭建 SwaggerHub

    什么是SwaggerHub? Hub 谓之 中心, 所以 SwaggerHub即swagger中心. 什么时候需要它? 通常, 公司都拥有多个服务, 例如商品服务, 订单服务, 用户服务, 等等, 每个服务都有自己的environment, endpoint, swagger schema. 然而这些信息都分散在各处, 如果能集中在一个地方展示出来, 就能减…

    C# 2023年4月18日
    00
  • ASP.NET Core 3.0迁移的完美避坑指南

    ASP.NET Core 3.0迁移的完美避坑指南 ASP.NET Core 3.0是一个重大的版本更新,其中包含了许多新功能和改进。但是,由于这些更改,迁移现有的ASP.NET Core应用程序可能会遇到一些问题。在本攻略中,我们将提供一些有用的提示和技巧,以帮助您成功地将现有的ASP.NET Core应用程序迁移到3.0版本。 1. 更新NuGet包 在…

    C# 2023年5月16日
    00
  • C#反射调用dll文件中的方法操作泛型与属性字段

    C#反射可以让我们在运行时根据需要动态加载并调用其他程序集中的对象、函数和属性等,这对于某些需要动态处理对象的场景非常有用。而操作泛型和属性字段是其中的常见需求。下面是一份完整攻略: 一、加载dll文件 使用反射前,需要首先通过Assembly.Load()方法或者Assembly.LoadFile()方法或Assembly.LoadFrom()方法来加载需…

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