C# 面向对象三大特性:封装、继承、多态

 更新时间:2016年03月25日 15:40:30   作者:唯心雨爱  
本文主要介绍了面向对象的三大特性:封装、继承、多态,提供了简单的示例供大家参考和理解。

面向对象有封装、继承、多态这三个特性,面向对象编程按照现实世界的特点来管理复杂的事物,把它们抽象为对象,具有自己的状态和行为,通过对消息的反应来完成任务。这种编程方法提供了非常强大的多样性,大大增加了代码的重用机会,增加了程序开发的速度,将具备独立性特制的程序代码包装起来,修改部分程序代码时不至于会影响到程序的其他部分。

1.封装

每个对象都包含它进行操作所需要的所有信息,封装只公开代码单元的对外接口,而隐藏其具体实现,尽量不对外公开代码。使用封装有很多好处,从设计角度来讲,封装可以对外屏蔽一些重要的信息,比如使用电脑的人只要知道怎么使用电脑就可以,不用知道这些功能具体是怎么实现的;从安全性考虑,封装使对代码的修改更加安全和容易,封装明确的指出了哪些属性和方法是外部可以访问的,这样当需要调整这个类的代码时,只要保证公有属性不变,公有方法的参数和返回值类型不变,那么就可以尽情的修改这个类,而不会影响到程序的其他部分;封装还避免了命名冲突的问题,封装有隔离作用,不同的类中可以有相同名称的方法和属性,但不会混淆,也可以减少耦合。

2.继承

继承可以使用现有类的所有功能,并在无须重新编写原来的类的情况下,对这些功能进行扩展。使用继承而产生的类被称为派生类或子类,而被继承的类则称为基类或超类或父类。继承表示一个类型派生于一个基类型,它拥有该基类型的所有成员字段和函数,其子类是对父类的扩展;接口继承是表示一个类型只继承了函数的签名,没有继承任何实现代码。继承划分了类的层次性,也可以说继承是对类的分组,父类代表的是抽象的类,更常用的类,而子类代表的是更为具体,更为细化的类;继承是实现代码重用、扩展的重要手段。所谓抽象的类是指与具体的事项相联系,但只是表达整体而不是具体概念的类,比如说形状包含正方形、长方形、圆等,这时候形状是一个抽象的概念,相当于一个父类,而正方形、长方形、圆是具体的形状,相当于是子类。

3.多态

多态是指程序中同名的不同方法共存的情况,主要通过子类对父类方法的覆盖来实现多态。这样,不同类的对象可以用同名的方法完成特定的功能,但具体的实现方法却可以不同。比如说形状包含正方形、长方形、圆等,每个形状都有面积和周长,但是不同的形状计算面积和周长的方法都不同。

下面就举个例子来说明封装、继承、多态:

这个例子的基类,就是上面描述概念的时候提到的形状,形状是基类,而这个基类是个抽象的概念,而不是具体的,因此是抽象类,此类包含属性形状名称、输出形状周长和面积的方法以及计算形状周长和面积的抽象方法:

  /// <summary>
  /// 形状基类
  /// </summary>
  public abstract class Shape
  {
    /// <summary> 
    /// 形状名称
    /// </summary>
    public string ShapeName { get; private set; }

    public Shape(string shapeName)
    {
      ShapeName = shapeName;
    }

    /// <summary>
    /// 输出形状周长
    /// </summary>
    public virtual void PrintPerimeter(double perimeter)
    {
      Console.WriteLine(ShapeName + " Perimeter: " + perimeter);
    }

    /// <summary>
    /// 输出形状面积
    /// </summary>
    public virtual void PrintArea(double area)
    {
      Console.WriteLine(ShapeName + " Area: " + area);
    }

    /// <summary>
    /// 计算形状周长
    /// </summary>
    /// <returns></returns>
    public abstract double CalculatePerimeter();

    /// <summary>
    /// 计算形状面积
    /// </summary>
    /// <returns></returns>
    public abstract double CalculateArea();
  }

下面再来看具体的子类,子类是圆,包含属性半径、计算周长和面积的方法:

  /// <summary>
  /// 圆
  /// </summary>
  public class Circle : Shape
  {
    /// <summary>
    /// 圆的半径
    /// </summary>
    public double R { get; set; }

    public Circle()
      : base("Circle")
    {
      this.R = 0;
    }

    /// <summary>
    /// 圆的周长
    /// </summary>
    /// <returns></returns>
    public override double CalculatePerimeter()
    {
      return 2 * Math.PI * R;
    }

    /// <summary>
    /// 圆的面积
    /// </summary>
    /// <returns></returns>
    public override double CalculateArea()
    {
      return Math.PI * R * R;
    }
  }

再来看看长方形,包含属性高度和宽度、计算周长和面积的方法:

public class Rectangle : Shape
  {
    /// <summary>
    /// 长方形的长度
    /// </summary>
    public double Width { get; set; }

    /// <summary>
    /// 长方形的高度
    /// </summary>
    public double Height { get; set; }

    public Rectangle()
      : base("Rectangle")
    {
      Width = 0;
      Height = 0;
    }

    /// <summary>
    /// 长方形的周长
    /// </summary>
    /// <returns></returns>
    public override double CalculatePerimeter()
    {
      return (Width + Height) * 2;
    }

    /// <summary>
    /// 长方形的面积
    /// </summary>
    /// <returns></returns>
    public override double CalculateArea()
    {
      return Width * Height;
    }
  }

以下是调用的代码:

Circle circle = new Circle();
circle.R = 20;

Square square = new Square();
square.Edge = 10;

Rectangle rectangle = new Rectangle();
rectangle.Width = 20;
rectangle.Height = 30;

// 把子类赋给父类,能更好的体现多态性
IList<Shape> shapeList = new List<Shape>();
shapeList.Add(circle);
shapeList.Add(square);
shapeList.Add(rectangle);

foreach (var shape in shapeList)
{
  shape.PrintPerimeter(shape.CalculatePerimeter());
  shape.PrintArea(shape.CalculateArea());
}

在此例子中,输出形状的周长和面积的方法没有太大作用,是因为方法的具体实现比较简单,如果是复杂的方法时会有很大作用。比如说想要实现拖拽功能,每个形状都是可以拖拽的,而且每个形状拖拽的方法都会是一样的,但是想要实现拖拽功能可不像输出这么简单,这时候子类可以继承父类的方法,直接调用。

相关文章

  • C#中使用CAS实现无锁算法的示例详解

    C#中使用CAS实现无锁算法的示例详解

    CAS(Compare-and-Swap)是一种多线程并发编程中常用的原子操作,用于实现多线程间的同步和互斥访问。本文将利用CAS实现无锁算法,需要的可以参考一下
    2023-04-04
  • C#实现DevExpress本地化实例详解

    C#实现DevExpress本地化实例详解

    这篇文章主要介绍了C#实现DevExpress本地化,以实例形式较为详细的分析了DevExpress本地化的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-08-08
  • C#委托与事件初探

    C#委托与事件初探

    事件是委托的一种特殊形式,当发生有意义的事情时,事件处理对象通知过程。接下来通过本文给大家介绍C#委托与事件初探,感兴趣的朋友一起学习吧
    2016-02-02
  • C# 值类型的实现

    C# 值类型的实现

    本文主要介绍了C# 值类型的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-01-01
  • 浅谈Unity脚本生命周期与执行顺序

    浅谈Unity脚本生命周期与执行顺序

    在Unity中,脚本可以理解为附加在游戏对象上的用于定义游戏对象行为的指令代码。必须绑定在游戏对象上才能开始它的生命周期。游戏对象可以理解为能容纳各种组件的容器,游戏对象的所有组件一起决定了这个对象的行为和游戏中的表现
    2021-06-06
  • C#中XmlTextWriter读写xml文件详细介绍

    C#中XmlTextWriter读写xml文件详细介绍

    .NET中包含了很多支持XML的类,这些类使得程序员使用XML编程就如同理解XML文件一样简单。在这篇文章中,我将给出这样的一个类的使用示例,这个类就是XmlTextWriter类
    2013-04-04
  • C# ManualResetEvent用法详解

    C# ManualResetEvent用法详解

    这篇文章主要介绍了C# ManualResetEvent用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • C#开发WinForm根据条件改变DataGridView行颜色

    C#开发WinForm根据条件改变DataGridView行颜色

    这篇文章介绍了C#开发WinForm根据条件改变DataGridView行颜色的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • 使用C#实现将Word 转文本存储到数据库并进行管理

    使用C#实现将Word 转文本存储到数据库并进行管理

    这篇文章主要为大家详细介绍了如何使用C#实现将Word 转文本存储到数据库并进行管理,文中的示例代码讲解详细,需要的小伙伴可以参考一下
    2024-03-03
  • C#利用VS中插件打包并发布winfrom程序

    C#利用VS中插件打包并发布winfrom程序

    这篇文章主要为大家详细介绍了C#利用VS中插件打包并发布winfrom程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08

最新评论