C# 类和继承(构造函数的执行)

article/2025/8/14 15:16:23

构造函数的执行

在前一章中,我们看到了构造函数执行代码来准备一个即将使用的类。这包括初始化类的静
态成员和实例成员。在这一章,你会看到派生类对象有一部分就是基类对象。

  • 要创建对象的基类部分,需要隐式调用基类的某个构造函数。
  • 继承层次链中的每个类在执行它自己的构造函数体之前执行它的基类构造函数。

例如,下面的代码展示了类MyDerivedClass及其构造函数声明。当调用该构造函数时,它在
执行自己的方法体之前会先调用无参数的构造函数MyBaseClass()。

class MyDerivedClass:MyBaseClass
{MyDerivedClass() //构造函数调用基类构造函数MyBaseClass(){...}
}

构造的顺序如图8-11所示。创建一个实例的过程中,完成的第一件事是初始化对象的所有
实例成员。在此之后,调用基类的构造函数,然后才执行该类自己的构造函数体。

image
例如,在下面的代码中,MyField1和MyField2的值在调用基类构造函数之前会分别设置为5
和0。

class MyDerivedClass:MyBaseClass
{int MyField1=5;   //成员初始化int MyField2;     //成员初始化public MyDerivedClass()  //执行构造函数体{...}
}class MyBaseClass
{public MyBaseClass()   //调用基类构造函数{...}
}

警告 强烈反对在构造函数中调用虚方法。在执行基类的构造函数时,基类的虚方法会调用派
生类的覆写方法,但这是在执行派生类的构造函数方法体之前。因此,调用会在派生类
完全初始化之前传递到派生类。

构造函数初始化语句

默认情况下,在构造对象时,将调用基类的无参数构造函数。但构造函数可以重载,所以基
类可能有一个以上的构造函数。如果希望派生类使用一个指定的基类构造函数而不是无参数构造
函数,必须在构造函数初始化语句中指定它。

有两种形式的构造函数初始化语句。

  • 第一种形式使用关键字base并指明使用哪一个基类构造函数。
  • 第二种形式使用关键字this并指明应该使用当前类的哪一个构造函数。
    基类构造函数初始化语句放在冒号后面,跟在类的构造函数声明的参数列表后面。构造函数
    初始化语句由关键字base和要调用的基类构造函数的参数列表组成。

基类构造函数初始化语句放在冒号后面,跟在类的构造函数声明的参数列表后面。构造函数
初始化语句由关键字base和要调用的基类构造函数的参数列表组成。
例如,下面的代码展示了类MyDerivedClass的构造函数。

  • 构造函数初始化语句指明要使用有两个参数的基类构造函数,并且第一个参数是一个
    int,第二个参数是一个string。
  • 基类参数列表中的参数必须在类型和顺序方面与已定的基类构造函数的参数列表相匹配。

image
当声明一个不带构造函数初始化语句的构造函数时,它实际上是带有base()构造函数初始化
语句的简写形式,如图8-12所示。这两种形式是语义等价的。

等价的构造函数形式
另外一种形式的构造函数初始化语句可以让构造过程(实际上是编译器)使用当前类中其他
的构造函数。例如,如下代码所示的myclass类包含带有一个参数的构造函数。但这个单参数的
构造函数使用了同一个类中具有两个参数的构造函数,为第二个参数提供了一个默认值。

image
这种语法很有用的另一种情况是,一个类有好几个构造函数,并且它们都需要在对象构造的
过程开始时执行一些公共的代码。对于这种情况,可以把公共代码提取出来作为一个构造函数,
被其他所有的构造函数用作构造函数初始化语句。由于减少了重复的代码,实际上这也是推荐的
做法。

你可能会觉得还可以声明另外一个方法来执行这些公共的初始化,并让所有构造函数来调用
这个方法。由于种种原因这不是一个好办法。首先,编译器在知道方法是构造函数后能够做一些
优化。其次,有些事情必须在构造函数中进行,在其他地方则不行。比如之前我们学到的readonly
字段只可以在构造函数中初始化。如果尝试在其他方法(即使这个方法只被构造函数调用)中
初始化一个readonly字段,会得到编译错误。不过要注意,这一限制仅适用于readonly字段,
不适用于readonly属性。

回到公共构造函数,如果这个构造函数可以用作一个有效的构造函数,能够初始化类中所有
需要初始化的东西,那么完全可以把它设置为public的构造函数。
但是如果它不能完全初始化一个对象怎么办?此时,必须禁止从类的外部调用构造函数,因
为那样的话它只会初始化对象的一部分。要避免这个问题,可以把构造函数声明为private,而
不是public,然后只让其他构造函数使用它,如以下代码所示:

class MyClass
{readonly int firstVar;readonly double secondVar;public string UserName;public int UserIdNumber;private MyClass()   //私有构造函数执行其他构造{                   //函数共用的初始化firstVar=20;secondVar=30.5;}public MyClass(string firstName):this  //使用构造函数初始化语句{UserName=firstName;UserIdNumber=-1;}public MyClass(int idNumber):this()   //使用果子函数初始化语句{UserName="Annonymous";UsserIdNumber=idNumber;}
}

类访问修饰符

类可以被系统中其他类看到并访问。这一节阐述类的可访问性。虽然我们会在解说和示例中使用类,因为类是本书中一直阐述的内容,但可访问性规则也适用于以后将阐述的其他类型。
可访问(accessible)有时也称为可见(visible),它们可以互换使用。类的可访问性有两个
级别:public和internal。

  • 标记为public的类可以被系统内任何程序集中的代码访问。要使一个类对其他程序集可
    见,使用public访问修饰符,如下所示:

image

  • 标记为internal的类只能被它自己所在的程序集内的类看到。(第1章介绍过,程序集既
    不是程序也不是DLL。第22章将阐述程序集的细节。)
  • 这是默认的可访问级别,所以,除非在类的声明中显式地指定修饰符public,否则程
    序集外部的代码不能访问该类。
  • 可以使用internal访问修饰符显式地声明一个类为内部的。

image

图8-13阐明了internal和public类从程序集的外部的可访问性。类MyClass对左边程序集
内的类不可见,因为myClass被标记为internal。然而,类OtherClass对于左边的类可见,因为
它被标记为public。

其他程序集中的类可以访问公有类但不能访问内部类


http://www.hkcw.cn/article/XQUIiwhAWe.shtml

相关文章

79. Word Search

题目描述 79. Word Search 回溯 代码一&#xff0c;使用used数组 class Solution {vector<pair<int,int>> directions{{0,1},{0,-1},{1,0},{-1,0}};vector<vector<bool>> used; public:bool exist(vector<vector<char>>& board, st…

大模型备案中语料安全详细说明

《AIGC安全要求》针对语料安全&#xff0c;在语料来源授权合法、安全评估核验、不良语料类型三个方面提出了重点要求&#xff0c;具体要求包括&#xff1a; 1、授权合法 语料的来源需要有合法的、明确的授权&#xff0c;确保其符合“授权、同意、告知”的合法性原则。根据语料…

汽车安全:功能安全FuSa、预期功能安全SOTIF与网络安全Cybersecurity 解析

汽车安全的三重防线&#xff1a;深入解析FuSa、SOTIF与网络安全技术 现代汽车已成为装有数千个传感器的移动计算机&#xff0c;安全挑战比传统车辆复杂百倍。 随着汽车智能化、网联化飞速发展&#xff0c;汽车电子电气架构已从简单的分布式控制系统演变为复杂的移动计算平台。现…

【云安全】以Aliyun为例聊云厂商服务常见利用手段

目录 OSS-bucket_policy_readable OSS-object_public_access OSS-bucket_object_traversal OSS-Special Bucket Policy OSS-unrestricted_file_upload OSS-object_acl_writable ECS-SSRF 云攻防场景下对云厂商服务的利用大同小异&#xff0c;下面以阿里云为例 其他如腾…

[MongoDB] 认识MongoDB以及在Windows和Linux上安装MongoDB

初次学习&#xff0c;如有错误还请指正 目录 MongoDB简介 体系结构 数据模型 MongoDB的特点 Windows中的安装 Linux系统中的安装启动和连接 MongoDB简介 MongoDB是一个开源、高性能、无模式的文档型数据库&#xff0c;当初的设计就是用于简化开发和方便扩展&#xff0c;…

iOS —— UI 初探

简介 第一次新建时&#xff0c;你可能会好奇。为什么有这么多文件&#xff0c;他们都有什么用&#xff1f; App 启动与生命周期管理相关 文件名 类型 作用 main.m m 程序入口&#xff0c;main() 函数定义在这里 AppDelegate.h/.m h/m App 启动/进入后台/退出等全局事…

【设计模式-3.4】结构型——代理模式

说明&#xff1a;说明&#xff1a;本文介绍结构型设计模式之一的代理模式 定义 代理模式&#xff08;Proxy Pattern&#xff09;指为其他对象提供一种代理&#xff0c;以控制对这个对象的访问&#xff0c;属于结构型设计模式。&#xff08;引自《设计模式就该这样学》P158&am…

C++: STL简介与string类核心技术解析及其模拟实现

目录: 一.STL二.string类一、创建对象的6种构造方式二、常用接口解析1. 容量操作2. 元素访问3. 修改操作4. 字符串操作 三.string模拟实现一、设计基础&#xff1a;类结构与资源管理二、拷贝控制&#xff1a;深拷贝的三种实现1. 传统深拷贝2. 现代写法&#xff08;推荐&#xf…

【复杂网络分析】什么是modularity?

在复杂网络研究中&#xff0c;modularity&#xff08;模块化程度或模块度&#xff09; 是衡量网络社区结构&#xff08;即节点分组为紧密连接的社区&#xff0c;而社区间连接稀疏&#xff09;的重要指标。它由Mark Newman和Michelle Girvan于2004年提出&#xff0c;广泛用于评估…

模型训练相关的问题

与模型训练相关问题 损失函数Cross entropy loss的含义训练数据有脏数据,怎么处理?loss一直不收敛,怎么排查?连续值的特征怎么处理后输入到机器学习模型当中损失函数Cross entropy loss的含义 在深度学习中,可以看作通过概率分布q ( x )(预测概率)表示概率分布p ( x ) …

【项目记录】登录认证(下)

1 过滤器 Filter 刚才通过浏览器的开发者工具&#xff0c;可以看到在后续的请求当中&#xff0c;都会在请求头中携带JWT令牌到服务端&#xff0c;而服务端需要统一拦截所有的请求&#xff0c;从而判断是否携带的有合法的JWT令牌。 那怎么样来统一拦截到所有的请求校验令牌的有…

Portainer安装指南:多节点监控的docker管理面板-家庭云计算专家

背景 Portainer 是一个轻量级且功能强大的容器管理面板&#xff0c;专为 Docker 和 Kubernetes 环境设计。它通过直观的 Web 界面简化了容器的部署、管理和监控&#xff0c;即使是非技术用户也能轻松上手。Portainer 支持多节点管理&#xff0c;允许用户从一个中央控制台管理多…

基于微信小程序的垃圾分类系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;没有什么华丽的语言&#xff0…

【前端面经】百度一面

写在前面&#xff1a;面经只是记录博主遇到的题目。每题的答案在编写文档的时候已经有问过deepseek&#xff0c;它只是一种比较普世的答案&#xff0c;要学得深入还是靠自己 Q&#xff1a; <html><style>.a {background-color: red;width: 200px;height: 100px;}…

智能体觉醒:AI开始自己“动手”了-自主进化开启任务革命时代

1. 智能体&#xff1a;AI从“工具”到“伙伴”的关键跃迁 1.1 什么是智能体&#xff1f; 智能体&#xff08;Agent&#xff09;是AI的“进化版”——它不再局限于生成文字或图像&#xff0c;而是能像人类一样“规划任务”“调用工具”甚至“协同合作”。例如&#xff0c;一个…

STM32软件spi和硬件spi

核心观点 本文主要介绍了SPI通信的两种实现方式&#xff1a;软件SPI和硬件SPI。详细阐述了SPI通信协议的基本概念、硬件电路连接方式、移位示意图、时序基本单元以及四种工作模式。同时&#xff0c;对W25Q64模块进行了详细介绍&#xff0c;包括其硬件电路、框图以及操作注意事…

MongoDB数据库命令

目录 一、数据库操作 二、集合&#xff08;表&#xff09;操作 三、文档&#xff08;记录&#xff09;CRUD 操作 1、插入文档 2、查询文档 3、更新文档 4、删除文档 四、聚合操作 1、单目的聚合操作 2、聚合管道 3、MapReduce编程 五、索引管理操作 六、用户权限管…

当前最新IDEA社区版安装当前最新的tomcat插件:集成SmartTomcat,提升开发效率

当前最新IDEA社区版安装当前最新的tomcat插件&#xff1a;集成SmartTomcat&#xff0c;提升开发效率 【下载地址】当前最新IDEA社区版安装当前最新的tomcat插件 该项目为开发者提供了详细的指南&#xff0c;帮助在IntelliJ IDEA社区版中安装SmartTomcat插件&#xff0c;以便更高…

Docker 实战——部署 Nginx 镜像容器、Tomcat 镜像容器、MySQL 镜像容器

#设置基础镜像 FROM dadoha/centos7.4.1708 #维护该镜像的用户信息 MAINTAINER zhangsan #安装相关依赖包 RUN yum clean all ; yum -y install proc-devel net-tools gcc zlib zlib-devel make openssl-devel wget #下载并解压nginx软件包 RUN wget http://nginx.org/d…

Nginx和Tomcat实现负载均衡群集部署应用

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;Linux高级管理专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; ⏰️创作时间&…