使用 C# 学习面向对象编程:第 4 部分

C# 构造函数

第 1 部分仅介绍了类构造函数的基础知识。 在本课中,我们将详细讨论各种类型的构造函数。

属性类型

  • 默认构造函数
  • 构造函数重载
  • 私有构造函数
  • 构造函数链
  • 静态构造函数
  • 析构函数

请注意构造函数的一些基本概念,并确保你的理解非常清楚,否则你无法理解 OOP(构造函数)。

  1. 构造函数的名称与类名相同。
  2. 构造函数的目的是为了初始化成员变量。
  3. 创建对象时会自动调用构造函数。
  4. 构造函数没有任何返回类型,甚至没有 void。
  5. 如果我们希望自动执行某些代码,那么我们想要执行的代码必须放在构造函数中。
  6. 我们不能明确调用构造函数。

C# 构造函数的一般形式如下。

modifier constructor_name(parameters)
{// constructor body
}

修饰符可以是 private、public、protected 或 internal。构造函数的名称必须是其定义所属类的名称。构造函数可以接受零个或多个参数。零个参数(即无参数)的构造函数称为默认构造函数。请记住,构造函数没有返回类型。

默认构造函数

无参数的构造函数称为默认构造函数。请记住,构造函数没有返回类型。默认构造函数只是调用直接基类的无参数构造函数。

例子

using System;namespace DefaultConstructors
{class Program{static void Main(string[] args){// 创建 car 类的一个实例 sportscar,调用默认构造函数car sportscar = new car();// 打印 sportscar 的 model_Id 属性值Console.WriteLine("Car Model is :{0} ", sportscar.model_Id);// 打印 sportscar 的 Maker_Name 属性值Console.WriteLine("Car Name is :{0}", sportscar.Maker_Name);// 等待用户按下任意键继续执行程序Console.ReadKey();}// 定义 car 类class car{// 私有字段 model,表示车型private int model = -1;// 私有字段 maker,表示制造商private string maker = string.Empty;// 默认构造函数public car(){// 默认构造函数的主体是空的,可以添加初始化逻辑}// 公共只读属性 model_Id,用于获取 model 字段的值public int model_Id{get {return model;}}// 公共只读属性 Maker_Name,用于获取 maker 字段的值public string Maker_Name{get{return maker;}}}}
}

输出


在这个简单的例子中,我们有一个无参数或零参数的构造函数,它是类的默认构造函数。上述示例的输出是空成员变量。

请注意另外一点;如果我们从示例 1 中删除以下代码,则输出是相同的。

public car()
{//Default Constructor
}

这意味着如果我们没有定义类的构造函数,系统将调用默认构造函数。

构造函数重载

首先,我们来讨论一下构造函数重载的目的;对前面的主题有清晰的理解非常重要。在设计 OOP 模型时存在许多复杂的情况,我们需要为类的不同目的初始化一组不同的成员变量。所以我们需要使用构造函数重载。构造函数重载的定义是。

和成员函数一样,构造函数也可以在类中重载。重载的构造函数必须在参数数量和/或参数类型和/或参数顺序上有所不同。

例子

using System;namespace ConstructorsOverloading
{class Program{static void Main(string[] args){// 使用无参数构造函数创建 car 类的一个实例car sportscar1 = new car();// 使用包含两个参数(model 和 maker)的构造函数创建 car 类的一个实例car sportscar2 = new car(2013, "mercedes");// 使用包含两个参数(maker 和 Enginetype)的构造函数创建 car 类的一个实例car sportscar3 = new car("mercedes", 7.8);// 输出使用无参数构造函数创建的 sportscar1 的属性值Console.WriteLine("Constructor without arguments");Console.WriteLine("Car Model is :{0} ", sportscar1.model_Id);Console.WriteLine("Car Name is :{0}", sportscar1.Maker_Name);Console.WriteLine("Car Engine Power is :{0}", sportscar1.Engine);// 输出使用包含两个参数的构造函数创建的 sportscar2 的属性值Console.WriteLine("\nConstructor with two arguments");Console.WriteLine("Car Model is :{0} ", sportscar2.model_Id);Console.WriteLine("Car Name is :{0}", sportscar2.Maker_Name);Console.WriteLine("Car Engine Power is :{0}", sportscar2.Engine);// 输出使用包含两个参数的构造函数创建的 sportscar3 的属性值Console.WriteLine("\nConstructor with two arguments");Console.WriteLine("Car Model is :{0} ", sportscar3.model_Id);Console.WriteLine("Car Name is :{0} ", sportscar3.Maker_Name);Console.WriteLine("Car Engine Power is :{0}", sportscar3.Engine);// 等待用户按下任意键继续执行程序Console.ReadKey();}// 定义 car 类class car{// 私有字段,表示车型private int model = -1;// 私有字段,表示制造商private string maker = string.Empty;// 私有字段,表示发动机类型private double Enginetype = 0.0;// 无参数的默认构造函数public car(){// 默认构造函数的主体是空的,可以添加初始化逻辑}// 包含两个参数(model 和 maker)的构造函数public car(int _model, string _maker){model = _model;maker = _maker;}// 包含两个参数(maker 和 Enginetype)的构造函数public car(string _maker, double _power){maker = _maker;Enginetype = _power;}// 公共属性,用于获取和设置 model 字段的值public int model_Id{get{return model;}set{model = value;}}// 公共属性,用于获取和设置 maker 字段的值public string Maker_Name{get{return maker;}set{maker = value;}}// 公共属性,用于获取和设置 Enginetype 字段的值public double Engine{get{return Enginetype;}set{Enginetype = value;}}}}
}

输出


亲爱的读者,请注意,在这个例子中,我们使用三个不同的对象重载了构造函数,它们是sportscar1、sportscar2 和 sportscar3。

我们注意到

  • sportscar1 没有参数(默认构造函数超出了主题范围)。因此该成员变量具有在初始化时分配的默认值。
  • sportscar2 有两个参数,分别用值 2013 和 Mercedes 初始化成员变量 model 和 name,但没有初始化 Enginetype 变量,因此它具有默认值零。
  • sportscar3 有两个参数,分别用值 Mercedes 和 7.8 初始化成员变量 name 和 Enginetype,但不初始化 model 变量,因此它具有默认值 -1。

私有构造函数

亲爱的读者,我们知道,私有访问修饰符有点特殊。我们既不能创建类的对象,也不能仅使用私有构造函数来继承类。但是,是的,我们可以在类中拥有一组公共构造函数以及私有构造函数,并且公共构造函数可以通过构造函数链从类内部访问私有构造函数。私有构造函数通常用于仅包含静态成员的类中。

using System;namespace PrivateConstructors
{class Program{static void Main(string[] args){// 使用包含 model 参数的构造函数创建 car 类的一个实例car sportscar = new car(2013);Console.Read();}class car{// 公共字段,表示汽车名称public string carname;// 私有的默认构造函数private car(){// 初始化 carname 字段carname = "lamborghini";}// 公共的构造函数,包含一个 int 型的 model 参数// 该构造函数通过 :this() 调用私有的默认构造函数public car(int model) : this(){// 打印车型年份Console.WriteLine("Model Year:{0}", model);// 打印制造商名称Console.WriteLine("Maker Name:{0}", carname);}}}
}

这是一个非常简单的私有构造函数的例子,其中我们使用公共构造函数来调用私有构造函数。

构造函数链

亲爱的读者,当一个构造函数调用同一个类或该类的基类中的另一个构造函数时,这被称为构造函数链。这是避免代码重复的非常有用的技术。

using System;namespace Constructorchaining
{class Program{static void Main(string[] args){// 使用包含 engine 参数的构造函数创建 car 类的一个实例car sportscar = new car(7.8);Console.Read();}class car{// 公共字段,表示汽车名称public string carname;// 公共字段,表示车型年份public int model;// 公共字段,表示发动机类型public double engine;// 包含一个 carname 参数的构造函数public car(string _carname){carname = _carname;}// 包含一个 model 参数的构造函数,并调用包含 carname 参数的构造函数public car(int _model) : this("lamborghini"){model = _model;}// 包含一个 engine 参数的构造函数,并调用包含 model 参数的构造函数public car(double _engine) : this(2013){engine = _engine;// 打印车型年份Console.WriteLine("Model Year:{0}", model);// 打印制造商名称Console.WriteLine("Maker Name:{0}", carname);// 打印发动机类型Console.WriteLine("Engine Type:{0}", engine);}}}
}

在前面的例子中,我们创建了三个不同的类,它们都具有相同的名称 car 和不同的参数类型,每个类都链接前一个类来调用另一个构造函数。

静态构造函数

静态构造函数是一种特殊类型,不采用访问修饰符,也不具有参数。在创建第一个实例或引用任何静态成员之前,会自动调用它以初始化类。静态构造函数不会被直接调用。用户无法控制静态构造函数的执行。

using System;namespace staticconstructors
{class Program{// 定义 car 类public class car{// 静态构造函数static car(){// 打印静态信息,静态构造函数在类第一次被使用前自动调用,并且只调用一次System.Console.WriteLine(@"Lamborghini is the best sports car owned by Audi AG 1998 (its static info)");}// 静态方法 Drivepublic static void Drive(){// 打印稳定公司信息System.Console.WriteLine("Audi is the stable company");}}// 主程序入口点static void Main(){// 调用 car 类的静态方法 Drivecar.Drive();// 再次调用 car 类的静态方法 Drivecar.Drive();// 等待用户按下任意键继续执行程序Console.ReadKey();}}
}

输出


注意,静态构造函数在第一次加载类时被调用。当我们再次调用“car.Drive”时,它不会调用静态构造函数。

析构函数

亲爱的读者,当我们使用 OOP 并在系统内存中创建对象时,需要从系统内存中清除不需要的对象。.NET 框架内置了垃圾收集功能,用于释放未使用对象占用的内存。析构函数是一个与类名同名但以字符 ~ 开头的函数。析构函数不能有任何修饰符 private、public 等。

例子

class car
{// 公共构造函数public car(){// 构造函数,在创建对象实例时调用// 可以在这里进行对象的初始化操作// 比如分配资源,设置初始状态等}// 析构函数~car(){// 析构函数,在对象被垃圾回收时调用// 可以在这里进行对象的清理操作// 比如释放资源,关闭文件,断开网络连接等}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/25893.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WDF驱动开发-电源策略(三)

多组件设备的 KMDF 驱动程序只能将请求发送到处于活动状态的组件。 通常,驱动程序将 I/O 队列分配给组件或组件集。 首先考虑分配给单个组件的队列。 驱动程序在组件变为活动状态时启动队列,并在组件空闲时停止队列。 因此,当 KMDF 调用队列…

生成式人工智能重置:从初期热潮到战略扩展

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

PyTorch学习8:多分类问题

文章目录 前言一、说明二、示例1.步骤2.示例代码 总结 前言 介绍如何利用PyTorch中Softmax 分类器实现多分类问题。 一、说明 1.多分类问题的输出是一个分布,满足和为1. 2.Softmax 分类器 3.损失函数:交叉熵损失 torch.nn.CrossEntropyLoss() 二、…

虚拟化 之一 详解 jailhouse 架构及原理、软硬件要求、源码文件、基本组件

Jailhouse 是一个基于 Linux 实现的针对创建工业级应用程序的小型 Hypervisor,是由西门子公司的 Jan Kiszka 于 2013 年开发的,并得到了官方 Linux 内核的支持,在开源社区中获得了知名度和吸引力。 Jailhouse Jailhouse 是一种轻量级的虚拟化…

微软如何打造数字零售力航母系列科普13 - Prime Focus Technologies在NAB 2024上推出CLEAR®对话人工智能联合试点

Prime Focus Technologies在NAB 2024上推出CLEAR对话人工智能联合试点 彻底改变您与内容的互动方式,从内容的创建到分发 洛杉矶,2024年4月9日/PRNewswire/-媒体和娱乐(M&E)行业人工智能技术解决方案的先驱Prime Focus Techn…

人工智能在医学领域的应用及技术实现

欢迎来到 Papicatch的博客 目录 🍉引言 🍉 医学影像分析 🍈技术实现 🍍数据准备 🍍模型构建 🍍模型训练 🍍模型评估 🍍应用部署 🍈示例代码 🍉 基因…

操作系统真象还原:内存管理系统

第8章-内存管理系统 这是一个网站有所有小节的代码实现,同时也包含了Bochs等文件 8.1 Makefile简介 8.1.1 Makefile是什么 8.1.2 makefile基本语法 make 给咱们提供了方法,可以在命令之前加个字符’@’,这样就不会输出命令本身…

微信小程序使用 “云函数“ 获取 “openid“

文章目录 1.前期准备2.具体操作步骤 1.前期准备 必须使用云开发已经配置好云开发 2.具体操作步骤 1.进入小程序开发工具→在云函数目录上右键→选中新建云函数 创建结束,自动上传(必须确认已经上传才生效) 2.进入对应页面的js文件&#…

QT 信号和槽 信号关联到信号示例 信号除了可以绑定槽以外,信号还可以绑定信号

信号除了可以关联到槽函数,还可以关联到类型匹配的信号,实现信号的接力触发。上个示例中因为 clicked 信号没有参数,而 SendMsg 信号有参数,所以不方便直接关联。本小节示范一个信号到信号的关联,将按钮的 clicked 信号…

【优化过往代码】关于vue自定义事件的运用

【优化过往代码】关于vue自定义事件的运用 需求说明过往代码优化思路优化后代码(Vue2)遇到问题记录 Vue2官方自定义指令说明文档 Vue3官方自定义指令说明文档 需求说明 进入某些页面需要加载一些外部资源,并在资源加载完后进行一些处理&…

【栈】2751. 机器人碰撞

本文涉及知识点 栈 LeetCode2751. 机器人碰撞 现有 n 个机器人,编号从 1 开始,每个机器人包含在路线上的位置、健康度和移动方向。 给你下标从 0 开始的两个整数数组 positions、healths 和一个字符串 directions(directions[i] 为 ‘L’ …

MySQL-数据处理函数

026-distinct去重 select job from emp;加个 distinct 就行了 select distinct job from emp;注意:这个去重只是将显示的结果去重,原表数据不会被更改。 select 永远不会改变原数据 select distinct deptno, job from emp order by deptno asc;027-数…

步态控制之足旋转点(Foot Rotation Indicator, FRI)

足旋转点(Foot Rotation Indicator, FRI) 足旋转点是人形机器人步态规划中的一个关键概念,用于描述步态过程中机器人脚部的旋转和稳定性。FRI 可以帮助确定机器人在行走时是否稳定,以及如何调整步态以保持稳定。下面详细介绍FRI的原理,并举例说明其应用。 足旋转点(FRI…

R语言统计分析——图形的简单示例

参考资料:R语言实战【第2版】 1、示例一 # 绑定数据框mtcars attach(mtcars)# 打开一个图形窗口并生成一个散点图plot(wt,mpg)# 添加一条最优拟合曲线abline(lm(mpg~wt))# 添加标题title("Regression of MPG on weight") # 解除数据框绑定 detach(mtcar…

ES8.13 _bulk报错Malformed content, found extra data after parsing: START_OBJECT解决

在使用elaticsearch8.13.0使用批量创建索引时,根据谷粒中说的es7.9方法去批量操作请求: http://127.0.0.1:9200/shop/_doc/_bulk 注意1:设置header为Content-Type:application/x-ndjson,否则请求报错: {"error": &qu…

机器学习笔记:focal loss

1 介绍 Focal Loss 是一种在类别不平衡的情况下改善模型性能的损失函数最初在 2017 年的论文《Focal Loss for Dense Object Detection》中提出这种损失函数主要用于解决在有挑战性的对象检测任务中,易分类的负样本占据主导地位的问题,从而导致模型难以…

【recast-navigation-js】使用three.js辅助绘制Agent寻路路径

目录 说在前面setAgentTarget绘制寻路路径结果问题其他 说在前面 操作系统:windows 11浏览器:edge版本 124.0.2478.97recast-navigation-js版本:0.29.0golang版本:1.21.5上一篇:【recast-navigation-js】使用three.js辅…

linux:centos7升级libstdc++版本到3.4.26

下载,解压 wget http://www.vuln.cn/wp-content/uploads/2019/08/libstdc.so_.6.0.26.zip unzip libstdc.so_.6.0.26.zip 复制到【/usr/lib64】: cp libstdc.so.6.0.26 /usr/lib64创建软链接 cd /usr/lib64 sln libstdc.so.6.0.26 libstdc.so.6查看一…

Python | Leetcode Python题解之第144题二叉树的前序遍历

题目: 题解: class Solution:def preorderTraversal(self, root: TreeNode) -> List[int]:res list()if not root:return resp1 rootwhile p1:p2 p1.leftif p2:while p2.right and p2.right ! p1:p2 p2.rightif not p2.right:res.append(p1.val)…

机器学习笔记 - LoRA:大型语言模型的低秩适应

一、简述 1、模型微调 随着大型语言模型 (LLM) 的规模增加到数千亿,对这些模型进行微调成为一项挑战。传统上,要微调模型,我们需要更新所有模型参数。这也称为完全微调 (FFT) 。下图详细概述了此方法的工作原理。 完全微调FFT 的计算成本和资源需求很大,因为更新每…