前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >认真CS☀️接口

认真CS☀️接口

作者头像
星河造梦坊官方
发布2024-08-14 16:42:34
1260
发布2024-08-14 16:42:34
举报
文章被收录于专栏:星河造梦坊专栏

如果把接口比作一个合同(规定了你必须做什么,但没规定你怎么做),那么实现了这个合同的类就相当于履行合约的人。这个人必须补充上自己的方式实现接口内规定的所有条款

🟥 什么是接口?

接口是指定一组函数成员(声明)而不实现他们的引用类型(方法),所以只能类和结构来实现接口

🟧 接口作用

代码语言:javascript
复制
using System;

class a
{
    public int a0;
}

class b
{
    public int b0;
}

class Program
{
    static void PrintInfo(a a1)
    {
        Console.WriteLine(a1.a0);
    }

    static void Main()
    {
        a ac = new a() { a0 = 10 };
        b bc = new b() { b0 = 20 };
        PrintInfo(ac);
    }
} 

这段代码很明显无法PrintInfo(bc),即PrintInfo类只能处理特定结构的类,那有没有办法让PrintInfo没有这个限制,能处理各种各样的类呢?接口将这个设想变为可能

🟨 接口实现的原理

接口仅声明方法名,不完成实现,由继承该接口的类完成实现。且我们在调用的方法参数列表里传入接口类型的方法,由于继承的类继承了该接口,继承的类也能传入,也就完成了该设想。也就是说只要继承类继承了该接口,无论该类内部什么结构,则都可以传入该方法

代码语言:javascript
复制
using System;

interface Ia
{
    string a0();
}

class b:Ia
{

    public string a0()
    {
        return "b0";
    }
}

struct c : Ia
{
    public string a0()
    {
        return "c0";
    }
    string c0()
    {
        return "cc0";
    }
}

class Program
{
    static void PrintInfo(Ia a1)
    {
        Console.WriteLine(a1.a0());
    }

    static void Main()
    {
        b ac = new b();
        c bc = new c();
        PrintInfo(ac);
        PrintInfo(bc);
    }
}

🟩 接口定义的条件

2️⃣ 声明接口

a、接口声明不能包含以下成员:

数据成员:字段(int a...)、运算重载符、实例构造函数、析构函数

静态成员

b、接口声明只能包含如下类型的非静态成员函数声明:

方法

属性

事件

索引器

1️⃣ 实现接口

只有类和结构才能实现接口,要实现接口,类或结构必须:

a、在基类列表中包含接口名称

b、为每一个接口的成员提供实现

c、实现接口的方法必须是公共的public

接口中方法默认为public,且接口中修饰符不可改变,实现中方法默认private,所以需加public更改为公共的

注意:如果类从基类继承并实现了接口,基类列表中的基类名称必须放在所有接口之前

代码语言:javascript
复制
class Derived : MyBaseClass, IIfc1, IIfc2
{
    ...
}

🟦 接口是引用类型

接口不仅仅是类或结构要实现的成员列表,它是一个引用类型

我们不能直接通过类对象的成员访问接口(因为接口只有方法名,没有实现,并且下文会提到显、隐式实现,会出现方法名重名 的现象),我们只能通过把类对象强制转换成接口类型来获取指向接口的引用(类对象继承自接口,因为已经将继承类赋值给了接口的引用,所以调用对应接口的方法,会“看到”且实际调用继承类的成员),有了接口的引用,我们便可使用点号来调用接口方法

代码语言:javascript
复制
using System;

interface Ia
{
    void PrintInfo(string a1);
}

class b:Ia
{

    public void PrintInfo(string a1)
    {
        Console.WriteLine(a1);
    }

}

class Program
{
   
    static void Main()
    {
        b bc = new b();
        Ia ac = (Ia)bc;
        //上两句也可直接写为  Ia ac = new b();  
        ac.PrintInfo("I'm ac");
    }
}

🟪 接口和as运算符

如果我们尝试将类对象引用转换为接口的引用,若强制转换不成功则会抛出异常,as运算符可避免这个问题

a类对象引用转换为接口类型ILiveBirth

代码语言:javascript
复制
IliveBirth b = a as ILiveBirth;
if(b!=null)
    {
        ...
    }

🟫 实现多个接口

类或结构可以实现任意数量的接口

所有接口必须列在基类列表中,并以逗号分隔,如果有基类名称(例BaseB),则接口在基类之后

代码语言:javascript
复制
class b:BaseB,Ia,Ib
{
    ...
}

⬛ 实现具有重复成员的接口

如果一个类实现了多个接口,并且其中一些接口有相同签名和返回值,那么类可以实现单个成员来满足所有重复成员的接口

代码语言:javascript
复制
interface Ia
{
    void PrintInfo(string a1);
}

interface Ib
{
    void PrintInfo(string a1);
}

class c:Ia,Ib
{

    public void PrintInfo(string a1)
    {
        Console.WriteLine(a1);
    }

}

🟥 多个接口的引用

即一个类实现了多个接口,那如何对不同接口内的方法进行调用?

在这我们仅讨论这个类实现的都是具有重复成员的接口

答:尽管接口内的成员相同,但接口名不同。我们声明不同的接口,对不同的接口进行调用,从而实现区分相同的方法名

代码语言:javascript
复制
using System;

interface Ia
{
    void PrintInfo(string a1);
}

interface Ib
{
    void PrintInfo(string a1);
}

class c:Ia,Ib
{

    public void PrintInfo(string a1)
    {
        Console.WriteLine(a1);
    }

}

class Program
{
    static void Main()
    {
        Ia a1 = new c();
        Ib b1 = new c();
        a1.PrintInfo("I'm a1");
        b1.PrintInfo("I'm b1");
    }
}

🟧 派生成员作为实现

即实现类是基类的派生,即实现类不仅继承了基类的接口,还可继承基类的方法

代码语言:javascript
复制
using System;

class st
{
public interface Ia
{
    void PrintInfo(string a1);
}

public interface Ib
{
    void PrintInfo(string a1);
}
}

class c:st
{
    class Iaa : Ia,Ib
    {
        public void PrintInfo(string a1)
        {
            Console.WriteLine(a1);
        }
    }
   
    class Program
    {
        static void Main()
        {
            Ia a1 = (Ia)new Iaa();
            Ib b1 = (Ib)new Iaa();
            a1.PrintInfo("I'm a1");
            b1.PrintInfo("I'm b1");
        }
    }
}

🟨 接口可继承接口

代码语言:javascript
复制
interface Ib:Ia
{
    ...
}

🟩

实例:不同类都派生自一个基类且部分类实现一个接口,如何筛选出继承接口的类?

代码语言:javascript
复制
using System;

interface ILiveBirth
{
    string BabyCalled();
}

class Animal { }

class Cat : Animal, ILiveBirth
{
     public string BabyCalled()
    {
        return "kitten";
    }
}

class Dog : Animal, ILiveBirth
{
    public string BabyCalled()
    {
        return "puppy";
    }
}

class Bird : Animal
{

}

class Program
{
    static void Main()
    {
        Animal[] animalArray = new Animal[3];
        animalArray[0] = new Cat();
        animalArray[1] = new Dog();
        animalArray[2] = new Bird();

        foreach (Animal a in animalArray)
        {
            ILiveBirth b = a as ILiveBirth;
            if (b != null)
            {
                Console.WriteLine(b.BabyCalled());
            }
        }
    }
}

大家还有什么问题,欢迎在下方留言!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-09-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 🟥 什么是接口?
  • 🟧 接口作用
  • 🟨 接口实现的原理
  • 🟩 接口定义的条件
    • 2️⃣ 声明接口
      • 1️⃣ 实现接口
      • 🟦 接口是引用类型
      • 🟪 接口和as运算符
      • 🟫 实现多个接口
      • ⬛ 实现具有重复成员的接口
      • 🟥 多个接口的引用
      • 🟧 派生成员作为实现
      • 🟨 接口可继承接口
      • 🟩
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档