3.4C#引用类型之类(Class)

1.类声明

class 类名<类型参数> : 基类, 基接口
{
    //类体
}

2.继承

派生类只能有一个直接基类。但是,因为一个基类本身可能继承自另一个类,所以一个类可能会间接继承多个基类。省略基类相当于从 object 类型继承。

派生类会隐式获取基类的所有成员(除了基类的静态构造函数、实例构造函数、析构函数),所以无需在派生类再书写继承过来的基类成员,但您还可以在派生类中新增更多成员。

3.创建对象

构造函数非必须有参数。

//使用构造函数创建类的对象。
类型 变量 = new 类型();
//使用构造函数和对象初始值设定项创建对象。
类型 变量 = new 类型() {...};

4.对象初始值设定项(Object Initializer)

使用 对象初始值设定项(Object Initializer),可以在new运算符创建对象时向对象的任何可访问 字段、属性、索引器 分配值,而无需显式调用类型的构造函数。

编译器通过首先访问构造函数,然后处理对象初始值设定项。因此,如果构造函数在类中声明为 private,则需要 public 对象初始值设定项将失败。

//属性
public class Cat
{
    // Auto-implemented properties.
    public int Age { get; set; }
    public string Name { get; set; }

    public Cat()
    {
    }

    public Cat(string name)
    {
        this.Name = name;
    }
}


Cat cat = new Cat { Age = 10, Name = "Fluffy" };
Cat sameCat = new Cat("Fluffy"){ Age = 10 };
//索引器
public class Matrix
{
    private double[,] storage = new double[3, 3];

    public double this[int row, int column]
    {
        // The embedded array will throw out of range exceptions as appropriate.
        get { return storage[row, column]; }
        set { storage[row, column] = value; }
    }
}


var identity = new Matrix
{
    [0, 0] = 1.0,
    [0, 1] = 0.0,
    [0, 2] = 0.0,

    [1, 0] = 0.0,
    [1, 1] = 1.0,
    [1, 2] = 0.0,

    [2, 0] = 0.0,
    [2, 1] = 0.0,
    [2, 2] = 1.0,
};

5.访问成员

//调用外部类
外部类.静态数据成员
外部类.静态函数成员()

//调用同一个类可省略类
[类.]静态数据成员
[类.]静态函数成员()

//调用外部类的对象
对象.实例数据成员
对象.实例函数成员()

//调用同一个类可省略this
[this.]实例数据成员
[this.]实例函数成员()

6.this

this 关键字指向当前实例。

7.析构(Deconstruct)类

可定义一个或多个Deconstruct方法来析构类的实例,该方法返回void,每个要析构的值由方法签名中的out参数表示。

然后可以使用=赋值运算符析构类的实例。

using System;

public class Person
{
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
    public string City { get; set; }
    public string State { get; set; }

    public Person(string fname, string mname, string lname,
                  string cityName, string stateName)
    {
        FirstName = fname;
        MiddleName = mname;
        LastName = lname;
        City = cityName;
        State = stateName;
    }

    // Return the first and last name.
    public void Deconstruct(out string fname, out string lname)
    {
        fname = FirstName;
        lname = LastName;
    }

    public void Deconstruct(out string fname, out string mname, out string lname)
    {
        fname = FirstName;
        mname = MiddleName;
        lname = LastName;
    }

    public void Deconstruct(out string fname, out string lname,
                            out string city, out string state)
    {
        fname = FirstName;
        lname = LastName;
        city = City;
        state = State;
    }
}

public class ExampleClassDeconstruction
{
    public static void Main()
    {
        var p = new Person("John", "Quincy", "Adams", "Boston", "MA");

        // Deconstruct the person object.
        var (fName, lName, city, state) = p;
        Console.WriteLine($"Hello {fName} {lName} of {city}, {state}!");
    }
}
// The example displays the following output:
//    Hello John Adams of Boston, MA!

8.抽象(abstract)类

abstract class 类名
{
    public abstract 返回类型 F();
}

抽象类不必包含具有签名定义但没有实现的抽象方法,但包含抽象方法的类必须是抽象类。

如果非抽象类是从抽象类派生的,则非抽象类必须包含所有继承的抽象成员的实际实现,从而重写这些抽象成员。

抽象类被用作一个基类,用途是提供一个可供多个派生类共享的通用基类定义。

抽象类不能被实例化,可以通过非抽象派生类来实例化。

9.密封(sealed)类

public sealed class 类名
{
    public sealed override 返回类型 F() { }
}

一个类可以通过将自身或成员声明为 sealed 来阻止其它类继承自它或继承自它的任何成员。

密封类不能用作基类,它也不能是抽象类。

密封类可以被实例化。

10.静态(static)类

static class 
{
    //类体
}

static修饰符用于声明为 静态类

静态类是隐式密封的,因此不能被继承。

静态类只能包含静态成员,没有实例成员,因此不能被实例化。 

11.分部(partial)类

拆分一个的定义到两个或更多的文件中,每个文件包含类型或方法定义的一部分,编译应用程序时将把所有部分组合起来。

public partial class Employee
{
    public void DoWork()
    {
    }
}

public partial class Employee
{
    public void GoToLunch()
    {
    }
}
//合并后
public class Employee
{
    public void DoWork()
    {
    }

    public void GoToLunch()
    {
    }
}

所有部分都必须使用 partial 关键字。各个部分必须具有相同的可访问性。

类名和泛型类型参数在所有的分部类型定义中都必须匹配。泛型类型可以是分部的。每个分部声明都必须以相同的顺序使用相同的参数名。

在某一分部定义中声明的任何类、结构或接口成员可供所有其他部分使用。

如果任意部分声明继承基类型,则整个类型都将继承该基类型。

如果将任意部分声明为抽象的,则整个类型都被视为抽象的。

如果将任意部分声明为密封的,则整个类型都被视为密封的。

各个部分可以指定不同的基接口,最终类型将实现所有分部声明所列出的全部接口。

所有分部类型定义中合并内容还包括:注释、特性。

原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/csharp/csharplang/7867.html

(2)
上一篇 2021年3月4日 02:52
下一篇 2021年3月4日 22:39

相关推荐

  • 3.6C#引用类型之字符串(String)

    1.字符串声明 2.获取字符串长度 3.访问字符串 4.字符串连接 可使用 + 运算符 或 += 运算符连接字符串。 5.字符串内插(Interpolation) 若要将字符串标识为字符串内插(Interpolation),可在该字符串 ” 左引号前面加上 $ 美元符号( $ 和 ” 之间不能有任何…

    C#语言教程 2021年3月6日
    04820
  • 2.2C#数据成员之常量(Constant)

    1.常量声明和初始化 const 字段只能在该字段的声明中初始化,不能用任何构造函数对其赋值,后期也不能修改其值。 常量是隐式的静态常量,所以声明时不需要使用 static 关键字。 常量值可以是C# 内置类型(包括数字、布尔、字符串、null等,不包括  System.Object),不…

    C#语言教程 2021年2月2日
    03880
  • 3.1C#语言的命名空间(Namespace)

    1.命名空间声明 C# 10 中可使用文件范围的命名空间声明,一个文件中的所有类型都在一个命名空间中。文件范围的命名空间不能声明嵌套的命名空间或第二个文件范围的命名空间。 可以在两个或多个声明中定义一个命名空间。 2.using指令 2.1导入其它命名空间的类型 2.2创建命名空间别名 using 指令的声明…

    C#语言教程 2021年3月1日
    06530

发表回复

登录后才能评论