接口,多态性,密封类
C# 接口
遥控器是观众和电视之间的接口。 它是此电子设备的接口。 外交礼仪指导外交领域的所有活动。 道路规则是驾车者,骑自行车者和行人必须遵守的规则。 编程中的接口类似于前面的示例。
接口是:
- APIs
- Contracts
对象通过其公开的方法与外界交互。 实际的实现对程序员而言并不重要,或者也可能是秘密的。 公司可能会出售图书馆,但它不想透露实际的实施情况。 程序员可能会在 GUI 工具箱的窗口上调用Maximize()
方法,但对如何实现此方法一无所知。 从这个角度来看,接口是对象与外界交互的方式,而又不会过多地暴露其内部功能。
从第二个角度来看,接口就是契约。 如果达成协议,则必须遵循。 它们用于设计应用的体系结构。 他们帮助组织代码。
接口是完全抽象的类型。 它们使用interface
关键字声明。 接口只能具有方法,属性,事件或索引器的签名。 所有接口成员都隐式具有公共访问权限。 接口成员不能指定访问修饰符。 接口不能具有完全实现的方法,也不能具有成员字段。 C# 类可以实现任何数量的接口。 一个接口还可以扩展任何数量的接口。 实现接口的类必须实现接口的所有方法签名。
接口用于模拟多重继承。 C# 类只能从一个类继承,但可以实现多个接口。 使用接口的多重继承与继承方法和变量无关。 它是关于继承想法或合同的,这些想法或合同由接口描述。
接口和抽象类之间有一个重要的区别。 抽象类为继承层次结构中相关的类提供部分实现。 另一方面,可以通过彼此不相关的类来实现接口。 例如,我们有两个按钮。 经典按钮和圆形按钮。 两者都继承自抽象按钮类,该类为所有按钮提供了一些通用功能。 实现类是相关的,因为它们都是按钮。 另一个示例可能具有类Database
和SignIn
。 它们彼此无关。 我们可以应用ILoggable
接口,该接口将迫使他们创建执行日志记录的方法。
C# 简单接口
以下程序使用一个简单的接口。
Program.
using System;
namespace SimpleInterface
{
interface IInfo
{
void DoInform();
}
class Some : IInfo
{
public void DoInform()
{
Console.WriteLine("This is Some Class");
}
}
class Program
{
static void Main(string[] args)
{
var some = new Some();
some.DoInform();
}
}
}
这是一个演示接口的简单 C# 程序。
interface IInfo
{
void DoInform();
}
这是接口IInfo
。 它具有DoInform()
方法签名。
class Some : IInfo
我们实现了IInfo
接口。 为了实现特定的接口,我们使用冒号(:)运算符。
public void DoInform()
{
Console.WriteLine("This is Some Class");
}
该类提供了DoInform()
方法的实现。
C# 多个接口
下一个示例显示了一个类如何实现多个接口。
Program.
using System;
namespace MultipleInterfaces
{
interface Device
{
void SwitchOn();
void SwitchOff();
}
interface Volume
{
void VolumeUp();
void VolumeDown();
}
interface Pluggable
{
void PlugIn();
void PlugOff();
}
class CellPhone : Device, Volume, Pluggable
{
public void SwitchOn()
{
Console.WriteLine("Switching on");
}
public void SwitchOff()
{
Console.WriteLine("Switching on");
}
public void VolumeUp()
{
Console.WriteLine("Volume up");
}
public void VolumeDown()
{
Console.WriteLine("Volume down");
}
public void PlugIn()
{
Console.WriteLine("Plugging In");
}
public void PlugOff()
{
Console.WriteLine("Plugging Off");
}
}
class Program
{
static void Main(string[] args)
{
var cellPhone = new CellPhone();
cellPhone.SwitchOn();
cellPhone.VolumeUp();
cellPhone.PlugIn();
}
}
}
我们有一个CellPhone
类,它从三个接口继承。
class CellPhone : Device, Volume, Pluggable
该类实现所有三个接口,并用逗号分隔。 CellPhone
类必须实现来自所有三个接口的所有方法签名。
$ dotnet run
Switching on
Volume up
Plugging In
运行程序,我们得到此输出。
C# 多接口继承
下一个示例显示接口如何从多个其他接口继承。
Program.
using System;
namespace InterfaceInheritance
{
interface IInfo
{
void DoInform();
}
interface IVersion
{
void GetVersion();
}
interface ILog : IInfo, IVersion
{
void DoLog();
}
class DBConnect : ILog
{
public void DoInform()
{
Console.WriteLine("This is DBConnect class");
}
public void GetVersion()
{
Console.WriteLine("Version 1.02");
}
public void DoLog()
{
Console.WriteLine("Logging");
}
public void Connect()
{
Console.WriteLine("Connecting to the database");
}
}
class Program
{
static void Main(string[] args)
{
var db = new DBConnect();
db.DoInform();
db.GetVersion();
db.DoLog();
db.Connect();
}
}
}
我们定义了三个接口。 我们可以按层次结构组织接口。
interface ILog : IInfo, IVersion
ILog
接口继承自其他两个接口。
public void DoInform()
{
Console.WriteLine("This is DBConnect class");
}
DBConnect
类实现DoInform()
方法。 该方法由该类实现的ILog
接口继承。
$ dotnet run
This is DBConnect class
Version 1.02
Logging
Connecting to the database
这是输出。
C# 多态性
多态是以不同方式将运算符或函数用于不同数据输入的过程。 实际上,多态性意味着如果类 B 从类 A 继承,那么它不必继承关于类 A 的所有内容。 它可以完成 A 类所做的某些事情。
通常,多态性是以不同形式出现的能力。 从技术上讲,它是重新定义派生类的方法的能力。 多态性与将特定实现应用于接口或更通用的基类有关。
多态性是重新定义派生类的方法的能力。
Program.
using System;
namespace Polymorphism
{
abstract class Shape
{
protected int x;
protected int y;
public abstract int Area();
}
class Rectangle : Shape
{
public Rectangle(int x, int y)
{
this.x = x;
this.y = y;
}
public override int Area()
{
return this.x * this.y;
}
}
class Square : Shape
{
public Square(int x)
{
this.x = x;
}
public override int Area()
{
return this.x * this.x;
}
}
class Program
{
static void Main(string[] args)
{
Shape[] shapes = { new Square(5), new Rectangle(9, 4), new Square(12) };
foreach (Shape shape in shapes)
{
Console.WriteLine(shape.Area());
}
}
}
}
在上面的程序中,我们有一个抽象的Shape
类。 此类演变为两个后代类别:Rectangle
和Square
。 两者都提供了自己的Area()
方法实现。 多态为 OOP 系统带来了灵活性和可伸缩性。
public override int Area()
{
return this.x * this.y;
}
...
public override int Area()
{
return this.x * this.x;
}
Rectangle
和Square
类具有Area()
方法的自己的实现。
Shape[] shapes = { new Square(5), new Rectangle(9, 4), new Square(12) };
我们创建三个形状的数组。
foreach (Shape shape in shapes)
{
Console.WriteLine(shape.Area());
}
我们遍历每个形状,并在其上调用Area()
方法。 编译器为每种形状调用正确的方法。 这就是多态性的本质。
C# 密封类
sealed
关键字用于防止意外地从类派生。 密封类不能是抽象类。
Program.
using System;
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
基类。 该类的唯一目的是为程序员提供一些有用的方法和常量。 (出于简单起见,在我们的案例中,我们只有一种方法。)它不是从继承而创建的。 为了防止不知情的其他程序员从此类中派生,创建者创建了sealed
类。 如果尝试编译该程序,则会出现以下错误:’Derived’不能从密封类’Math’派生。