一、关键知识点
1、类
在C#中,类(Class)是一种用户定义的数据类型,它包含字段(数据成员)、属性(用于访问字段的可读写的成员)、方法(成员函数)和事件等。
-
基本类的定义和使用
以下是一个例子:
using System;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public void SayHello()
{
Console.WriteLine($"Hello, my name is {Name} and I'm {Age} years old.");
}
}
class Program
{
static void Main(string[] args)
{
// 创建Person类的实例
Person person = new Person();
// 设置属性
person.Name = "xiaoming";
person.Age = 18;
// 调用方法
person.SayHello();
}
}
运行结果如下图:
以下是对代码的详细解释:
该例子它展示了如何定义一个类(Person
),创建该类的一个实例(person
),设置该实例的属(Name
和 Age
),以及调用该实例的一个方法(SayHello
)。
person类定义了两个属性(Name
和 Age
)和一个方法(SayHello
)。
Name
是一个字符串类型的属性,用于存储人的名字。Age
是一个整数类型的属性,用于存储人的年龄。SayHello
是一个方法,它使用字符串插值来输出一个包含名字和年龄的打招呼信息。
program类包含程序的入口点,即 Main
方法。
- 在
Main
方法中,首先创建了一个Person
类的实例person
。 - 然后,通过
person
实例的Name
和Age
属性,设置了人的名字和年龄。 - 最后,通过调用
person
实例的SayHello
方法,输出了打招呼的信息。
2、接口
在C#中,接口(Interface)是一种引用类型,它定义了一组方法、属性、事件或索引器的签名,但不包含实现。接口允许你定义可以由类或其他接口实现的成员。实现接口的类必须提供接口中定义的所有成员的具体实现。
以下代码是一个C#示例,展示了接口(IAnimal
)和类(Cat
)之间的关系,以及如何通过接口来引用一个类实例并调用其方法。
-
接口定义
- 接口使用
interface
关键字定义,它包含方法的签名(返回类型和名称),但不包含方法的实现(即方法体)。
public interface IAnimal
{
void MakeSound();
}
这里定义了一个名为 IAnimal
的接口。接口是一个合约,它定义了一组方法、属性、事件或索引器的签名,但不提供它们的实现。任何实现这个接口的类都必须提供这些成员的具体实现。在这个例子中,IAnimal
接口有一个方法 MakeSound
,它没有具体的实现。
-
接口实现
- 类使用
:
符号后跟接口名称来实现接口。实现接口的类必须提供接口中所有方法的实现。
public class Cat : IAnimal
{
public void MakeSound()
{
Console.WriteLine("The cat meows.");
}
}
Cat
类实现了 IAnimal
接口。这意味着 Cat
类必须提供 MakeSound
方法的具体实现。在 Cat
类中,MakeSound
方法被实现为在控制台上输出 "The cat meows."。
-
主程序:Program
class Program
{
static void Main(string[] args)
{
IAnimal animal = new Cat();
// 调用接口中定义的方法
animal.MakeSound();
}
}
运行结果如下图:
以下是对代码的详细解释:
在 Main
方法中:
-
创建了一个
Cat
类的实例,并将其赋值给一个IAnimal
类型的变量animal
。这是多态性的一个示例:你可以通过基类型(或接口)的引用来引用派生类(或实现类)的实例。 -
通过
animal
变量调用了MakeSound
方法。由于animal
是IAnimal
类型的引用,它调用的是接口中定义的方法。然而,由于实际上animal
引用的是一个Cat
对象,所以最终调用的是Cat
类中实现的MakeSound
方法。
3、委托
C# 中的委托(Delegate)是一种类型,它安全地封装了方法的签名和定义,可以作为参数传递或赋值给变量。委托特别用于实现回调方法、事件处理和异步编程。
委托的基本知识点
-
定义委托
- 使用
delegate
关键字来定义委托。委托的声明指定了它可以引用的方法的签名。
public delegate void MyDelegate(string message);
-
创建委托实例
- 委托实例可以引用与委托签名匹配的方法。
public class MyClass
{
public void MyMethod(string message)
{
Console.WriteLine(message);
}
}
// ...
//创建委托实例
MyClass myClass = new MyClass();
// 创建MyDelegate委托实例,将myClass.MyMethod作为目标方法
MyDelegate myDelegate = new MyDelegate(myClass.MyMethod);
-
调用委托
- 通过委托实例可以直接调用它所引用的方法。
myDelegate("Hello, World!"); // 输出 "Hello, World!"
以下是一个完整的实例程序:
using System;
namespace try01
{
// 定义一个名为 MyDelegate 的委托,它接受一个 string 参数并返回 void
public delegate void MyDelegate(string message);
// 定义一个名为 MyClass 的类,包含一个方法 MyMethod
public class MyClass
{
// MyClass 类的一个方法,与 MyDelegate 委托签名匹配
public void MyMethod(string message)
{
// 输出传入的 message 参数
Console.WriteLine(message);
}
}
// Program 类,包含程序的入口点 Main 方法
class Program
{
// 程序的入口点
static void Main(string[] args)
{
// 创建 MyClass 类的一个实例 myClass
MyClass myClass = new MyClass();
// 创建一个 MyDelegate 类型的委托实例 myDelegate,将 myClass 的 MyMethod 方法作为目标方法
MyDelegate myDelegate = new MyDelegate(myClass.MyMethod);
// 调用 myDelegate 委托,这将会调用 myClass 的 MyMethod 方法,并传入字符串 "Hello, World!"
myDelegate("Hello, World!"); // 输出 "Hello, World!"
}
}
}
运行结果如下图:
二、实现对周黑鸭工厂的产品生产统一管理,主要产品包括鸭脖和鸭翅。
武汉工厂能生生产鸭脖和鸭翅,南京工厂只能生产鸭翅,长沙工厂只能生产鸭脖。
具体要求如下:
- 定义接口 IProductionFactory,包含生产鸭脖和鸭翅的方法。
- 定义类 WuhanFactory、NanjingFactory、ChangshaFactory 分别实现接口 IProductionFactory,用于具体的生产工厂。
- 使用委托 ProductionDelegate 定义生产委托。
- 在 Main 函数中,创建不同工厂的实例,并通过生产委托进行生产。
示例:
首先,定义接口 IProductionFactory
:
public interface IProductionFactory
{
void ProduceDuckNeck();
void ProduceDuckWing();
}
接着,定义委托 ProductionDelegate
:
public delegate void ProductionDelegate();
然后,定义实现 IProductionFactory
接口的具体工厂类:
public class WuhanFactory : IProductionFactory
{
public void ProduceDuckNeck()
{
Console.WriteLine("武汉工厂生产鸭脖");
}
public void ProduceDuckWing()
{
Console.WriteLine("武汉工厂生产鸭翅");
}
}
public class NanjingFactory : IProductionFactory
{
public void ProduceDuckNeck()
{
throw new NotImplementedException("南京工厂不能生产鸭脖");
}
public void ProduceDuckWing()
{
Console.WriteLine("南京工厂生产鸭翅");
}
}
public class ChangshaFactory : IProductionFactory
{
public void ProduceDuckNeck()
{
Console.WriteLine("长沙工厂生产鸭脖");
}
public void ProduceDuckWing()
{
throw new NotImplementedException("长沙工厂不能生产鸭翅");
}
}
最后,在 Main
函数中,创建不同工厂的实例,并通过生产委托进行生产:
class Program
{
static void Main(string[] args)
{
// 创建工厂实例
IProductionFactory wuhanFactory = new WuhanFactory();
IProductionFactory nanjingFactory = new NanjingFactory();
IProductionFactory changshaFactory = new ChangshaFactory();
// 定义生产委托并赋值
ProductionDelegate produceDuckNeck = wuhanFactory.ProduceDuckNeck;
ProductionDelegate produceDuckWing = (wuhanFactory as IProductionFactory).ProduceDuckWing;
// 通过委托进行生产
produceDuckNeck();
produceDuckWing();
// 南京工厂只能生产鸭翅
produceDuckWing = nanjingFactory.ProduceDuckWing;
produceDuckWing();
// 长沙工厂只能生产鸭脖
produceDuckNeck = changshaFactory.ProduceDuckNeck;
produceDuckNeck();
// 等待用户输入,防止控制台窗口立即关闭
Console.ReadLine();
}
}
以下是一个完整的代码:
using System;
namespace homework1
{
public interface IProductionFactory//定义接口 IProductionFactory
{
void ProduceDuckNeck();
void ProduceDuckWing();
}
public delegate void ProductionDelegate(); //定义委托 ProductionDelegate
public class WuhanFactory : IProductionFactory
{
public void ProduceDuckNeck()
{
Console.WriteLine("武汉工厂生产鸭脖");
}
public void ProduceDuckWing()
{
Console.WriteLine("武汉工厂生产鸭翅");
}
}
public class NanjingFactory : IProductionFactory
{
public void ProduceDuckNeck()
{
throw new NotImplementedException("南京工厂不能生产鸭脖");
}
public void ProduceDuckWing()
{
Console.WriteLine("南京工厂生产鸭翅");
}
}
public class ChangshaFactory : IProductionFactory
{
public void ProduceDuckNeck()
{
Console.WriteLine("长沙工厂生产鸭脖");
}
public void ProduceDuckWing()
{
throw new NotImplementedException("长沙工厂不能生产鸭翅");
}
}
class Program
{
static void Main(string[] args)
{
// 创建工厂实例
IProductionFactory wuhanFactory = new WuhanFactory();
IProductionFactory nanjingFactory = new NanjingFactory();
IProductionFactory changshaFactory = new ChangshaFactory();
// 定义生产委托并赋值
ProductionDelegate produceDuckNeck = wuhanFactory.ProduceDuckNeck;
ProductionDelegate produceDuckWing = (wuhanFactory as IProductionFactory).ProduceDuckWing;
// 通过委托进行生产
produceDuckNeck();//调用委托,输出“武汉工厂生产鸭脖”
produceDuckWing();//调用委托,输出“武汉工厂生产鸭翅”
// 南京工厂只能生产鸭翅
produceDuckWing = nanjingFactory.ProduceDuckWing;
produceDuckWing();
// 长沙工厂只能生产鸭脖
produceDuckNeck = changshaFactory.ProduceDuckNeck;
produceDuckNeck();
// 等待用户输入,防止控制台窗口立即关闭
Console.ReadLine();
}
}
}
运行结果如下图:
以下是对代码的详细解释:
- 我们创建了三个工厂类,分别对应武汉、南京和长沙工厂。武汉工厂能生产鸭脖和鸭翅,南京工厂只能生产鸭翅,长沙工厂只能生产鸭脖。
- 在
Main
函数中,我们创建了这些工厂的实例,并通过生产委托ProductionDelegate
来调用它们的生产方法。 - 当南京工厂或长沙工厂调用它们不能生产的产品时(例如,南京工厂用
ProduceDuckNeck
方法),会抛出NotImplementedException
异常。 - 此外,这里使用
(wuhanFactory as IProductionFactory).ProduceDuckWing
是为了确保委托produceDuckWing
的类型是正确的,因为委托的声明类型没有参数信息,所以在赋值时需要确保赋值的方法签名与委托的签名相匹配。在实际应用中,更好的做法是使用泛型委托或 Lambda 表达式来避免这种类型转换。