在本文中,我们展示了如何在C#中定义类。
class
关键字用于定义类,类是创建对象的模板。这些对象称为类的实例。使用new
关键字创建一个新类。
在类内部,我们定义成员字段和成员函数。在类内部定义的函数称为方法。成员字段和函数通过点运算符访问。
C#简单类示例
下面的例子创建了一个简单的类。
var u = new User("John Doe", "gardener"); Console.WriteLine($"{u.Name} is a {u.Occupation}"); u.Occupation = "driver"; Console.WriteLine($"{u.Name} is a {u.Occupation}"); class User { public User(string name, string occupation) { this.Name = name; this.Occupation = occupation; } public string Name { get; set; } public string Occupation { get; set; } }
在程序中,我们定义了User
类。该类有两个属性:姓名
和职业
。属性使用访问器,通过访问器可以读取、写入或操作成员字段的值。
var u = new User("John Doe", "gardener");
我们创建了一个User
类的新实例。我们将两个参数传递给构造函数。构造函数是在创建对象时调用的方法。
Console.WriteLine($"{u.Name} is a {u.Occupation}");
我们访问User
类的两个属性。
class User { ... }
class
关键字定义了一个类。类的主体写在{}
括号内。
public User(string name, string occupation) { this.Name = name; this.Occupation = occupation; }
这是类的构造函数。构造函数与类同名。它在对象的构造中被调用。在构造函数中,我们设置了两个属性。
public string Name { get; set; } public string Occupation { get; set; }
我们定义了两个属性。自动实现的属性为定义类提供了简洁的语法。
$ dotnet run John Doe is a gardener John Doe is a driver
C#标准类
.NET有一个庞大的类库,可供程序员使用。
using System.Text; var path = "words.txt"; string content = File.ReadAllText(path, Encoding.UTF8); Console.WriteLine(content);
例如,在这个小程序中,我们使用File
类读取文件的内容,并使用Console
类将内容写入终端。
人类可读的类表示
为了提供类的人类可读表示,我们覆盖了ToString
方法。
var u = new User("John Doe", "gardener"); Console.WriteLine(u); class User { public User(string name, string occupation) { this.Name = name; this.Occupation = occupation; } public string Name { get; set; } public string Occupation { get; set; } public override string ToString() { return $"{this.Name} is a {this.Occupation}"; } }
在程序中,我们创建了自己的ToString
方法实现。
var u = new User("John Doe", "gardener"); Console.WriteLine(u);
当我们将用户实例传递给Console.WriteLine
方法时,将调用ToString
方法。
C#抽象类
未完成类中的抽象类,其目的是为其子类定义一些通用定义。它必须在其子类中实现。抽象类是用抽象关键字创建的。我们可以创建抽象方法和成员字段。
抽象类不能被实例化,抽象方法也不能被实现。
var c = new Circle(12, 45, 22); Console.WriteLine(c); Console.WriteLine($"Area of circle: {c.Area()}"); Console.WriteLine(c.GetCoordinates()); Console.WriteLine("---------------------"); var s = new Square(10, 20, 50); Console.WriteLine(s); Console.WriteLine($"Area of square: {s.Area()}"); Console.WriteLine(s.GetCoordinates()); abstract class Drawing { protected int x = 0; protected int y = 0; public abstract double Area(); public string GetCoordinates() { return $"x: {x}, y: {y}"; } } class Circle : Drawing { private int r; public Circle(int x, int y, int r) { this.x = x; this.y = y; this.r = r; } public override double Area() { return this.r * this.r * Math.PI; } public override string ToString() { return $"Circle at x: {x}, y: {x}, radius: {r}"; } } class Square : Drawing { private int width; public Square(int x, int y, int width) { this.x = x; this.y = y; this.width = width; } public override double Area() { return this.width * this.width; } public override string ToString() { return $"Square at x: {x}, y: {y}, w: {width}"; } }
我们有一个抽象基类Drawing。该类定义了两个成员字段,定义了一个方法并声明了一个方法。其中一种方法是抽象的,另一种是完全实现的。Drawing类是抽象的,因为我们无法绘制它。我们可以画一个圆、一个点或一个正方形。Drawing类对我们可以绘制的对象具有一些通用功能。
abstract class Drawing
我们使用abstract
关键字来定义一个抽象类。
public abstract double Area();
抽象方法也以abstract
关键字开头。
class Circle : Drawing
Circle是一个具体的类,它可以画在surface上。我们将其定义为Drawing
类的子类;因此,它必须实现抽象的Area
方法。
public override double Area() { return this.r * this.r * Math.PI; }
当我们实现Area
方法时,我们必须使用override
关键字。通过这种方式,我们通知编译器我们重写了一个现有的(继承的)方法。
$ dotnet run Circle at x: 12, y: 12, radius: 22 Area of circle: 1520.53084433746 x: 12, y: 45 --------------------- Square at x: 10, y: 20, w: 50 Area of square: 2500 x: 10, y: 20
C#嵌套类
嵌套类是在另一个类的主体中定义的内部类。当嵌套类与外部类密切相关时,定义嵌套类是有意义的。
var fjet = new FighterJet(); fjet.TakeOff(); fjet.DropBomb(); fjet.DropBomb(); fjet.DropBomb(); fjet.Land(); class FighterJet { public void TakeOff() { Console.WriteLine("FighterJet takes off"); } public void Land() { Console.WriteLine("FighterJet lands"); } public void DropBomb() { var bomb = new Bomb(); bomb.Drop(); } class Bomb { public Bomb() { Console.WriteLine("Bomb prepared"); } public void Drop() { Console.WriteLine("Bomb launched"); } } }
我们有一个可以投掷炸弹的FighterJet
类。炸弹对象可以定义为嵌套类,因为它可以被视为外部类的组成部分。
$ dotnet run FighterJet takes off Bomb prepared Bomb launched Bomb prepared Bomb launched Bomb prepared Bomb launched FighterJet lands
C#部分类
使用partial
关键字,可以将一个类的定义拆分成同一个命名空间内的几个部分。该类也可以定义在多个文件中。
部分类在处理非常大的代码库时使用,它可以被拆分成更小的单元。部分类也与自动代码生成器一起使用。
namespace PartialClass; partial class Worker { public string DoWork() { return "Doing work"; } } partial class Worker { public string DoPause() { return "Pausing"; } } class Program { static void Main(string[] args) { var worker = new Worker(); Console.WriteLine(worker.DoWork()); Console.WriteLine(worker.DoWork()); Console.WriteLine(worker.DoPause()); } }
在示例中,我们将Worker
类定义为两部分。编译器将这些部分连接在一起形成最终类。
$ dotnet run Doing work Doing work Pausing
C#密封类
sealed
关键字用于防止从类中意外派生。密封类不能是抽象类。
namespace DerivedMath; sealed class Math { public static double GetPI() { return 3.141592; } } class Derived : Math { public void Say() { Console.WriteLine("Derived class"); } } class Program { static void Main(string[] args) { var dm = new Derived(); dm.Say(); } }
在上面的程序中,我们有一个基Math
类。此类的唯一目的是为程序员提供一些有用的方法和常量。(在我们的例子中,出于简单的原因,我们只有一种方法。)它不是为继承而创建的。
为了防止不知情的其他程序员从该类派生,创建者将该类密封
。如果您尝试编译此程序,则会收到以下错误:“派生”无法从密封类型“数学”派生。
在本文中,我们展示了如何定义类并描述了各种类型的类。
列出所有C#教程。