Unity-C# (面向对象三大特性)

这篇具有很好参考价值的文章主要介绍了Unity-C# (面向对象三大特性)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

面向对象(C# )

ref 和 out

传值调用和引用调用

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

输出:11

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

Unity-C# (面向对象三大特性),Unity,c#,算法,unity

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

输出:22

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

Unity-C# (面向对象三大特性),Unity,c#,算法,unity

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

输出:1

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

Unity-C# (面向对象三大特性),Unity,c#,算法,unity

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个字节为一个单元进行存储,当四个字节容纳不下下一个类型的数据时,编译器会将这个单元中没有存放数据的剩余内存空下,转而存放在下一个单元中

    Unity-C# (面向对象三大特性),Unity,c#,算法,unity

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

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

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

垃圾回收GC

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

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

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

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

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

Unity-C# (面向对象三大特性),Unity,c#,算法,unity

封装

成员属性

  • 作用:保护成员变量,为成员属性的获取和赋值添加逻辑处理,解决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常量不能被修改,必须赋初值

单例模式

一个类对象在整个生命周期中,有且只会有一个该对象存在,不能在外部实例化,通过类名得到唯一的对象

class Test
{
    private static Test instance = new Test(); // 唯一静态对象
    public static Test Instance // 公共属性提供外部获取
    {
        get
        {
            return instance;
        }
    }
    private Test() // 私有构造函数,不能在外部实例化
    {}
}

静态类

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

静态构造函数

  • 特点:

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

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

拓展方法

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

  • 特点:

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

  • 格式:

    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,因为需要被继承后的类重写所以不能设置私有

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

  • 代码文章来源地址https://www.toymoban.com/news/detail-844813.html

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

密封方法

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

到了这里,关于Unity-C# (面向对象三大特性)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 面向对象三大特性之一——継承(上篇)

    目录 前文 一.什么是継承? 1.1 継承的定义 1.2 継承的格式 1.2.1 継承的使用格式 1.2.2 継承关系和访问限定符 二,基类和派生类对象复制转换 三,継承中的作用域 四,派生类/子类中的默认成员函数 六,継承与友元  六,継承与静态成员 总结 本篇文章主要是详解面向对象三大

    2024年02月03日
    浏览(40)
  • 【java】面向对象三大特性之多态

            俗话说的好,“一龙生九子,九子各不同”,这句话就蕴含了面向对象三大特性之一的多态的思想。那么多态具体有什么特点呢,就由博主来带大家梳理一下吧🤔 目录 一、什么是多态 二、重写 三、向上转型和向下转型 1、向上转型 2、向下转型 四、多态的优缺点

    2024年03月15日
    浏览(75)
  • 【JAVASE】面向对象程序三大特性之一( 封装)

    ✅作者简介:大家好,我是橘橙黄又青,一个想要与大家共同进步的男人😉😉n 🍎个人主页:再无B~U~G-CSDN博客 目标: 1.包的使用 2.static的使用 3. 代码块概念以及分类 面向对象程序三大特性:封装、继承、多态 。而类和对象阶段,主要研究的就是封装特性。何为

    2024年04月17日
    浏览(49)
  • Java面向对象03——三大特性之继承

    继承就是 Java 允许我们用 extends ,让一个类与另一个类建立起一种父子关系; 被继承的类称为父类(基类、超类),继承父类的类都称为子类(派生类), 当子类继承父类后,就可以直接使用父类公共的属性和方法了 当子类继承父类后,就可以直接使用父类公共的属

    2024年04月27日
    浏览(44)
  • 【javaSE】 面向对象程序三大特性之继承

    目录 为什么需要继承 继承的概念 继承的语法 注意事项  父类成员访问 子类中访问父类的成员变量 子类和父类不存在同名成员变量 子类和父类成员变量同名 访问原则 子类中访问父类的成员方法 成员方法名字不同 总结: 成员方法名字相同 总结: super 注意事项 子类

    2024年02月14日
    浏览(36)
  • 面向对象的三大特性之继承(C++)

    概念   继承机制是面向对象编编程使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称为派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。继承是类设计层次的复用。 定

    2024年02月06日
    浏览(49)
  • Python教程(21)——面向对象编程的三大特性

    在Python中,面向对象编程是一种核心的编程思想。Python被称为“一切皆对象”的语言,因为在Python中,几乎所有的数据都被视为对象。这包括数字、字符串、列表、函数等基本类型,还有自定义的类和对象。 Python中的面向对象编程提供了类(Class)来创建对象(Object)。类是

    2024年02月03日
    浏览(52)
  • 【JAVASE】带你了解面向对象三大特性之一(继承)

    ✅作者简介:大家好,我是橘橙黄又青,一个想要与大家共同进步的男人😉😉 🍎个人主页:再无B~U~G-CSDN博客 Java 中使用类对现实世界中实体来进行描述,类经过实例化之后的产物对象,则可以用来表示现实中的实体,但是现实世界错综复杂,事物之间可能会存在一些关

    2024年04月09日
    浏览(52)
  • 【JAVASE】带你了解面向对象三大特性之一(多态)

    ✅作者简介:大家好,我是橘橙黄又青,一个想要与大家共同进步的男人😉😉 🍎个人主页:再无B~U~G-CSDN博客 多态的概念:通俗来说,就是多种形态, 具体点就是去完成某个行为,当不同的对象去完成时会产生出不同 的状 态。 总的来说:同一件事情,发生在不同对象

    2024年04月14日
    浏览(71)
  • 【Go语言快速上手(四)】面向对象的三大特性引入

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:Go语言专栏⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习更多Go语言知识   🔝🔝 GO语言也支持面向对象编程,但是和传统的面向对象语言(如CPP)有明显的区别,GO并不是纯粹的面对对象编程语言.所以说GO是支持面向对

    2024年04月26日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包