接口定义了所有类继承接口时应遵循的语法合同。接口定义了语法合同 "是什么" 部分,派生类定义了语法合同 "怎么做" 部分。
接口定义了属性、方法和事件,这些都是接口的成员。接口只包含了成员的声明。成员的定义是派生类的责任。接口提供了派生类应遵循的标准结构。
抽象类在某种程度上与接口类似,但是,它们大多只是用在当只有少数方法由基类声明由派生类实现时。
接口的优点
-
实现多态性:接口允许一个类实现多个接口,从而实现多重继承。这使得类可以具有多个不同类型的行为,提供了更大的灵活性。
-
促进代码复用:通过实现接口,可以将常用的功能和行为封装成一个接口,然后多个类可以共享该接口的实现。这样可以减少代码的重复性,提高开发效率。
-
支持接口的集合和泛型:接口可以用于定义集合类型,从而可以通过接口对集合进行统一的操作和访问。此外,接口也可以与泛型结合使用,以进一步提高代码的灵活性和可重用性。
-
隔离和解耦:接口的使用可以将程序的各个组件解耦,并提供了一种隔离实现细节的方式。通过面向接口的编程,可以使得组件之间的耦合度更低,以便更容易进行单元测试和维护。
接口的缺点与局限性
-
不支持字段:接口不能包含字段,只能包含方法、属性和事件的声明。这意味着接口无法定义实例字段,而只能通过实现接口的类来定义字段。
-
需要手动实现:类实现接口时,必须手动实现接口中声明的所有成员,包括方法、属性和事件。这需要一定的工作量,特别是在实现多个接口时。
-
限制了成员的可访问性:接口中的成员默认为公共的,无法指定其他的访问修饰符(如private、protected等),这可能会影响到一些需要限制访问的情况。
-
可能导致多个类实现类似的代码:当多个类实现相同的接口时,它们可能会具有类似的代码实现。这可能会导致一些冗余的代码。
综上所述,接口在C#中是一种强大且常用的工具,它提供了多态性、代码共享和解耦等优点。然而,接口也有一些限制和缺点需要考虑。在使用接口时,需要权衡其优缺点,并根据具体的情况进行选择。
声明接口
接口使用 interface 关键字声明,它与类的声明类似。接口声明默认是 public 的。下面是一个接口声明的实例:
interface ITransactions{
// 接口成员
void showTransaction();
double getAmount();
}
实例
下面的实例演示了上面接口的实现:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System;
namespace InterfaceApplication{
interface ITransactions{
// 接口成员
void showTransaction();
double getAmount();
}
public class Transaction : ITransactions{
private string tCode;
private string date;
private double amount;
public Transaction(){
tCode = " ";
date = " ";
amount = 0.0;
}
public Transaction(string c, string d, double a){
tCode = c;
date = d;
amount = a;
}
public double getAmount(){
return amount;
}
public void showTransaction(){
Console.WriteLine("Transaction: {0}", tCode);
Console.WriteLine("Date: {0}", date);
Console.WriteLine("Amount: {0}", getAmount());
}
}
class Tester{
static void Main(string[] args){
Transaction t1 = new Transaction("001", "8/10/2012", 78900.00);
Transaction t2 = new Transaction("002", "9/10/2012", 451900.00);
t1.showTransaction();
t2.showTransaction();
Console.ReadKey();
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
Transaction: 001
Date: 8/10/2012
Amount: 78900
Transaction: 002
Date: 9/10/2012
Amount: 451900
实例2
public interface IShape
{
// 方法
double CalculateArea();
// 属性
double Perimeter { get; }
// 事件
event EventHandler ShapeChanged;
}
public class Circle : IShape
{
private double radius;
// 实现接口中的方法
public double CalculateArea()
{
return Math.PI * radius * radius;
}
// 实现接口中的属性
public double Perimeter
{
get { return 2 * Math.PI * radius; }
}
// 实现接口中的事件
public event EventHandler ShapeChanged;
public double Radius
{
get { return radius; }
set
{
radius = value;
OnShapeChanged();
}
}
protected virtual void OnShapeChanged()
{
ShapeChanged?.Invoke(this, EventArgs.Empty);
}
}
public class Program
{
static void Main(string[] args)
{
Circle circle = new Circle();
circle.Radius = 5;
Console.WriteLine("Area: " + circle.CalculateArea());
Console.WriteLine("Perimeter: " + circle.Perimeter);
}
}
接口使用的注意事项:
- 接口方法不能用public abstract等修饰。接口内不能有字段变量,构造函数。
- 接口内可以定义属性(有get和set的方法)。如string color { get ; set ; }这种。
- 实现接口时,必须和接口的格式一致。
- 必须实现接口的所有方法。