C#学习——4.接口实现多态

1.接口的概念
1.1什么是接口?

接口是一种规范,是一种约束形式,其中只包括成员定义,不包含成员实现的内容。接口是一种能力,没有具体实现,像抽象方法一样,光说不做

1.2接口怎么定义?

接口的定义与类的定义是类似的,只不过关键字不是class,而是interface。具体定义的特点如下:

  • 接口成员不允许使用访问修饰符,所有接口成员都隐式为公共成员。
  • 接口成员只能包括方法、属性、索引器、事件,本质都是方法,不能有字段,更不能包含方法体。
  • 不能用关键字static、virtual、abstract或sealed来定义接口成员。
  • 如果要隐藏从基接口中继承的成员,可以用new关键字来定义。
  • 继承接口的类必须实现接口中所有成员,除非子类是抽象类。

需要注意的是接口名称一般以大写字母I开始,下面定义一个展示对象信息的接口:

interface IShowInfo
{
    void ShowInfo();
}
1.3接口怎么实现?

让某个类继承上面定义的接口,实现接口中定义的打印信息的方法,就实现了这个接口。需要注意的是,接口的实现分为普通实现方法和显示实现方法两种。
下面这种是普通实现方法:

class Animal:IShowInfo
{
    public void ShowInfo()
    {
        Console.WriteLine("我是动物类,实现了ShowInfo()接口。");
    }
}

下面这种是显式实现方法:

class Animal1 : IShowInfo
{
    void IShowInfo.ShowInfo()
    {
        Console.WriteLine("我是动物类,显式实现了ShowInfo()接口。");
    }
}

为什么需要显式实现接口呢?假设一个类实现了多个接口,每个接口中都有一个定义相同的方法,我们用一个类来继承这两个接口,示例如下:

interface IShowInfo
{
    void ShowInfo();
}

interface IShowInfo1
{
    void ShowInfo();
}
class Animal1 : IShowInfo,IShowInfo1
{
    void ShowInfo()
    {
      //尴尬了!!!!!
    }
}

上述情况中,我们没法区分实现的是哪一个接口中的方法,普通实现方法就行不通了。所以,显式方法就是为了解决这个问题产生的。显式实现时采取 【接口名.方法名】方式就行了。如下所示:

class Animal1 : IShowInfo,IShowInfo1
{
    void IShowInfo.ShowInfo()
    {
        Console.WriteLine("我是动物类,实现了IShowInfo接口。");
    }
    void IShowInfo1.ShowInfo()
    {
        Console.WriteLine("我是动物类,实现了IShowInfo1接口。");
    }
}
1.4接口怎么调用?
  • 普通方式实现接口和调用:
class Animal:IShowInfo
{
    public void ShowInfo()
    {
        Console.WriteLine("我是动物类,实现了ShowInfo()接口。");
    }
}
Animal p1 = new Animal();
p1.ShowInfo();
IShowInfo p2 = new Animal();
p2.ShowInfo();

结果如下:

我是动物类,实现了ShowInfo()接口。
我是动物类,实现了ShowInfo()接口。
  • 显式实现接口和调用:
class Animal1 : IShowInfo
{
    void IShowInfo.ShowInfo()
    {
       Console.WriteLine("我是动物类,显式实现了ShowInfo()接口。");
    }
}

            
Animal1 p3 = new Animal1();
//p3.ShowInfo(); //error
(p3 as IShowInfo).ShowInfo();
IShowInfo p4 = new Animal1();
p4.ShowInfo();

结果如下:

我是动物类,显式方法实现了ShowInfo()接口。
我是动物类,显式方法实现了ShowInfo()接口。

可以发现,显式实现的接口方法在类中都是私有的,无法通过类的实例对象直接调用,需要把实例先转型成为对应的接口类型再进行调用。

1.4接口有什么作用?

接口的主要目的是为不相关的类提供通用的处理服务,实现多态。由于C#中只允许树形结构中的单继承,即一个类只能继承一个父类,所以接口是让一个类具有两个以上基类的唯一方式。一接口解决了类的多继承,又能使类继承后体积不那么庞大。

2.接口实现多态的例子

IShowInfo.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _3.接口_demo2
{
    interface IShowInfo
    {
        void ShowInfo();
    }
}

Car.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _3.接口_demo2
{
    abstract public class Car : IShowInfo
    {
        public string Name
        {
            get;
            set;
        }

        public double Price
        {
            get;
            set;
        }

        public abstract void ShowInfo();
    }

    public class Bieke : Car
    {

        public override void ShowInfo()
        {
            Console.WriteLine("我是别克车!");
        }
    }

    public class Aodi : Car
    {

        public override void ShowInfo()
        {
            Console.WriteLine("我是奥迪车!");
        }
    }
}

Person.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _3.接口_demo2
{
    public class Person : IShowInfo
    {
        public string Name
        {
            get;
            set;
        }
        public int Age
        {
            get;
            set;
        }

        public virtual void ShowInfo()
        {
        }
    }

    class American : Person
    {
        
        public override void ShowInfo()
        {
            Console.WriteLine("我是美国人....");
        }
    }

    class Chinese : Person
    {
        public override void ShowInfo()
        {
            Console.WriteLine("我是中国人....");
        }
    }

    class German : Person
    {
        public override void ShowInfo()
        {
            Console.WriteLine("我是德国人....");
        }
    }
}

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _3.接口_demo2
{
    class Program
    {
        static void Main(string[] args)
        {
            Person c = new Chinese();
            c.ShowInfo();
            Register(c);
            Person a = new American();
            Register(a);
            Person g = new German();
            Register(g);
            Car aodi = new Aodi();
            Register(aodi);
            Car bieke = new Bieke();
            Register(bieke);

            Console.ReadKey();
        }

        public static void Register(IShowInfo i)
        {
            i.ShowInfo();
        }
    }
}

结果如下:

我是中国人....
我是中国人....
我是美国人....
我是德国人....
我是奥迪车!
我是别克车!

欢迎关注我的公众号。
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

遥感与地理信息

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值