面向对象(C# )

news2024/12/23 19:13:39

面向对象(C# )

文章目录

  • 面向对象(C# )
    • ref 和 out
      • 传值调用和引用调用
      • ref 和 out 的使用
      • ref 和 out 的区别
    • 结构体
    • 垃圾回收GC
    • 封装
      • 成员属性
      • 索引器
      • 静态成员
      • 静态类
      • 静态构造函数
      • 拓展方法
      • 运算符重载
      • 内部类和分布类
    • 继承
      • 里氏替换
      • 继承中的构造函数
      • 装箱拆箱
      • 密封类
    • 多态
      • `virtual`、`override`、`base`
      • 抽象类
      • 抽象方法(纯虚函数)
      • 接口
      • 密封方法

ref 和 out

传值调用和引用调用

void ChangeValue(int value)
{
    a = 3;
}
// 主函数
int a = 11;
ChangeValue(a);
Console.WriteLine(a);

输出:11

传值调用中形参为一个新的临时变量,赋值由实参拷贝而来,只是赋予了与实参一样的值所以在函数体内部修改并不会影响实参

在这里插入图片描述

void Changevalue(int[] array)
{
    array[0] = 22;
}
// 主函数
int[] a = {1, 2, 3};
Changevalue(a);
Console.WriteLine(a[0]);

输出:22

引用调用时,形参拷贝的是实参的地址,二者指向同一个堆空间,所以形参改变会对实参造成影响

void Changevalue(int[] array)
{
    array = new int[] {10, 20, 30};
}
// 主函数
int[] a = {1, 2, 3};
Changevalue(a);
Console.WriteLine(a[0]);

输出:1

单纯的记忆传值调用和引用调用可以改变和不能改变仍然是不太正确的,需要从栈和堆数据存储的角度去分析才行

ref 和 out 的使用

void ChangeValue1(ref int value)
{
    a = 3;
}
void Changevalue2(ref int[] array)
{
    array = new int[] {10, 20, 30};
}
// 主函数
int a = 11;
ChangeValue1(ref a);
Console.WriteLine(a);

int[] a = {1, 2, 3};
Changevalue2(ref a);
Console.WriteLine(a[0]);

输出:3、10

out类似

ref 和 out 的区别

  • ref 传入的变量必须初始化,但是在函数体内部可以不去赋值
  • out传入的变量可以不需要初始化,但是在函数体内部必须赋值

结构体

  • 结构体内部不能直接进行初始化

  • 结构体的存储方式:

    储存结构体中不同类型的数据结构时,会以4个字节为一个单元进行存储,当四个字节容纳不下下一个类型的数据时,编译器会将这个单元中没有存放数据的剩余内存空下,转而存放在下一个单元中

  • 结构体内部不能定义自身

    定义自身这个结构体会导致循环

  • 结构体不能定义无参构造函数

垃圾回收GC

  • 垃圾回收通过遍历堆上被动态分配的对象,识别哪些对象是垃圾选择释放,垃圾是没有被任何变量或对象引用的内容

  • GC只负责堆上的垃圾回收,栈上的内存是系统自动管理的,会自动分配和释放

  • 垃圾回收机制是一种算法(分代算法)

    当第 n(0、1、2)代内存满的时候就触发垃圾回收释放内存,垃圾回收开始时默认堆中所有都是垃圾,从根出发检查引用对象,对可达对象进行标记,未标记的结束不可达对象为垃圾。然后释放未标记对象,搬迁可达对象到下一代

  • 大对象(83kb以上)总是被认为是第二代内存,目的是减少搬迁的性能损耗

封装

成员属性

  • 作用:保护成员变量,为成员属性的获取和赋值添加逻辑处理,解决3p的局限性:get、set方法

  • 访问权限:

    默认与声明属性权限相同

    自定义权限需要低于属性权限,get \ set 不能同时低于属性权限

  • 格式:

    public string Name
    {
        get // 默认继承public
        {
            return name; // 获取
        }
        set
        {
            name = value;// value关键字用来表示外部传入的值
        }
    }
    
  • 自动属性

    public float Heigt // 相当于一个成员属性封装了getset的方法
    {
        get; // 自动获得
        set; // 自动赋值
    }
    

索引器

  • 格式:

    class Person
    {
        private Person[] freinds;
        // 范围权限 返回值 this[参数类型 参数名, 参数类型 参数名, …]
        public Person this[int index]
        {
            get
            {
                return freinds[index];
            }
            set
            {
                freinds[index] = value;
            }
        }
    }
    
  • 索引器可以重载

静态成员

  • 程序开始运行时就会为静态成员分配内存空间,静态成员直到程序结束才会被释放。所有静态成员拥有自己唯一的一块内存区域,在任何地方使用这块内存都会改变

  • 静态成员方法:

    静态函数不能使用非静态成员,因为非静态成员需要对象实例化才有内存分配,所以静态函数只能使用静态成员

  • 常量和静态变量的区别

    相同:都可以直接通过类名加.调用

    不同:const常量不能被修改,必须赋初值

静态类

  • ​ 作用:常用静态成员写在静态类中方便调用,静态类不能被实例化更能体现工具类的唯一性

静态构造函数

  • 特点:

    静态类和普通类都可以使用,不能使用访问修饰符,不能有参数

    只会自动调用一次,当第一次使用这个类时

拓展方法

  • 作用:为现有的非静态类添加新的方法,不需要在类中重新添加方法(我理解就是直接写了一个函数在原本的类中,只是写的方式不同)

  • 特点:

    一定写在静态类中,一定是静态函数

  • 格式:

    static class test // 写在静态类中
    {
        // 访问修饰符 static 返回值 函数名(this 拓展的类型 参数名, 参数类型 参数名, …)
        public static void display(this int value) // 为int拓展一个方法
        {
            Console.WriteLine("int拓展方法");
        }
    }
    

运算符重载

  • 作用:让自定义类和结构体对象可以进行运算

  • 注意:

    一定是静态的公共的方法

    不能使用ref 和 out

    参数至少有一个是自身类型

    条件运算符需要成对出现,例如:== 和 !=> 和 <

    参数个数根据运算符规则定

  • 格式:

    class Point
    {
        int x, y;
        public Point(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
        // public static 返回类型 opeartor 重载运算符(参数列表)
        public static Point operator+(Point p1, Point p2)
        {
            return new Point(p1.x + p2.x, p1.y + p2.y);
        }
    }
    

内部类和分布类

  1. 内部类

    • 在一个类中再申明一个类,表示类之间的层级关系,注意访问修饰符

    • 格式:

      class Person
      {
          public int age;
          
          public class Arm // 公共的才能在外部访问
          {
              public int size;
          }
      }
      
      // 主函数
      Person.Arm arm = new Person.Arm();
      
  2. 分布类

    • 作用:把一个类分成几部分申明,增加程序拓展性

    • 关键字:partial

    • 格式:

      partial class Student
      {
          public bool sex;
          public string name;
      }
      
      partial class Student // 分别申明
      {
          public int number;
          public void Speak(string s)
          {
              Console.WriteLine(s);
          }
      }
      

继承

里氏替换

  • 作用:父类对象装载子类对象

  • isas

    GameObject p = new Player(); // Player是GameObject的子类
    
    if (p is Player) // 判断对象是否是执行类对象,返回bool
    {
        Console.WriteLine("是Player类");
    }
    
    Player p2 = p as Player; // 转换成功返回对象,失败返回null
    
    

继承中的构造函数

  • 创建子类对象时会先调用父类的构造函数,后调用子类的构造函数
  • 子类默认使用父类的无参构造函数,所以需要注意父类的构造函数是否有被有参构造顶掉。或者使用base关键字指定调用父类有参构造

装箱拆箱

  • 装箱:把值类型用引用类型存储,栈内存迁移到堆内存中

  • 拆箱:把引用类型用值类型存储,堆内存迁移到栈内存中

  • 例子:

    object obj = 1; // 装箱
    int i = (int)obj; // 拆箱
    

密封类

  • 作用:让类无法再被继承

  • 例子:

    sealed class Father // 无法再被继承
    {
    }
    

多态

virtualoverridebase

  • 作用:让继承同一父类的子类,在执行相同方法时有不同的表现
  • virtual(虚函数)、override(重写)、base(父类)

抽象类

  • 抽象是把多个事物相同的内容抽取出来,但是自己本身是没有实际实体的,(水果没有实体,苹果才是实体)
  • 不能被实例化,抽象类必须重写其中的抽象方法
  • 仍然可以用父类容器装载子类对象

抽象方法(纯虚函数)

  • 只能在抽象类中申明

  • 没有方法体

  • 不能是私有的,因为子类需要重写

  • 继承后必须重写(override)抽象方法

接口

  • 一个类可以继承多个接口,接口用于描述有共同方法或属性的类,成员方法没有方法体,只是定义共同需要的方法至少需要什么,不能包含成员变量,可以有方法、属性、索引器、事件

  • 默认修饰符是public,因为需要被继承后的类重写所以不能设置私有

  • 接口也不能被实例化,但是可以做父类容器装载子类对象

  • 代码

    interface IPereson // 命名规则前缀I
    {
    }
    

密封方法

  • 作用:让虚方法或抽象方法之后不能再被重写
  • 关键字:sealed

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

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

相关文章

XCTF:level0[WriteUP]

PWN入门题目&#xff1a;XCTF攻防世界的level0 使用file、checksec命令查看文件详细信息 这是一个64bit的ELF文件&#xff08;后面编写EXP需要用到&#xff09; 从checksec中展示的信息看&#xff0c;该二进制文件只开启了NX&#xff08;数据执行保护&#xff09; 这样的话就…

【好书推荐-第十二期】《并行计算与高性能计算》

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公众号&#xff1a;洲与AI。 &#x1f388; 本文专栏&#xff1a;本文收录…

信息系统项目管理(第四版)(高级项目管理)考试重点整理 第14章 项目沟通管理(四)

博主2023年11月通过了信息系统项目管理的考试&#xff0c;考试过程中发现考试的内容全部是教材中的内容&#xff0c;非常符合我学习的思路&#xff0c;因此博主想通过该平台把自己学习过程中的经验和教材博主认为重要的知识点分享给大家&#xff0c;希望更多的人能够通过考试&a…

2、FreeRTOS之队列管理

xQueueReceive() 用于从队列中接收 ( 读取&#xff09;数据单元。接收到的单元同时会从队列 中删除。 xQueuePeek() 也是从从队列中接收数据单元&#xff0c;不同的是并不从队列中删出接收到 的单元。 uxQueueMessagesWaiting()用于查询队列中当前有效数据单元个数。 写队列任…

springboot项目学习-瑞吉外卖(1)

第一天任务如下&#xff1a; 建立基本架构完成登录、退出功能 注意&#xff1a;本博客没有使用网上教程里的mybatis-plus&#xff0c;使用的是mybatis&#xff1b;数据库连接池也没有使用教程里的druid&#xff0c;使用的是spring自带的连接池 基本架构 common包&#xff1a;存…

主干网络篇 | YOLOv8更换主干网络之ShuffleNetV2(包括完整代码+添加步骤+网络结构图)

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。ShuffleNetV2是一种轻量级的神经网络架构&#xff0c;用于图像分类和目标检测任务。它是ShuffleNet的改进版本&#xff0c;旨在提高模型的性能和效率。ShuffleNetV2相比于之前的版本&#xff0c;在保持模型轻量化的同时&am…

spc x-bar 正态分布 echarts demo

使用echarts,elementUi,vue编写的spc分析的demo示例. 含x-bar和正态分布图,同一数据可以互转 chart.vue <template><div class"app-container"><el-row><el-col :span"4" class"button-container"><el-button clic…

Linux学习——线程池的创建

一&#xff0c;线程池的作用和优点 线程池使用的是一种池化技术&#xff0c;当我们要使用线程时采用线程池创建就一次创建多个线程&#xff0c;在调用当前线程时就让其它的线程进行等待。这样做的优点有如下几点&#xff1a; 1&#xff0c;提高响应速度。线程池提前把线程创建好…

使用Laravel框架创建项目

1.使用Composer创建项目 composer create-project --prefer-dist laravel/laravel blog "5.5.*" 如下图所以&#xff0c;Laravel框架就安装完成了 安装完成后&#xff0c;进入到项目文件夹根目录&#xff0c;打开终端&#xff0c;输入php artisan serve运行项目 p…

Linux操作系统裸机开发-环境搭建

一、配置SSH服务 1、下载安装ssh服务输入以下命令 sudo apt-get install nfs-kernel-server portmap2、建立一个供SSH服务使用的文件夹如以下命令 mkdir linux 3、完成前两步之后需要将其文件路径放到/etc/exports文件里输入以下命令&#xff1a; sudo vi /etc/esports 4.打…

天天说微服务,天天开发RESTful API,那你知道RESTful API是什么东东吗?

RESTful API&#xff08;Representational State Transfer&#xff09;是一种基于网络的架构风格&#xff0c;用于设计和构建Web服务。它是一种轻量级的架构&#xff0c;可以通过HTTP协议进行通信&#xff0c;并支持各种数据格式&#xff0c;例如JSON和XML。 在现代的Web应用程…

三极管工作原理及典型电路

一、三极管的工作原理 三极管&#xff0c;也被称为双极型晶体管或晶体三极管&#xff0c;是一种电流控制元件。主要功能是将微弱的电信号放大成幅度值较大的电信号&#xff0c;工作在饱和区和截止区时同时也被用作无触点开关。 根据结构和工作原理的不同&#xff0c;三极管可以…

Jmeter---分布式

分布式&#xff1a;多台机协作&#xff0c;以集群的方式完成测试任务&#xff0c;可以提高测试效率。 分布式架构&#xff1a;控制机&#xff08;分发任务&#xff09;与多台执行机&#xff08;执行任务&#xff09; 环境搭建&#xff1a; 不同的测试机上安装 Jmeter 配置基…

代码随想录|Day22|回溯02|216.组合总和III、17.电话号码的字母组合

216.组合总和III 本题思路和 77. 组合 类似&#xff0c;在此基础上多了一个和为 n 的判断。 class Solution:def combinationSum3(self, k: int, n: int) -> List[List[int]]:def backtrack(start, path, currentSum):# 递归终止条件&#xff1a;到达叶子节点# 如果和满足条…

HTTPS证书很贵吗?

首先&#xff0c;我们需要明确一点&#xff0c;HTTPS证书的价格并不是一成不变的&#xff0c;它受到多种因素的影响。其中最主要的因素包括证书的类型、颁发机构以及所需的验证级别。 从类型上来看&#xff0c;HTTPS证书主要分为单域名证书、多域名证书和通配符证书。单域名证书…

mmz批量多页抓取数据-AES.CBC算法-爬虫

目标&#xff1a;mmz多页下载 方法&#xff1a;加一个for循环实现多页的下载 问题&#xff1a;浏览器传输服务器时对页码参数做了加密处理 解决方法&#xff1a; 1、判断加密算法模式&#xff08;mmz是AES-CBC算法&#xff09; 2、找到加密的key和iv 代码&#xff1a; i…

基于springboot+vue实现疫情防控物资调配系统项目【项目源码】计算机毕业设计

基于springbootvue实现疫情防控物资调配系统演示 B/S结构的介绍 在确定了项目的主题和研究背景之后&#xff0c;就要确定本系统的架构了。主流的架构有两种&#xff0c;一种是B/S架构&#xff0c;一种是C/S架构。C/S的全称是Client/Server&#xff0c;Client是客户端的意思&am…

HarmonyOS NEXT应用开发—Grid和List内拖拽交换子组件位置

介绍 本示例分别通过onItemDrop()和onDrop()回调&#xff0c;实现子组件在Grid和List中的子组件位置交换。 效果图预览 使用说明&#xff1a; 拖拽Grid中子组件&#xff0c;到目标Grid子组件位置&#xff0c;进行两者位置互换。拖拽List中子组件&#xff0c;到目标List子组件…

插入排序:一种简单而有效的排序算法

插入排序&#xff1a;一种简单而有效的排序算法 一、什么是插入排序&#xff1f;二、插入排序的步骤三、插入排序的C语言实现四、插入排序的性能分析五、插入排序的优化六、总结 在我们日常生活和工作中&#xff0c;排序是一种非常常见的操作。比如&#xff0c;我们可能需要对一…

MasterPDF 强大的多功能软件

哈喽呀&#xff0c;我是苏音今天给大家带来一期免费PDF的工具&#xff0c;可以实现你的大部分需求。 最近有PDF文档相关的的需求&#xff0c;但是之前一直在用WPS&#xff0c;就看能不能实现下面两个功能 1.导出指定页的PDF 2.在某一页PDF中加入指定图片 虽然WPS可以实现将…