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
    评论
第1天 注释的应用 第2天 02_+号的应用 03变量的使用 C中的转义符 05交换量变量 07接收用户的信息 04个练习 06占位符 第3天 04逻辑运算符 05if结构 06习题 03bool类型 02Convert字符转换练习 01Convert字符装换 用户登录 第3天 Net第三天取余 第4天 01异常捕获 02练习 02异常捕获 03switch-case 04while循环 06练习 07while练习与do--while 08for 循环 12continue 09乘法口诀练习 10类型转换和方法转换 11tryparse练习 13三元表达式 第5天 00随机数 05数组 06数组的运用 06数组的运用:冒泡程序 07方法 01枚举 04结构 02枚举和int以及sting类型之间的转换 03枚举练习 第6天 01方法调用 判断是否为整数 yes或no 02方法练习求数组的和 03方法 out参数求数组的和 04 out参数练习 05 out练习 06 ref参数 07 ref 参数练习 08 params 可变参数 09方法的重载 10方法的递归 11方法练习 第7天 01面向对象 02 属性 03练习 第7天 01复习 02方法的调用问题 03判断闰年 04方法概念 05方法练习 06方法的3个练习 07out参数 08使用out参数做登陆 09自己动手写tryparse 10ref参数 11、ref练习 12params可变参数 13、方法的重载 14、方法的递归 15方法练习 第8天 01面向对象复习 02命名空间 03字符串的高级用法 04字符串练习 05继承 Driver Person Program Student Teacher 06继承的练习 第9天 00里氏转换 01里氏转换 M1 M2 M3 M4 person Program 02protected ArrayList集合 ArrayList集合练习 第10天 03_List泛型集合 04_Dictionary 05泛型集合练习 06文件流 FileStream 07StreamReader和StreamWriter 02 file类 01 path类。File.ReadAllBytes 第11天 02 抽象类 Animal Cat Dog Program 02-抽象类 Animal Program 03抽象类练习 04复习 06接口 05设计模式 06序列化 07partial部分类 08sealed密封类 01面向对象-多态 第12天 01接口 02接口的特点 03接口练习 03解决接口与方法重名问题 04收银系统 Banana BuDaZhe CangKu ....... 第13天 01第12天_接口 第14天 01MDI窗体设计 02PictureBox实现图片切换 03PictureBox和timer练习 第14天 MD5加密 03WindowsForms练习 05timer跑马灯练习 06timer闹钟练习不是完整的 08单选和多选练习 01MD5加密 04textBox控件显示输入的文本 02windows控件弹出窗体练习 07简单记事本应用 第15天 01浏览器控件 02下拉框日期选择器 02日期选择器控件 03双击播放音乐 04对话框练习 第16天 01播放音乐 01打开文件双击播放音乐 02线程 03线程执行带参数的方法-摇奖机 04创建服务端Socket(未实现) 04客户端的Socket(未实现) 05创建服务端的Socket 05创建客户端的Socket ConsoleApp1 第17天 02Command操作数据 03DataReader读取数据 04DataSet数据集 05DataAdapter数据适配 01第17天Connection数据库打开关闭 第18天 01DataGridView-表格数据控件 02DataGridView隐藏行列 03 DataGridView直接修改数据 04DataGridView当前行显示不同颜色 05分页 第19天 01进程 02进程 03FileStream文件流 03复制文件 03正则表达式 04正则表达式下载页面图片(未实现) 第20天 01创建XML文档 02对xml文档增删改查 03.2判断是否登录成功原版 03判断是否登录成功 04Xml增删改查 05Xml增删改查(更改的) 第21天 01为什么会有委托 02泛型委托 03多播委托 04使用委托进行窗体传值 05事件 06事件 07程序集的引用 07Common 08反射的常用函数 09用反射制作计算器 第22天 01 SqlConnection 数据库 02ConnectionStringBvilderDemo字符串创建器 03ConfigDemo 配置文件配置连接字符串 05UserDemon 04UserDemo 06DataImporting数据导入 07DataReader读取数据 第23天 第23天UserDemon用户登录

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爬虫与地理信息

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

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

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

打赏作者

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

抵扣说明:

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

余额充值