C#学习笔记 -- 抽象、密封类、静态类、扩展方法

发布时间 2023-05-22 19:43:28作者: Phonk

1、抽象成员

指设计被覆写的函数成员, 特征如下

  • 必须是一个函数成员,

    • 字段常量不可用

    • 属性、索引器、事件、方法都可用

  • 必须用abstracet修饰

  • 不能实现, 代码、访问器用分号表示

abstract public void PrintStuff(string s);
​
abstract pulbic int MyProperty
{
    set;
    get;
}
注意:
  1. 抽象成员必须在派生类中用相应成员覆写, 但不能用virtual修饰

  2. 类似于虚成员, 派生类中抽象成员的实现必须指定override修饰符

  3. 抽象成员与虚成员两者对比

  虚成员 抽象成员
关键字 virtual abstract
实现体 有实现 没有实现分号代替
在派生生类中被覆写 可以oveeride覆写 必须override覆写
成员的类型 方法 方法
  属性 属性
  事件 事件
  索引器 索引器

2、抽象类

设计为被继承的类, 只能被用作其他类的基类

  • 不能创建抽象类的实例

  • 抽象类使用abstract修饰声明

  • 可以包含抽象成员或普通成员

  • 抽象类的成员可以是抽象成员与普通带实现的成员的任意组合

  • 抽象类自己可以派生自另一个抽象类

    //抽象类
    abstract class AbClass
    {
        ...
    }
    ​
    //派生自抽象类的抽象类
    abstract class MyAbClass : AbClass
    {
        
    }
  • 任何派生自抽象类的类必须使用override关键字实现该类所有的抽象成员, 除非他自己也是抽象类

(1)抽象示例

abstract class MyBase
{
    //数据成员
    public int SideLength = 10;
    const int TriangleSideCount = 3;
​
    //抽象属性
    abstract public int MyInt { set; get; }
    //抽象方法
    abstract public void PrintStuff(string s);
​
    //普通方法
    public int PerimeterLength()
    {
        return TriangleSideCount * SideLength;
    }
}
class MyClass : MyBase
{
    private int _myInt;
    public override int MyInt
    { 
        get => _myInt; 
        set => _myInt = value; 
    }
​
    public override void PrintStuff(string s)
    {
        Console.WriteLine(s);
    }
}

3、密封类

  • 密封类只能被用作独立的类, 不能被用作基类, 不能派生

  • 使用sealed关键字密封

sealed class MyClass
{
    ...
}

4、静态类

  • 静态类中所有成员是static的

  • 用于存放不受实例数据影响的数据和函数

  • 常见用法是常数值类、工具类

  • 可以有一个静态的构造函数, 但不能有实例构造函数

    • 静态构造函数不能使用访问修饰符

    • 静态构造函数被编译器编译的时候执行

  • 密封类, 不能被用作基类, 不能派生

  • 可以使用类名和成员名访问, 像访问其他静态成员一样访问静态类的成员

  • 可以使用using static来访问静态类成员

public static class MyUtils
{
    public static float PI = 3.14F;
    public static bool isOdd(int x)
    {
        return x % 2 == 1;
    }
    public static int Times2(int x)
    {
        return x * 2;
    }
    //静态构造函数**不能使用访问修饰符**
    static MyUtils()
    {
        Console.WriteLine("静态工具类");
    }
}
static void Main(string[] args)
{
    Console.WriteLine($"{ MyUtils.Times2(2) }");// 静态工具类, 4
}

5、扩展方法

当你想扩展一个类, 但是这个类不能修改, 比如在第三方类库中, 只要他不是密封的, 就可以把它作为基类并派生自他的类中额外实现这个方法, 就是扩展方法

使用扩展方法的要求

  • 声明扩展方法的类必须为static

  • 扩展方法本身必须声明为static

  • 扩展方法必须包含this作为他的第一个参数类型, 并且在后面跟着它扩展的类的名称

访问修饰符 static class 扩展类
{
    访问修饰符 static 返回值 方法名(this 被扩展类名称 变量)
    {
        ...
    }
}
例子
//被扩展类
public sealed class MyData
{
    private double D1;
    private double D2;
    private double D3;
​
    public MyData(double d1, double d2, double d3)
    {
        D1 = d1;
        D2 = d2;
        D3 = d3;
    }
​
    public double Sum()
    {
        return D1 + D2 + D3;
    }
}
//扩展类
static class EntendMyData
{
    public static double Average(this MyData md)
    {
        return md.Sum() / 3;
    }
​
}
static void Main(string[] args)
{
    MyData myData = new MyData(3.0, 4.0, 5.0);
    double d = myData.Average();
    Console.WriteLine($"增强方法返回值: {d}");
}