C# Class专题自学备用,仅供参考

Class 专题

类的表现形式

静态类

关键字:static,主要用于工具类(如各类公式、基本不会发生变化的 构成的接口集)

特点:
  1. 不能被实例化,即不可new
  2. 不允许有实例构造函数,只允许存在一个静态构造函数
  3. 仅包含静态成员或常量
  4. 不能被继承
  5. 静态构造函数不会执行,也不可被调用

抽象类

关键字:abstract

特点:
  1. 不能被实例化,即不能使用new关键字创建实例

  2. 支持构造函数

    public abstract class MyClass
    {
        public MyClass(){} //构造函数
        static MyClass(){} //静态构造函数
    }
    
  3. 抽象类可被继承,但静态构造函数只执行一次,其他构造函数则根据实例数调用相应的次数

    public abstract class MyClass
    {
        public MyClass(){} //构造函数
        static MyClass(){} //静态构造函数
    }
    
    public abstract class MyClass1 : MyClass
    {
        public MyClass1(){} //构造函数
        static MyClass1(){} //静态构造函数
    }
    
    public class MyClass2 : MyClass
    {
        public MyClass2(){} //构造函数
        static MyClass2(){} //静态构造函数
    }
    
  4. 抽象类允许虚函数

  5. 抽象类中的函数若声明为abstract,则该函数不允许有结构体,其子类必须显示覆盖该方法

    public abstract class MyClass
    {
        public abstract void MyFunc(); // 抽象函数不许有函数结构体{}
    }
    
    public class MyClass1 : MyClass
    {
        public override void MyFunc()
        {
           Debug.log("子类必须显示覆盖父类的抽象方法"); 
        } 
    }
    
    
    

密封类

关键字:sealed,用于防止重写某些类或接口,影响功能的稳定

特点
  1. 不能被继承,但可以继承别的类或接口
  2. 不能声明为抽象类
  3. 类内的成员函数不得声明成sealed

泛型类

用于处理一组功能一样,仅类型不同的任务

特点:
  1. 声明是可以不指定具体的类型,但是在new实例化时,必须指定T类型,T不仅可以为数据类型,还可以为类

  2. 可指定泛型类型约束(关键字:where)

    泛型类型约束种类描述
    where T : classT必须是一个类
    where T : structT必须是一个结构类型
    where T : new()T必须要有一个无参数的构造函数
    where T : NameOfBaseClassT必须继承名为NameOfBaseClass的类
    where T :NameOfInterfaceT必须实现名为NameOfInterface的接口
  3. 如果子类也是泛型的,那么继承的时候可以不指定具体类型,反之,则需要指定

    //父类为泛型
    public class Father<T,X> 
    {
        
    }
    
    //子类为泛型,可不指定具体类型
    public class Son1<T,X> : Father<T,X> 
    {
        
    }
    
    //子类非泛型,需要指定具体的类型,如int, string
    public class Son2 : Father<int, string> 
    {
        
    }
    
    //子类可增加自己所需的泛型
    public class Son3<T,X,Y,A> : Father<T,X> 
    {
        
    }
    
    public class Son4<T,X> : Father<int, string> 
    {
        
    }
    
基础用法举例
//需求:在类里面定义一个数组,让这个类具备设置数据和访问数据的能力
//分析:数组中的数据可能是多种类型,所以需要用到泛型,本示例以int、string和类为例
public class MyArray<T>
{
    //声明一个数组,类型为泛型T
    public T[] myArray;


    //在其初始化的时候设置数组长度
    public MyArray(int size)
    {
        myArray = new T[size];
    }

    //设置数据,需要数组的下标,以及数组的值
    public void Set(int index, T value)
    {
        myArray[index] = value;
    }

    //访问数据,只需要数组的下标
    public T Get(int index)
    {
        return myArray[index];
    }
}

public class MyClass
{
    public int a;

    public MyClass(int value)
    {
        this.a = value;
    }
}

public class TClass : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        //int型
        MyArray<int> myArrayInt = new MyArray<int>(5);
        myArrayInt.Set(0, 1);
        myArrayInt.Set(1, 2);
        int aInt = myArrayInt.Get(0);
        int bInt = myArrayInt.Get(1);
        Debug.LogFormat("Int型的第一、二个值分别为{0}、{1}", aInt, bInt);

        //string型
        MyArray<string> myArrayString = new MyArray<string>(5);
        myArrayString.Set(0, "一");
        myArrayString.Set(1, "二");
        string aString = myArrayString.Get(0);
        string bString = myArrayString.Get(1);
        Debug.LogFormat("String型的第一、二个值分别为{0}、{1}", aString, bString);

        //类
        MyClass myClass1 = new MyClass(7);
        MyClass myClass2 = new MyClass(8);
        MyArray<MyClass> myArrayClass = new MyArray<MyClass>(5);
        myArrayClass.Set(0, myClass1);
        myArrayClass.Set(1, myClass2);
        MyClass aClass = myArrayClass.Get(0);
        MyClass bClass = myArrayClass.Get(1);
        Debug.LogFormat("Class的第一、二个值分别为{0}、{1}", aClass.a, bClass.a);

    }
}

接口

interface + name 约束一些行为规范时,可以用接口

特点
  1. 只声明接口函数,不包含实现
  2. 访问修饰符必须是public
  3. 接口成员函数的定义是派生类的责任,接口提供了派生类应遵循的标准结构
  4. 接口不可被实例化,即不可new
  5. 接口可继承其他接口,允许单一、多个继承
接口与抽象类的区别
区别接口抽象类
变量不允许允许
构造函数不允许允许
函数实现不允许允许
访问修饰符默认情况:public默认情况:private
访问修饰符不允许为private若为抽象函数,则不能为private,反之则可以
多重继承允许继承多个接口不允许继承多个类
接口与抽象类的相同点
  1. 都不允许实例化
  2. 支持只声明函数,不包含实现
  3. 关于派生类,都必须去实现接口或抽象类的方法

Struct结构体

struct + name{},

是***值类型***数据结构。它使得一个单一变量可以存储各种数据类型的相关数据。

特点:
  1. 结构体可带有方法、字段、索引、属性、运算符方法和时间
  2. 结构体可定义构造函数,但不能定义析构函数。不能定义无参构造函数。无参构造函数是自动定义的,且不能被改变
  3. 结构体不能继承其他的结构或类,但是可以实现一个或多个接口
  4. 结构不能作为其他结构或类的基础结构
  5. 结构成员不能指定为 abstract、virtual、protect
  6. 结构体不能通过new来实例化
struct和class的区别
区别structclass
构造函数不允许定义无惨构造函数,只允许定义有参构造函数都可以
析构函数不允许允许
函数修饰符不允许声明为virtual虚函数、protect函数允许
类型修饰符不允许声明为abstract抽象结构体允许
普通变量声明的全局普通变量,不能在声明式直接赋值,只能在构造函数中赋值都可以
readonly只能在构造函数中赋值都可以
继承不能互相继承,只能继承接口可以继承类和接口
访问变量给成员变量显示赋值,可直接访问,若不通过new初始化,则不可以直接访问其内部变量(除const)必须先实例化new
new是值类型,不会在堆上分配内存,仅仅是调用结构体的构造函数进行初始化是引用类型,会在堆上分配内存,并调用结构体的构造函数进行初始化
struct和class的区别相同点
  1. 都支持静态构造函数
  2. 都支持自定义函数
  3. 结构体和类对***const***修饰的变量使用方式一样
  4. 访问函数:结构体变量和类对象必须进行初始化,才可访问

值类型和引用类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PkSTDwnR-1670585924958)(D:\书籍\笔记\C#\相关图片\值类型和引用类型.jpg)]

类型转换

is

可检测值类型和引用类型,成功返回true,否则返回false

as

首先判断原数据类型是否是目标数据类型,不是的话,编译器直接报错

as转换成功,返回源数据类型存储的数据类型,否则返回空

强制类型转换(显式类型转换)
  1. ***高精度***转换为***低精度***需要强制类型转换

    (注)若想转换成功,需要高精度数据类型的位数 <= 低精度数据类型的位数

    int a = 123;		// 高精度
    short b = (short)a;	// 低精度
    
自动类型转换(隐式类型转换)
  1. ***低精度***转换为***高精度***需要强制类型转换,系统自动转换
short a = 1234; // 低精度
int b = a;		// 高精度

装箱和拆箱

装箱

值类型转换成引用类型,发生GC(内存分配)

拆箱

引用类型转换成值类型

int a = 20;
object b = (object)a;//装箱,显式转换
object b = a;		 //装箱,隐式转换	

int c = (int) b;	 //拆箱

堆和栈

a; // 低精度


#### 自动类型转换(隐式类型转换)

1. ***低精度***转换为***高精度***需要强制类型转换,系统自动转换

```c#
short a = 1234; // 低精度
int b = a;		// 高精度

装箱和拆箱

装箱

值类型转换成引用类型,发生GC(内存分配)

拆箱

引用类型转换成值类型

int a = 20;
object b = (object)a;//装箱,显式转换
object b = a;		 //装箱,隐式转换	

int c = (int) b;	 //拆箱

堆和栈

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值