面向对象(C# )

面向对象(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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

图像处理ASIC设计方法 笔记11 像素误差与字长优化

P108 P105 定点误差分析与字长优化 1 像素误差是什么原因导致的? 在本书所说的算法中,像素误差是由几次定点运算累加导致的: 首先由行(列)号与定点正弦/正切值计算出该行(列)的小数平移量,然后将这些小数平移量截取一定字长用来计算插值核,再将这些插值核也截取一…

python统计分析——单变量分布之量化变异度

参考资料&#xff1a;python统计分析【托马斯】 1、极差 极差仅仅是最高值和最低值之间的差异。使用函数为&#xff1a;numpy.ptp()。代码如下&#xff1a; import numpy as npxnp.arange(1,11) np.ptp(x) ptp代表“峰值到峰值”&#xff0c;唯一应该注意的异常值&#xff0c…

LCD屏的应用

一、LCD屏应用 Linux下一切皆文件&#xff0c;我们的LCD屏再系统中也是一个文件&#xff0c;设备文件&#xff1a;/dev/fb0。 如果要在LCD屏显示数据&#xff0c;那我们就可以把数据写入LCD屏的设备文件。 1.显示颜色块 LCD屏分辨&#xff1a;800*480 像素 32位:说明一个像…

HarmonyOS NEXT应用开发—发布图片评论

介绍 本示例将通过发布图片评论场景&#xff0c;介绍如何使用startAbilityForResult接口拉起相机拍照&#xff0c;并获取相机返回的数据。 效果图预览 使用说明 通过startAbilityForResult接口拉起相机&#xff0c;拍照后获取图片地址。 实现思路 创建CommentData类&#…

CSS中如何设置单行或多行内容超出后,显示省略号

1. 设置超出显示省略号 css设置超出显示省略号可分两种情况&#xff1a; 单行文本溢出显示省略号…多行文本溢出显示省略号… 但使用的核心代码是一样的&#xff1a;需要先使用 overflow:hidden;来把超出的部分隐藏&#xff0c;然后使用text-overflow:ellipsis;当文本超出时…

在react中使用tailwindcss

安装tailwind css npm i -D tailwindcssnpm:tailwindcss/postcss7-compat postcss^7 autoprefixer^9安装 CRACO 由于 Create React App 不能让您覆盖原生的 PostCSS 配置&#xff0c;所以我们还需要安装 CRACO 才能配置 Tailwind。 npm install craco/craco配置CRACO 在项目根…

贪心算法(算法竞赛、蓝桥杯)--糖果传递

1、B站视频链接&#xff1a;A31 贪心算法 P2512 [HAOI2008] 糖果传递_哔哩哔哩_bilibili 题目链接&#xff1a;[HAOI2008] 糖果传递 - 洛谷 #include <bits/stdc.h> using namespace std; const int N1000005; int n,a[N],c[N]; long long b,ans;int main(){scanf(&quo…

游戏引擎中的动画基础

一、动画技术简介 视觉残留理论 - 影像在我们的视网膜上残留1/24s。 游戏中动画面临的挑战&#xff1a; 交互&#xff1a;游戏中的玩家动画需要和场景中的物体进行交互。实时&#xff1a;最慢需要在1/30秒内算完所有的场景渲染和动画数据。&#xff08;可以用动画压缩解决&am…

【C语言初阶(五)】数组

❣博主主页: 33的博客❣ ▶文章专栏分类: C语言从入门到精通◀ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; 目录 1. 前言2.一维数组的概念3.一维数组的创建和初始化3.1数组的创建3.2数组的初始化3.3数组的类型 4.一维数组的使用4.1数组下标4.2数组元素打印4.4数组元…

算法——前缀和之除自身以外数组的乘积、和为K的子数组、和可被K整除的子数组、连续数组、矩阵区域和

这几道题对于我们前面讲过的一维、二维前缀和进行了运用,包含了面对特殊情况的反操作 目录 4.除自身以外数组的乘积 4.1解析 4.2题解 5.和为K的子数组 5.1解析 5.2题解 6.和可被K整除的子数组 6.1解析 6.2题解 7.连续数组 7.1题解 7.2题解 8.矩阵区域和 8.1解析 …

Ubuntu 20.04 系统如何优雅地安装NCL?

一、什么是NCL&#xff1f; NCAR Command Language&#xff08;NCL&#xff09;是由美国大气研究中心&#xff08;NCAR&#xff09;推出的一款用于科学数据计算和可视化的免费软件。 它有着非常强大的文件输入和输出功能&#xff0c;可读写netCDF-3、netCDF-4 classic、HDF4、b…

使用PWM实现呼吸灯功能

CC表示的意思位捕获比较&#xff0c;CCR表示的是捕获比较寄存器 占空比等效于PWM模拟出来的电压的多少&#xff0c;占空比越大等效出的模拟电压越趋近于高电平&#xff0c;占空比越小等效出来的模拟电压越趋近于低电平&#xff0c;分辨率表示的是占空比变化的精细程度&#xf…

MATLAB:拟合与插值

一、关于多项式的基本操作 若要求非线性方程的根&#xff0c;则采用fzero, fminbnd函数 二、多项式拟合 clc, clear x0:0.2:10; y0.25*x20*sin(x); plot(x,y,k.,MarkerSize,15) grid on; hold on [p1,s1,mu1]polyfit(x,y,3); %3阶多项式拟合 y1polyval(p1,x,s1,mu1); [p2,s…

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

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

微信小程序开发学习笔记——3.11完成form评论案例的实现逻辑

>>跟着b站up主“咸虾米_”学习微信小程序开发中&#xff0c;把学习记录存到这方便后续查找。 课程连接&#xff1a;https://www.bilibili.com/video/BV19G4y1K74d?p25&vd_source9b149469177ab5fdc47515e14cf3cf74 一、javascript参考手册——splice https://www.…

9.用FFmpeg测试H.264文件的解码时间

1. Essence of Method 要测试对H.264文件的解码时间&#xff0c;可以使用FFmpeg进行操作。FFmpeg是一个开源的多媒体处理工具&#xff0c;可以用来处理视频和音频文件&#xff0c;包括解码H.264文件。以下是使用FFmpeg的命令行来测试解码时间的方法&#xff1a; ffmpeg -i in…

01_什么是深度学习

人工智能包含了机器学习&#xff0c;而深度学习是机器学习的一个分支。 人工智能 试图将通常由人类完成的智力任务自动化—这就是人工智能。 用硬编码的方式实现人工智能&#xff0c;这称作符号主义人工智能Symbolic AI。其中包含专家系统。 机器学习 机器学习是一种替代符…

一个接口白嫖四个AI平台, 五个翻译平台

牙叔教程 简单易懂 家人们, 我这标题起的咋样, 请在评论区打出你对标题的评价 今天我们介绍的仓库是 OneYiGitHub - snailuncle/oneyi: 一个翻译接口, 对接多个平台, one译. 完全免费开源, 没有任何限制, 这是一个翻译接口, 他支持以下平台 五个翻译平台 小牛翻译 小牛翻译开…

sparksession对象简介

什么是sparksession对象 spark2.0之后&#xff0c;sparksession对象是spark编码的统一入口对象&#xff0c;通常我们在rdd编程时&#xff0c;需要SparkContext对象作为RDD编程入口&#xff0c;但sparksession对象既可以作为RDD编程对象入口&#xff0c;在sparkcore编程中可以通…

ARP和DDOS攻击防御介绍

学习目标&#xff1a; 1. 如何利用ARP漏洞进行攻击&#xff1f; 2. 怎样有效地防御ARP攻击&#xff1f; 3. 如何应对DDOS攻击&#xff1f; ARP攻击如何产生&#xff1f; ARP如何进行有效防御&#xff1f; ARP基础工作原理&#xff1a; 交换机会根据mac地址表&#xff0c;进行转…