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.抽象(abstract)类
abstract class 类名
{
public abstract 返回类型 F();
}
抽象类不必包含具有签名定义但没有实现的抽象方法,但包含抽象方法的类必须是抽象类。
如果非抽象类是从抽象类派生的,则非抽象类必须包含所有继承的抽象成员的实际实现,从而重写这些抽象成员。
抽象类被用作一个基类,用途是提供一个可供多个派生类共享的通用基类定义。
抽象类不能被实例化,可以通过非抽象派生类来实例化。
7.密封(sealed)类
public sealed class 类名
{
public sealed override 返回类型 F() { }
}
一个类可以通过将自身或成员声明为 sealed
来阻止其它类继承自它或继承自它的任何成员。
密封类不能用作基类,它也不能是抽象类。
密封类可以被实例化。
8.静态(static)类
static class
{
//类体
}
static
修饰符用于声明为 静态类。
静态类是隐式密封的,因此不能被继承。
静态类只能包含静态成员,没有实例成员,因此不能被实例化。
9.分部(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
关键字。各个部分必须具有相同的可访问性。
类名和泛型类型参数在所有的分部类型定义中都必须匹配。泛型类型可以是分部的。每个分部声明都必须以相同的顺序使用相同的参数名。
在某一分部定义中声明的任何类、结构或接口成员可供所有其他部分使用。
如果任意部分声明继承基类型,则整个类型都将继承该基类型。
如果将任意部分声明为抽象的,则整个类型都被视为抽象的。
如果将任意部分声明为密封的,则整个类型都被视为密封的。
各个部分可以指定不同的基接口,最终类型将实现所有分部声明所列出的全部接口。
所有分部类型定义中合并内容还包括:注释、特性。
10.析构(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!
11.this
this
关键字指向当前实例。
原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/csharp/csharplang/7867.html