C# 接口

C#接口

在 C# 中,接口(Interface)是一种定义了一组相关方法、属性和事件的合同(contract),用于实现类来遵循。接口定义了类应该具有的成员,但不提供实现。类可以实现一个或多个接口,并提供相应的实现代码。

通过实现接口,类可以遵循接口定义的合同,并提供特定的行为。这使得类可以以一种统一的方式与其他类和组件进行交互,实现了接口的多态性(polymorphism)。

接口还可以用于实现接口间的继承关系。一个接口可以继承自另一个接口,这样实现该派生接口的类需要同时满足两个接口的要求。

接口在 C# 中常用于定义插件架构、实现依赖注入、编写可测试的代码等场景。它们提供了一种灵活而强大的方式来定义和组织代码,使得代码更加可扩展、可维护和可重用。

1、接口的定义

在 C# 中,可以使用 interface 关键字来定义接口。接口定义了一组方法、属性、事件或索引器的规范,而不提供它们的实际实现。以下是定义接口的语法:

public interface InterfaceName
{
    // 方法、属性、事件和索引器的声明
}

接口名称通常以大写字母 “I” 开头,表示接口(Interface)的含义,然后跟随具体的接口名称。接口定义应该放在命名空间内部或类内部,以根据使用情况进行适当的封装。

接口可以包含多个成员,包括方法、属性、事件和索引器。这些成员只有声明,没有实际的实现。例如,以下是一个包含方法和属性的接口示例:

public interface IExampleInterface
{
    void Method1();
    int Property1 { get; set; }
}

在上述示例中,IExampleInterface 接口定义了一个无返回值的方法 Method1 和一个读写属性 Property1

接口成员可以有各种访问修饰符(public、private、internal、protected),但接口自身的成员默认为公共访问修饰符(public)。接口成员不允许有访问修饰符 privateprotected,因为接口成员必须为实现接口的类可见。

接口还可以继承其他接口,通过使用冒号 (:) 来指定基接口。例如:

public interface IChildInterface : IParentInterface
{
    // 子接口成员声明
}

在上述示例中,IChildInterface 接口继承了 IParentInterface 接口。

类可以实现一个或多个接口,并通过提供相应的实现来满足接口的合同。类通过使用 class 关键字声明,并使用 : InterfaceName 来表示实现的接口。例如:

public class ExampleClass : IExampleInterface
{
    public void Method1()
    {
        // 方法实现
    }

    public int Property1 { get; set; }
}

在上述示例中,ExampleClass 类实现了 IExampleInterface 接口,并提供了 Method1 方法和 Property1 属性的具体实现。

通过接口,我们可以定义一组规范,以使类具备特定的行为,并实现接口的多态性。这样,我们可以使用接口引用来操作不同的类实例,以达到代码的灵活性和扩展性。

2、接口的实现

[类]在 C# 中,要实现接口,需要使用类或结构来提供接口定义的成员的具体实现。一个类可以实现一个或多个接口,并提供每个接口成员的具体实现。

以下是一个示例,展示了如何在类中实现接口:

// 定义一个接口
public interface IExampleInterface
{
    void Method1();
    int Property1 { get; set; }
}

// 实现接口的类
public class ExampleClass : IExampleInterface
{
    public void Method1()
    {
        Console.WriteLine("Method1 implementation");
    }

    public int Property1 { get; set; }
}

在上述示例中,ExampleClass 类实现了 IExampleInterface 接口。它提供了 Method1 方法和 Property1 属性的具体实现。

接口的方法实现由实现类根据自身的逻辑来编写。在 Method1 方法的实现中,我们打印了一条消息。属性的实现可以是简单的自动属性(auto-implemented property),如上述示例中的 Property1

接口的成员在实现类中应该使用相同的名称和签名。当一个类实现一个接口时,它必须提供接口中声明的所有成员的实现。

接口还可以继承其他接口,通过使用冒号 (:) 来指定基接口。例如:

public interface IChildInterface : IParentInterface
{
    // 子接口成员声明
}

public interface IParentInterface
{
    void ParentMethod();
}

public class ExampleClass : IChildInterface
{
    public void ParentMethod()
    {
        Console.WriteLine("ParentMethod implementation");
    }

    // IChildInterface 成员的实现
    // ...
}

在上述示例中,IChildInterface 接口继承了 IParentInterface 接口,并且 ExampleClass 类实现了 IChildInterface 接口。它提供了 ParentMethod 方法的具体实现,并可以根据需要提供 IChildInterface 的其他成员的实现。

[结构体]

public interface IExampleInterface
{
    void Method1();
    int Property1 { get; set; }
}

public struct ExampleStruct : IExampleInterface
{
    public void Method1()
    {
        Console.WriteLine("Method1 implementation");
    }

    public int Property1 { get; set; }
}

在上述示例中,我们定义了一个接口 IExampleInterface,其中包含一个方法 Method1 和一个属性 Property1。然后,我们创建了一个结构体 ExampleStruct,并通过 : IExampleInterface 指定了它实现了 IExampleInterface 接口。

结构体中的接口实现与类中的接口实现类似。我们提供了 Method1 方法的具体实现,并定义了一个自动属性 Property1

需要注意的是,在结构体中实现接口时,结构体是值类型,而接口是引用类型。因此,在结构体中实现接口时,实现的接口成员是在结构体的副本上调用的,而不是对原始结构体的引用。

使用结构体实现接口时,可以像操作类实例一样使用结构体实例,并通过接口类型的引用来调用接口的成员。例如:

ExampleStruct example = new ExampleStruct();
example.Method1();
example.Property1 = 10;

在上述示例中,我们创建了一个 ExampleStruct 结构体的实例,并使用它调用了接口的方法和访问了接口的属性。

结构体实现接口可以用于一些特定的场景,如需要值类型语义、节省内存或需要在栈上分配的情况。但需要注意的是,结构体在复杂逻辑和大量数据存储方面可能不如类灵活和高效。因此,在选择结构体还是类来实现接口时,应根据具体情况和需求做出选择。

*{当我们声明对象是结构体类型时,对象是值类型,对象在栈中创建*
*当我们声明对象是接口类型时,对象是引用类型,对象在堆中创建}*(调用时)

通过实现接口,类可以遵循接口定义的合同,并提供特定的行为。这使得类可以以一种统一的方式与其他类和组件进行交互,实现了接口的多态性。

3、接口的调用

在 C# 中,可以通过接口类型的引用来调用接口的成员接口类型的引用可以引用实现了该接口的类的实例。这样做可以实现对不同类的实例进行统一的操作。

以下是一个示例,展示了如何使用接口类型的引用来调用接口的成员:

public interface IExampleInterface
{
    void Method1();
    int Property1 { get; set; }
}

public class ExampleClass : IExampleInterface
{
    public void Method1()
    {
        Console.WriteLine("Method1 implementation");
    }

    public int Property1 { get; set; }
}

public class Program
{
    public static void Main()
    {
        IExampleInterface example = new ExampleClass(); // 实例化 ExampleClass,并将其赋值给接口类型的引用
        example.Method1(); // 调用接口的方法
        example.Property1 = 10; // 访问接口的属性
    }
}

在上述示例中,我们定义了 IExampleInterface 接口和 ExampleClass 类,ExampleClass 类实现了 IExampleInterface 接口。然后,在 Program 类的 Main 方法中,我们实例化 ExampleClass,并将其赋值给接口类型的引用 example。通过这样做,我们可以使用 example 引用来调用接口的方法和访问接口的属性。

注意,通过接口类型的引用调用接口的成员时,实际执行的是实现类中的具体实现。这样可以实现对实现了同一接口的不同类的实例进行统一的操作,提高代码的灵活性和可扩展性。

在实际开发中,接口的调用经常用于实现依赖注入、面向接口编程等场景。通过定义和使用接口,我们可以实现松耦合的设计,提高代码的可测试性和可维护性。

总结

  • 接口的定义:指定一组函数成员而不实现成员的引用类型,其它类型和接口可以继承接口。
  • 接口是“是什么”的规范,继承类或结构体是“怎么做”的具体实现。
  • 接口和抽象类的区别

接口和抽象类的具体区别

  1. 定义:接口是一种完全抽象的类型,它只定义了成员的签名,没有提供任何实现细节。抽象类是一个可以包含抽象成员和具体实现的类。抽象类可以具有字段、属性、构造函数等成员,并且可以包含具体的方法实现。
  2. 多继承:类可以实现多个接口,但只能继承一个抽象类。C# 不支持多重继承,而接口的多实现使得类能够从多个接口中继承行为。
  3. 构造函数:抽象类可以有构造函数,而接口不能有构造函数。类在实例化时会调用其基类的构造函数,但接口没有实例化的概念,因此不需要构造函数。
  4. 访问修饰符:接口中的成员默认为公共(public),而抽象类中的成员可以有不同的访问修饰符,如公共(public)、受保护(protected)或内部(internal)。
  5. 默认实现:抽象类可以提供具体的方法实现,子类可以选择性地覆盖这些方法。接口只能定义成员的签名,没有默认实现,实现接口的类必须提供自己的实现逻辑。
  6. 设计目的:接口用于定义合同,表示一种能力或行为,强调类之间的契约关系。抽象类用于表示一种通用的、抽象的概念,并提供一些基本的实现,强调类之间的层次关系。

在选择接口或抽象类时,应根据具体的需求和设计目标来确定。如果需要定义一组方法签名,以实现多态性和契约编程,或者需要支持多重继承,那么接口是一个好的选择。如果需要定义一个通用的抽象概念,并提供一些默认的实现,或者需要在继承层次结构中共享代码和状态,那么抽象类是一个更合适的选择。

需要注意的是,C# 中的类可以同时实现接口和继承抽象类,以充分利用它们的特性。这种组合使用可以提供更灵活和可扩展的设计。

一、接口注意的几点:

1、接口方法不能用public abstract等修饰。接口内不能有字段变量,构造函数。
2、接口内可以定义属性(有get和set的方法)。如string color { get ; set ; }这种。
3、实现接口时,必须和接口的格式一致。
4、必须实现接口的所有方法。
二、接口的定义是指定一组函数成员而不实现成员的引用类型,其它类型和接口可以继承接口。接口主要有以下特点:

1、通过接口可以实现多重继承,C# 接口的成员不能有 public、protected、internal、private 等修饰符。原因很简单,接口里面的方法都需要由外面接口实现去实现方法体,那么其修饰符必然是 public。C# 接口中的成员默认是 public 的。
2、接口成员不能有 new、static、abstract、override、virtual 修饰符。有一点要注意,当一个接口实现一个接口,这2个接口中有相同的方法时,可用 new 关键字隐藏父接口中的方法。
3、接口中只包含成员的签名,接口没有构造函数,所以不能直接使用 new 对接口进行实例化。接口中只能包含方法、属性、事件和索引的组合。接口一旦被实现,实现类必须实现接口中的所有成员,除非实现类本身是抽象类。
4、C# 的类是单继承,接口是解决 C# 里面类可以同时继承多个基类的问题。

你可能感兴趣的:(c#,c#)