C#系列之接口介绍

一、接口定义简介

       接口可以简单理解为一种约定,使得实现接口的类或结构在形式上保持一致,使用接口可以使程序更加清晰和条理化。接口是指定一组函数成员而不实现他们的引用类型,所以只能类和结构来实现接口,在继承该接口的类里面要实现接口的所有方法。

      在C#语言中,类之间的继承关系仅支持单重继承,而接口是为了实现多重继承关系设计的。(可以理解为接口是C#的灵魂所在),一个类能同时实现多个接口,还能在实现接口的同时再继承其他类,并且接口之间也可以继承。接口定义了所有类继承接口时应遵循的语法合同。接口定义了语法合同“是什么”部分,派生类定义了语法合同“怎么做”部分。接口定义了属性、方法和事件,这些都是接口的成员。接口只包含了成员的声明。成员的定义是派生类的责任。接口提供了派生类应遵循的标准结构。

举个例子:接口可以简单理解为具备某种功能的标准化模块,当某个产品需要有一个自动输出尺寸的功能,我们将输出尺寸定义为接口后,该产品只需要按照接口要求自动调用即可,当我们换了一个新产品,仍然需要输出尺寸的功能,这时候我们只需要再调用对应接口就可以。接口定义了语法合同 “是什么” 部分,派生类定义了语法合同 "怎么做"部分。通俗来讲就是接口定义了一些行为,继承接口的类应该必须拥有这些行为,按照这些行为去做…

1.接口的成员

接口定义了属性、方法和事件,这些都是接口的成员。

interface 接口名称
{
    接口成员;//接口成员可以是属性、方法、事件;
}
public delegate void TestDelegate();  //定义一个事件

 public interface ITestInterface(接口的名字命名一般是大写I开头)
 {
    
     //接口成员

     event TestDelegate TestEvent;  //事件成员

     void FireAway();//方法成员

     int Age { get ; set; } //属性成员

 }

注意:!!!

接口中定义的成员虽然和类成员类似必须满足以下要求:

(根据命名的规范,一般统一来说接口名称必须从大写的I开始写起)

1.接口中的成员不允许使用 public、private、protected、internal 访问修饰符。所有的接口成员都必须是公共的。

2.但是接口声明可以有任何的访问修饰符,public、protected、internal、private,默认是public。

3.接口中的成员不允许使用 static、virtual、abstract、sealed 修饰符。

4.在接口中不能定义字段。

5.在接口中定义的方法不能包含方法的具体实现。

2.接口调用

接口的调用主要分为两种,显示调用和隐式调用。下面具体介绍调用过程:

1.隐示调用

//接口声明
public  interface IEnglish
{
     void Speaker();
    
}

//类继承接口
 class people : IEnglish
{
    public void Speaker() //隐式调用必须要有访问修饰符public
    {
        Console.WriteLine("我想说中国话");
    }
}

//主函数实现

第一种方式:
people pp = new people();
pp.Speaker();  //该种调用不会报错

第二种方式:
IEnglish pt = new people();
pt.Speaker();

2.显示调用

    public  interface IEnglish
    {
         void Speaker();
    
    }

    
         class people : IEnglish
    {

        //不能有public访问修饰符,同时方法的名字必须是接口+方法 如IEnglish.Speaker()

        void IEnglish.Speaker()    
        {
            Console.WriteLine("我想说中国话");

        }
    }

    
    //主函数实现过程

     people pp = new people();
     //pp.Speaker();  该种调用会报错!

     //正确调用
     IEnglish TT = (IEnglish)pp;
     TT.Speaker();

注意:

1、隐式方式people的成员实现有而且必须有自己的访问修饰符(public),显示实现方式people的成员(Speaker)不能有任何的访问修饰符。
2、显示实现方式people使用接口名称和一个句点命名该类成员(Speaker)来实现的:IEnglish.Speaker();

3.隐示实现对象声明为接口和类都可以访问到其行为,显示实现只有声明为接口可以访问。

4.如果两个接口中有相同的方法名,那么同时实现这两个接口的类,C#提供了显示接口实现技术,就是在方法名前加接口名称,用接口名称来限定成员,用“接口名.方法名()”来区分实现的是哪一个接口。

注意:显示接口实现时,在方法名前不能加任何访问修饰符。这种方式和普通方法不同,普通方法前不加访问修饰符,默认为私有的,而显式接口实现时方法前不加任何修饰符,默认为公有的,如果前面加上修饰符,会出现编译错误。

二、接口属性

1,实现接口的任何类或结构必须实现其所有成员的方法。
2,接口不能直接实例化,但是可以通过指向子类间接实例化。
3,接口可以包含方法和属性的声明,但不能包含字段。
4,接口中所有方法、属性默认为public,不能在后面再添加修饰符。
5,类或结构可以实现多个接口。 类可以继承基类并实现一个或多个
接口。

三、接口特点

1.可以实现多接口继承,也就是一个类可以继承多个接口。

using System;
public interface IPerson
{
  string Name
  {
      get;
      set;
  }
  void Show(string name);
}

public interface IStudent
{
  string StudentId
  {
      get;
      set;
  }
  void Show(string studentid);
}

public class Student: IPerson, IStudent  //一个类继承了多个接口;
{
  private string _name;
  public string Name
  {
      get
      {
        return _name;
      }
      set
      {
        _name = value;
      }
  }

2.当两个接口中有相同命名的方法

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {


        //这三种方法都属于强制转换类型

            people pp = new people();
            ((IEnglish)pp).Speaker();
            ((Ichina)pp).Speaker();

            IEnglish pt = new people();
            pt.Speaker();

            people PM = new people();
            IEnglish pl = (IEnglish)PM;
            pl.Speaker();

       
            Console.ReadKey();
        }
    }

    public interface IEnglish
    {
         void Speaker();
    
    }
    public interface Ichina
    {

        void Speaker();
    }
     class people : IEnglish,Ichina
    {
       void IEnglish.Speaker() //隐式调用必须要有访问修饰符public
        {
            Console.WriteLine("我会说英语");
        }

        void Ichina.Speaker() //隐式调用必须要有访问修饰符public
        {
            Console.WriteLine("我会讲中文");
        }
    }
}

具体使用情况如下:

  1. 参数列表+返回值 都相同:实现类只要实现一次此方法即可
  2. 参数列表相同+返回值不同:实现类无法直接实现两个方法(IDE报错),因为不满足方法重载原则
  3. 参数列表不相同:实现类可以分别实现两个方法,可以方法重载

3.接口和父类中名字相同时

1.若子类没有重写该方法,则默认会优先调用父类中的方法,不会报错。

interface A{
    public void run();
}
class B:A
{
    public void run(){
        Console.WriteLine("B中的run()方法");
    }
}

public class Test01 {
    public static void main(String[] args) {
        Test t = new Test();
        t.run();
    }
}
/*
输出:
B中的run()方法
*/

2.若子类重写了该方法,通过显示实现可以调用接口中的方法,否则调用的仍然是该类中固有的方法。

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {

            people pp = new people();
            pp.Speaker();


            IEnglish pt = new people();
            pt.Speaker();


       
            Console.ReadKey();
        }
    }

    public interface IEnglish
    {
        void Speaker();

    }
     class people : IEnglish
    {
          public void Speaker() //隐式调用必须要有访问修饰符public
        {
            Console.WriteLine("我会说英语");
        }
        void IEnglish.Speaker()
        {

            Console.WriteLine("我会说中文");

        }
    }
}

 

四、接口和抽象类的区别

    接口与抽象类非常相似,它定义了一些未实现的属性和方法。所有继承它的类都继承这些成员,在这个角度上,可以把接口理解为一个类的模板。接口最终的目的是起到统一的作用。

1,两者都包含可以由子类继承的抽象成员;

2,两者都不直接实例化。

3,抽象类除拥有抽象成员之外,还可以拥有非抽象成员;而接口所有的成员都是抽象的。
4,抽象成员可以是私有的,而接口的成员默认是公有的。
5,接口中不能含有构造函数、析构函数、静态成员和常量。

6、接口支持多继承,抽象类不能实现多继承。

7、接口只能定义抽象规则,抽象类既可以定义规则,还可能提供已实现的成员。

8、接口是一组行为规范,抽象类是一个不完全的类。

9、接口可以用于支持回调,抽象类不能实现回调,因为继承不支持。

10、接口只包含方法、属性、索引器、事件的签名,但不能定义字段和包含实现的方法,抽象类可以定义字段、属性、包含有实现的方法。

11、接口可以作用于值类型和引用类型,抽象类只能作用于引用类型。例如,Struct就可以继承接口,而不能继承类。

总结起来说,使用C#接口应注意几个问题:
  1、C#中的接口是独立于类来定义的。这与 C++模型是对立的,在 C++中接口实际上就是抽象基类。

  2、接口和类都可以继承多个接口。

  3、类可以继承一个基类,接口根本不能继承类。这种模型避免了 C++的多继承问题,C++中不同基类中的实现可能出现冲突。因此也不再需要诸如虚拟继承和显式作用域这类复杂机制。C#的简化接口模型有助于加快应用程序的开发。

  4、一个接口定义一个只有抽象成员的引用类型。C#中一个接口实际所做的,仅仅只存在着方法标志,但根本就没有执行代码。这就暗示了不能实例化一个接口,只能实例化一个派生自该接口的对象。

  5、接口可以定义方法、属性和索引。所以,对比一个类,接口的特殊性是:当定义一个类时,可以派生自多重接口,而你只能可以从仅有的一个类派生。
 

 

  • 18
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 高效的C,指的是在C语言编程中,能够通过优化代码和提高程序运行效率来达到高效的编程。 首先,在编写C程序时,要注重代码的优化。这包括使用适当的数据结构和算法,避免重复的代码和计算,以及提高代码的可读性和可维护性。例如,使用合适的循环结构、条件判断和函数封装来简化代码,并确保代码逻辑清晰,提高代码的可读性。另外,合理使用C语言的特性和语法,如指针、数组、结构体等,可以提高程序的效率和性能。 其次,编译器的优化也是提高C程序效率的重要手段。C语言的编译器通常会对代码进行优化,以提高程序的执行速度和节省内存空间。编译器的优化包括但不限于:控制流优化、内存访问优化、循环优化等。在编译时,可以通过指定编译器优化级别的方式来控制优化的程度。根据实际需求,选择适合的优化级别,可以在保证程序正确性的前提下,提高程序的执行效率。 此外,对于涉及大量计算或频繁访问内存的程序,可以考虑使用并发编程或多线程技术来提高程序的效率。通过将程序分解为多个并发执行的任务,可以充分利用多核处理器的计算能力。使用多线程技术可以将计算密集型任务与I/O操作分离,提高程序的并发性和效率。 最后,调试和性能分析是提高C程序效率的关键环节。通过调试工具和性能分析工具,可以发现程序中的潜在问题和性能瓶颈,并进行相应的优化。通过逐步调试程序,可以发现代码中的错误和问题,并进行修复。性能分析可以帮助我们找到程序中耗时较多的部分,为进一步的优化提供指导。 总之,要实现高效的C程序,需要注重代码优化、编译器优化、并发编程和性能分析。通过不断的学习和实践,我们能够不断提高C程序的效率和性能。 ### 回答2: 高效的C是指在C语言程序中能够提高代码性能和效率的一系列做法和技巧。 首先,高效的C需要合理地优化算法和数据结构。选择正确的数据结构和算法可以最大程度地提高程序的执行速度和内存使用效率。例如,合理地选择使用数组、链表、队列、栈等数据结构,以及使用快速排序、二分查找等高效的算法,都能够降低程序的时间和空间复杂度。 其次,高效的C需要充分利用编译器的优化功能。通过设置编译器的优化选项,让编译器在编译过程中对代码进行优化,从而提高程序的执行效率。常见的编译器优化包括循环展开、代码复用、内联函数等,这些优化可以减少函数调用开销和循环次数,提高程序的执行速度。 另外,高效的C还需要合理地利用C语言提供的一些特性和技巧。例如,使用位运算代替乘除法可以提高计算速度,使用指针操作可以减少内存访问开销,使用预编译指令可以减少代码冗余等。掌握这些技巧能够使程序更加高效和灵活。 最后,高效的C还需要进行适当的内存管理。C语言没有自动内存回收机制,所以需要开发人员手动管理内存的分配和释放。合理地使用动态内存分配函数(如malloc、free等),避免内存泄漏和多次分配释放开销,是保证程序高效运行的重要一环。 总之,高效的C需要结合合理的算法和数据结构、编译器优化选项、C语言特性和技巧以及良好的内存管理,以实现代码的高性能和高效率。 ### 回答3: 高效的C是指在C语言程序设计中,能够以尽可能少的时间和资源完成任务的代码和技术。在编写高效的C代码时,有以下几点是需要注意的: 首先,合理选择算法和数据结构。在解决问题时,不同的算法和数据结构的选择会对程序的效率产生重大影响。因此,需要根据实际需求选择合适的算法和数据结构,以提高程序的执行效率。 其次,进行适当的优化。在编写C代码时,可以通过一些常见的优化技巧来提高程序的效率,比如使用位运算替代乘除法,减少无用的代码和循环次数,以及使用指针等。但是需要注意的是,优化代码的同时也要考虑代码的可读性和可维护性。 此外,合理使用编译器优化。现代编译器都提供了优化选项,可以根据不同的需求进行配置,如设置编译等级、启用内联函数等。这些优化选项可以帮助提高程序的效率,但需要根据实际情况进行选择和测试。 最后,进行适当的并发处理。对于需要处理大量数据或耗时任务的程序,可以考虑使用多线程或并行处理来提高效率。C语言提供了丰富的线程和并发相关的库和函数,可以方便地实现并发处理。 综上所述,高效的C编程需要合理选择算法和数据结构、进行适当的代码优化、使用编译器优化选项和进行并发处理等。通过这些方法,可以提高C语言程序的执行效率,使程序更加高效和快速地完成任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值