首页 > 编程语言 >c# 接口、抽象类

c# 接口、抽象类

时间:2023-04-17 17:58:22浏览次数:45  
标签:c# 成员 接口 实现 基类 抽象类 public

接口概述

接口像类一样声明,里面的成员可以包含方法的签名(是隐式public的且抽象的)、属性、事件和委托,但在接口中不可以定义数据成员(字段)和静态成员。

与类不同的是,接口中仅仅是他们的声明,并不提供实现。因此接口是函数声明的集合。如果类或结构从一个接口派生,则这个类或结构负责实现该接口中所声明的所有成员。一个接口可以从多个接口继承,而一个类或结构可以实现多个接口。

出现缘由

由于c#语言不支持一个类同时继承多个类,因此,如果某个类需要继承多方面的行为时,可以通过继承多个接口实现。

接口的作用

接口是一组规则的集合,它规定了实现本接口的类或接口必须拥有的一组规则。体现了自然界“如果你是……则必须能……”的理念。

接口声明格式:

【修饰符】 interface 接口名(建议以大写字母I开头) 【:基接口1,基接口2,……】

  • 接口中每个成员的声明后必须加分号(属性的{ }后不用加),不能包含任何实现。

  • 接口内的成员声明不能包含任何修饰符,所有接口成员的访问方式自动是public;

  • 声明一个类来实现一个接口,如果该类还要显示声明基类,则基类和接口之间要有逗号分开,且基类写在前面。

  • 若类要实现某个接口,则必须实现该接口里的所有接口成员;

  • 如果基类实现了某个接口,则其接口成员就不能在该基类的派生类中再次实现了。基类也可以在接口成员上添加virtual关键字,则派生类可以通过重写来实现这些接口成员,可以参照基类的重写.

  • 如果一个类实现了多个接口,并且有些接口里的成员的签名和返回类型相同,那么,在类中只需要实现一个就能满足所有相同的了。

  • 接口和as运算符:如果我们尝试将类对象引用强制转换为类未实现的接口的引用,则会抛出一个异常,那么as运算符就是为了避免这个问题。格式:
    接口名 变量名=类对象名 as 接口名; 这时,如果类实现了接口,表达式返回指向接口的引用,若未实现,表达式返回null而不是抛出异常;

接口实现方式

实现接口有两种方式,隐式和显示。

/*main 方法里:*/
IMust1 m1 = new MyClass();
m1.MustCan1();//显示实现的接口方法,只能接口类型实例来调用
IMust2 m2 = new MyClass();
m2.MustCan2();

MyClass c1 = new MyClass();
c1.MustCan2();
//c1..MustCan1();//编译报错,不能调用显示实现的方法:MustCan1()
(c1 as IMust1)?.MustCan1();//但可以转换成接口引用后再调用
Console.Read();

/*准备接口和实现类*/
public interface IMust1
{
    void MustCan1();
}
public interface IMust2
{
    void MustCan2();
}
public class MyClass:IMust1,IMust2
{
    //显式实现接口,”指名道姓”的写出要实现哪个接口的哪个方法。
    void IMust1.MustCan1()
    {
        throw new NotImplementedException();
    }
    //隐式实现接口,直接方法名。
    public void MustCan2()
    {
        throw new NotImplementedException();
    }

    public virtual void MyFunc() => Console.WriteLine("I'm 1111.");
}

注意:

  • 显式接口实现方式,是为了希望每个接口分离实现,且方法不能使用任何访问修饰符,都默认为私有。因此只可以通过指向接口的引用来访问。

  • 隐式接口实现,类或接口都可以访问接口中的方法;

所以

  • 当类实现单个接口时,通常使用隐式接口实现方式,这样类的对象可以直接去访问接口方法。

  • 当类实现多个接口且不同接口中有相同方法签名和返回类型的方法时,则使用显示接口实现方式。即使没有相同的方法啊签名,在实现多个接口时,仍推荐使用显示接口实现方式,因为这样可以标识出哪个方法属于哪个接口。

显示接口实现的这些成员都不能通过类的对象访问。但是可以把类对象再显示的转换为对应的接口,然后通过接口来调用方法,这样就能调用了。

论接口(interface)与抽象类(abstract class)

有网友说:

单从具体功能来看,除多重继承外(C#,Java中),抽象类似乎完全能取代接口。但是,难道接口的存在是为了实现多重继承?当然不是。我认为,抽象类和接口的区别在于使用动机。使用抽象类是为了代码的复用,而使用接口的动机是为了实现多态性。所以,如果你在为某个地方该使用接口还是抽象类而犹豫不决时,那么可以想想你的动机是什么。”

参考:http://www.cnblogs.com/huihui-gohay/archive/2009/12/13/1623070.html。

觉得有理,自己再总结下:

接口:用于约束子类行为。体现了自然界“如果你是……则必须能……”的理念。

抽象类:为继承而用,所以代码复用是显然的意图。抽象类和子类,就是一般和特殊的区别。

不管是接口还是抽象类,结合子类或实现类,都能实现多态(抽象类需要子类各自覆写方法,接口实现类则直接各自实现方法即可)。

我是想,考虑代码复用的话,用抽象类,否则用接口。和上面网友观点基本一致。


更新于:2023-04-17

标签:c#,成员,接口,实现,基类,抽象类,public
From: https://www.cnblogs.com/idasheng/p/17326628.html

相关文章

  • cmake学习
    Cmake学习最开始加:cmake_minimum_required(VERSION3.10.2)一、Cmake介绍1、cmake一款高级的编译配置工具2、编译过程和配置步骤都是通过CMakeLists.txt来完成二、Cmake操作流程1、编写源码cpp源代码2、编写CMakeLists.txtPROJECT(HELLO)SET(SRC_LISTmain.cpp)MESSA......
  • 使用vue-cli创建第一个vue项目
    命令提示符切换至需要创建项目的目录:直接在路径输入cmd在按键盘的enter键打开的终端就直接切换到该目录下(1)输入以下命令:vuecreate项目名称(2)我这里选手动选择,键盘上下按钮,选完后按enter键(3)我这里选Babel和CSS,键盘上下按钮,选中或取消选中按空格,选完后按enter键(4)我这里选......
  • oracle登录
    oracle登录允许错误次数设置一般数据库默认是10次尝试失败后锁住用户1、查看FAILED_LOGIN_ATTEMPTS的值select*fromdba_profiles2、修改为30次alterprofiledefaultlimitFAILED_LOGIN_ATTEMPTS30;3、修改为无限次(为安全起见,不建议使用)alterprofi......
  • mock软件工程化设计
    1、需求(1)ws_client用来模拟ws协议的客户端,向总体网的数据通道发送数据。通过cli插件,满足用户交互。需要考虑各种数据,周期/非周期,周期间隔,表号send1203100(ms)cyclicsendAcycliclist-c/-ac:查询所有的cyclic和acyclic表号同时发送多张表,如何发,指令如何设计考虑......
  • css实现艺术字
    最近在写一个新的小活动,本来有涉及艺术字的标题,本来是想用图片展示的,后来面向百度编程的时候,发现可以使用css来实现效果及代码如下font-size:60rpx;color:#fff;text-shadow:005px#FF0200,0010px#727272;text-align:center;margin:30rpxau......
  • WebSocket+心跳机制
    maven依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>WebSocket.classimportcn.hutool.json.JSONUtil;importlombok.SneakyThrows;impo......
  • oracle open_cursor监控
    SELECTmax(a.value)ashighest_open_cur,p.valueasmax_open_curFROMv$sesstata,v$statnameb,v$parameterpWHEREa.statistic#=b.statistic#andb.name='openedcursorscurrent'andp.name='open_cursors'groupbyp.value;mos......
  • ECShop开源商城与COS互通:降低本地存储负载、提升访问体验
    ECShop简介ECShop是一款开源电子商务平台,具有简单易用、安全稳定、模块化设计等特点。它提供了完整的电子商务解决方案,包括商品管理、订单管理、支付管理、配送管理、会员管理、促销管理、数据统计等功能。ECShop支持多语言、多货币、多种支付方式和配送方式,并可通过插件扩展更多......
  • 记录 RedisTemplate.executePipelined 使用问题
    需求,向redis写入2000万个key@Slf4j@Component("job2")publicclassToRedis2implementsIJob{privateAtomicLongcount=newAtomicLong(0);privateLongoldCount=0L;privateList<String>userIdList=newArrayList<>();pri......
  • ansible的docker_container模块使用
    使用docker_container模块创建容器示例:----hosts:myserveripremote_user:root#执行用户gather_facts:false#屏蔽系统信息返回vars:ansible_python_interpreter:/usr/bin/python3#定义ansible使用python3的环境serial:"100%"#更新比列,可以......