C#基础之面向对象编程(二)

news/2024/11/7 5:34:10/

总目录


文章目录

  • 总目录
  • 前言
  • 一、概述
    • 1. 定义
    • 2. 面向对象的三大特性
  • 二、封装
    • 1. 定义
    • 2. 属性
  • 三、继承
    • 1. 定义
    • 2. 继承的使用
    • 3. base 和this
  • 四、多态
    • 1. 定义
    • 2. 重写和重载
    • 3. 多态性的实现
      • 1、静态多态性
      • 2、动态多态性
    • 4. 向上转型和向下转型
      • 1、定义
      • 2、语法格式
      • 3、案例
  • 结语


前言

本文主要用于供自身复习使用,上篇文章首先回顾了C#中的数据类型,数据转换以及数据之间进行运算的运算符,然后回顾了基本的流程控制语句if else,switch for,while等,最后还回顾了数组,枚举,结构体,类,接口,抽象类等基本的数据结构,本文将从面向对象编程的角度进一步的回顾相关知识。


一、概述

1. 定义

把现实世界中的对象使用代码的形式表现出来

2. 面向对象的三大特性

  • 封装 - 体现了代码的可维护性
  • 继承 - 体现了代码的可扩展性
  • 多态 - 体现了代码的灵活性

二、封装

1. 定义

  • 封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中"。
  • 在面向对象程序设计方法论中,封装是为了防止对实现细节的访问。
  • 通俗说法:使用class,将变量和方法,包装到一个独立的程序单元中,一旦封装后,变量称之为属性,方法称为行为

2. 属性

变量封装到类中,分为两种形式:
字段:变量的声明,使用_标识
属性:使用get 和set 进行包装,一般首字母大写,符合驼峰命名规则

代码如下(示例):

    class UserInfo{private string _id;public string Id{get { return _id; }set { _id = value; }}}

关于get 和set 的理解如下:

 		private int _id;public int Id{get//返回给外界的值,供外界调用读取的值  {if (_id < 0)//如果内部逻辑得出的_id<0,则同一返回0{_id = 0;}return _id; }set//供给外界设置的窗口,如果设置为private,外界将无法为该属性赋值,为只读属性{if (value>999)//value 即是外界赋予的值,可以通过set来处理外界的值{_id = 999;//如果外界赋予的值大于999,则统一修正为999}_id = value;}}

三、继承

1. 定义

  • 一个类通过申明沿用另一个类中,非私有的属性和行为。
  • 被继承的类称之为 基类或父类,继承类称之为 派生类或子类

继承的可扩展性体现在:继承的时候,子类不仅沿用父类中非私有的属性和行为,还可增加自己特有的内容,另外通过重写和重载,同样实现了内容的扩展

注意 : 继承的时候,一个类只能有一个父类

2. 继承的使用

继承我们通过冒号(:)表示,表现形式如下:

class Shape{public void setWidth(int w){width = w;}public void setHeight(int h){height = h;}protected int width;protected int height;}// 派生类class Rectangle: Shape{//通过 Rectangle: Shape 的形式表示:Rectangle继承自Shape //由于Rectangle继承自Shape,就有了Shape中非私有的width和height变量以及setWidth和setHeightpublic int getArea(){return (width * height);}}class RectangleTester{static void Main(string[] args){Rectangle Rect = new Rectangle();Rect.setWidth(5);Rect.setHeight(7);// 打印对象的面积Console.WriteLine("总面积: {0}",  Rect.getArea());Console.ReadKey();}}

3. base 和this

  • 一般当前类使用this,子类使用父类的使用base
  • 构造函数时不可继承的 ,只能去调用;因此子类使用父类的构造函数的时候,需要使用base

在这里插入图片描述

  • 子类继承了父类的非私有的属性和行为,因此子类使用父类的非私有属性和行为的时候使用this
  • 子类调用父类的方法,可使用base,也可使用this。主要是使用base的时候我们知道去父类找该方法,指向更明确
  • 大多情况下,都省略的this和base关键字

四、多态

1. 定义

  • 在面向对象编程范式中,多态性往往表现为"一个接口,多个功能"。
    多态就是同一个接口,使用不同的实例而执行不同操作,如图所示
    在这里插入图片描述

2. 重写和重载

重写:在子类中重新编写父类方法

重写具有相同的方法名、参数列表以及返回值

重写的方式有如下两种:

  • 使用new 重写(也称覆盖)
  • 使用vitual 和override 重写
    class Animal{public void Eat(){Console.WriteLine("吃");}//定义虚方法,需子类重新,另外abstract 自带virtual属性public virtual void Action(){Console.WriteLine("行动");}}class Monkey:Animal{//通过new 重写父类的方法public new void Eat(){Console.WriteLine("猴子吃香蕉");}//通过override重写public override void Action(){base.Action();//重写后,可以通过base调出父类的原方法执行,也可不调用,重新实现Console.WriteLine("猴子上树");}}

重载:就是在同一个类中有多个同名方法,但是方法的参数列表不同

重载可以实现一种方法的多种实现方式,有利于程序的扩展。

    class Animal{public void Eat(){Console.WriteLine("吃");}public void Eat(string food){Console.WriteLine($"吃{food}");}public void Eat(int num,string food){Console.WriteLine($"一天吃{num}{food}");}public int Eat(string name ,int num,string food){Console.WriteLine($"{name}一天吃{num}{food}");//如猴子一天吃三次香蕉,(假如一次2根),返回一天总量return num * 2 ;}}

3. 多态性的实现

  • 多态性可以是静态的或动态的。
  • 在静态多态性中,函数的响应是在编译时发生的。
  • 在动态多态性中,函数的响应是在运行时发生的。
  • 多态是建立在封装和继承的基础上的

1、静态多态性

静态多态性通过函数(方法)重载和运算符重载实现。
函数重载上面已经介绍了,这里介绍以下运算符的重载。

C# 允许用户定义的类型通过使用 operator 关键字定义静态成员函数来重载运算符。
注意必须用public修饰且必须是类的静态的方法。

运算符的重载可为用户自定义的对象实现运算。

运算符重载的使用案例如下:

    class Rect{public double Width { get; set; }public double Length { get; set; }public static Rect operator+(Rect a,Rect b){Rect rect = new Rect();rect.Width = a.Width + b.Width;rect.Length = a.Length + b.Length;return rect;}public double GetArea(){return Width * Length;}}class Program{static void Main(string[] args){Rect RectA = new Rect() { Width=2.5,Length=4};Rect RectB = new Rect() { Width=3.5,Length=6};Console.WriteLine($"RectA的面积{RectA.GetArea()}");Console.WriteLine($"RectB的面积{RectB.GetArea()}");//如果没有通过operator+ 进行重载,RecA是无法和RecB进行相加的操作的Rect RectC = RectA+RectB;Console.WriteLine($"RectC的面积{RectC.GetArea()}");Console.ReadLine();}}

下图罗列了可重载和不可重载的运算符
在这里插入图片描述
这里解释以下成对重载,也就是说,如果我们重载了==,那么就必须连同 != 一起重载

详细使用如下:

    class Program{static void Main(string[] args){Student student = new Student(15, "小栗子");var student1 = student + 3;var student2 = student + "新手小白";Console.WriteLine(student1.ToString());//年龄 = 18,名称 = 小栗子Console.WriteLine(student2.ToString());//年龄 = 15,名称 = 新手小白小栗子Student stu1 = new Student(12, "小张子");Student stu2 = new Student(18, "小王五");var stu3 = stu1 - stu2;Console.WriteLine(stu3.ToString()); //年龄 = 6,名称 = 小张子和小王五Console.ReadLine();}}public class Student{public int Age { get; set; }public string Name { get; set; }public Student(){ }public Student(int age, string name){this.Age = age;this.Name = name;}# 形如 public static Student operator +(int c1, int c2) 是会报错的# 因为这样,就与需要操作的Student类毫无关联!# 二元运算符的参数之一必须是包含类型(参数c1、c2中有一个类型为Student即可).//+重载 ,操作年龄public static Student operator +(Student stu, int c2){return new Student(stu.Age + c2, stu.Name);}//+重载 ,增加姓名前缀public static Student operator +(Student stu, string prefix){return new Student(stu.Age, prefix+stu.Name); }//重载运算符"-",计算两个学生的年龄差.public static Student operator -(Student a, Student b){return new Student(Math.Abs(a.Age - b.Age), $"{a.Name}{b.Name}");}//重写ToString方法,格式化输出public override string ToString(){return $"年龄={Age},名称={Name}";}}

2、动态多态性

动态多态性是通过 抽象类、接口 和 虚方法 实现的。

  • 抽象类 和 接口 综合案例如下:
    abstract class Animal{public abstract void Run();//abstract 自带virtual属性}interface IFly//接口默认public,通常接口命名以 I 开头{void Fly();//飞翔这项功能作为一个接口,并不是所有动物都可以的}class Monkey : Animal{public override void Run(){Console.WriteLine("猴子在奔跑!");}}class Pig : Animal{public override void Run(){Console.WriteLine("小猪在狂奔!");}}//同一个方法(“接口”)Run,在不同的实例中有不同的实现就是多态的一种体现# 这里需要注意:当一个子类同时继承抽象类,类,和接口的时候,抽象类,类必须排在接口前面class Brid : Animal, IFly{public void Fly(){Console.WriteLine("奋飞的小鸟!");}public override void Run(){Console.WriteLine("愤怒的小鸡在奔跑!");}}
  • 虚方法
    class Worker{public virtual void DoWork(){Console.WriteLine("做工作!");}}class WorkerA : Worker{public override void DoWork(){base.DoWork();Console.WriteLine("编写项目ppt");}}

4. 向上转型和向下转型

1、定义

  • 向上转型:将子类对象转为父类对象。此处父类对象可以是接口,抽象类。
  • 向下转型:把父类对象转为子类对象。
  • 向上转型和向下转型 就是针对同一个继承链中的两个类型的相互转换

2、语法格式

  • 向上转型格式:父类类型 上转型变量 = new 子类类型();
  • 向下转型格式:子类类型 下转型变量 = (子类类型)父类类型变量;

3、案例

    class Worker{public virtual void DoWork(){Console.WriteLine("做工作!");}}class WorkerA : Worker{public override void DoWork(){base.DoWork();Console.WriteLine("编写项目ppt");}public void Avocation(){Console.WriteLine("WorkA的业余爱好");}}class Program{static void Main(string[] args){//向上转型Worker worker= new WorkerA();worker.DoWork();/*  输出:做工作!编写项目ppt*///worker.Avocation();//注意这里会报错:因为上转型变量不是可调用 子类中扩展的方法的,只能调用两者共有的方法//向下转型//这种情况是不合理的,因为相当于用父类替换子类,当时子类会有扩展,不可能完全替换//Worker wo = new Worker();//WorkerA wa = (WorkerA)wo;Worker wo = new WorkerA();WorkerA wa = (WorkerA)wo;wa.Avocation();//这样是可行的,因为自始至终实例都是WorkAwo.DoWork();/*WorkA的业余爱好做工作!编写项目ppt*/Console.ReadLine();}}

结语

以上就是本文的内容,希望以上内容可以帮助到您,如文中有不对之处,还请批评指正。


参考资料:
C# 运算符重载
菜鸟教程-C# 运算符重载


http://www.ppmy.cn/news/31721.html

相关文章

HTML看这一篇就够啦,HTML基础大全,可用于快速回顾知识,面试首选

HTML 1.基础 1.1DOCTYPE <!DOCTYPE> 文档类型声明&#xff0c;作用就是告诉浏览器使用哪种HTML版本来显示网页。 <!DOCTYPE html> 这句代码的意思是: 当前页面采取的是 HTML5 版本来显示网页. 注意: 声明位于文档中的最前面的位置&#xff0c;处于 标签之前。 …

Git使用教程:最详细、最傻瓜、最浅显、真正手把手教

GITGIT版本控制版本控制的意义分布式图形化客户端环境搭建仓库的操作分支使用场景命令远程仓库操作生成公钥命令冲突忽略列表的配置时机配置方式版本回退练习&#xff1a;GIT 版本控制 把文件系统中的文件&#xff0c;按照修改的版本进行记录&#xff0c;进行管理的操作。 版…

小黑子—Java从入门到入土过程:第二章

Java零基础入门2.0Java系列第二章1. 注释和关键字2. 字面量3. 变量3.1 基本用法3.2 使用方式3.3 注意事项4. 变量练习5. 计算机中的数据存储5.1 计算机的存储规则5.2 进制5.3 进制间转换二进制转十八进制转十十六进制转十十进制转其他进制6. 数据类型7. 定义变量的练习8. 标识符…

运动蓝牙耳机什么牌子好,比较好的运动蓝牙耳机推荐

现在市面上的运动蓝牙耳机越来越多&#xff0c;在选择耳机的时候应该如何入手呢&#xff1f;最重要的是需要按照自己的需求来选择&#xff0c;但在耳机的配置上不能忽视的是耳机的防水等级&#xff0c;运动耳机对防水等级的要求更高&#xff0c;这样能够更好地防御汗水浸湿耳机…

【C#进阶】C# 反射

序号系列文章11【C#基础】C# 预处理器指令12【C#基础】C# 文件与IO13【C#进阶】C# 特性文章目录前言1&#xff0c;反射的概念2&#xff0c;使用反射访问特性3&#xff0c;反射的用途4&#xff0c;反射的优缺点比较4.1 优点&#xff1a;4.2 缺点&#xff1a;5&#xff0c;System…

Jetpack Compose 学习汇总

关于 Jetpack Compose 的学习本想只是简单的快速学习一下&#xff0c;结果万万没想到&#xff0c;竟然一下子折腾了好几个月。。。 下面将之前记录的 Jetpack Compose 相关的学习博文进行一个汇总链接整理&#xff0c;方便我以后自己查阅&#xff0c;也希望能帮到一些有正在学…

Web漏洞-XXE漏洞(详细)

XXE漏洞XXE全称为XML External Entity Injection即XMl外部实体注入漏洞原理&#xff1a;XXE漏洞发生在应用程序解析XML输入时&#xff0c;没有禁止外部实体的加载&#xff0c; 导致用户可以控制外部的加载文件&#xff0c;造成XXE漏洞。XXE漏洞触发点往往是可以上传xml文件的位…

实现VOC数据集与COCO数据集格式转换

实现VOC数据集与COCO数据集格式转换2、将voc数据集的xml转化为coco数据集的json格式2、COCO格式的json文件转化为VOC格式的xml文件3、将 txt 文件转换为 Pascal VOC 的 XML 格式<annotation><folder>文件夹目录</folder><filename>图片名.jpg</file…