接口、索引器、Foreach的本质(学习笔记)
接口
什么是接口?
接口代表一种能力,和抽象类类似但比抽象类的抽象程度更高!
接口的定义:
public interface IEat//定义一个接口
{
void Eat(string food);//为该接口定义一种能力
}接口的定义
从上边的例子中我们可以看到,接口中的方法是没有方法体的甚至连访问修饰符都没有。而且在接口中只能有方法、属性、索引器及事件!
接口的使用:
public class
Dog:IEat //Dog类实现IEat接口
{
//Dog类实现IEat接口的Eat方法
public void Eat(string food)
{
Console.WriteLine("吃"+food);
}
}
接口的使用
注意:如果一个类实现了一个接口则该类必须实现该接口及其父接口的所用方法除非该类是一个抽象类则交由该类的子类来实现!一个接口也可以继承另一个接口而不实现该接口的方法而是交由其实现者来实现
Demo:
//接口一
public Interface IEat
{
void Eat();
}
//接口二
public Interface Ipaly
{
void Play();
}
//接口三
public Interface Itravel:IEat,Ipaly
{
//接口三继承接口一和接口二
} public class program:Itravel
{
public void Eat()
{
//省略方法体
}
public void Play()
{
//省略方法体
}
}Mode
从上面的demo中一些可以看到Itravel接口继承的IEat接口和Ipaly接口可能有些朋友要问了”在C#以及JAVA中不是不支持多继承吗?”
注意这句活是针对类而言的,但针对接口来说一个类是可以实现多个接口的同样一个接口也可以继承多个接口
接口和抽象类的区别:
当需要的各个对象之间存在父子类关系时,可以考虑使用抽象类,
当各个对象之间不存在继承关系,只是有相同的能力时,而已考虑使用接口
抽象类是某一类事物的抽象结果而接口则代表某些事物的一种能力
接口的注意点:
01.接口就是为了约束方法的格式(参数和返回值类型)而存在的
02.接口可以实现多继承,弥补单继承的缺陷。
03.接口可以看成是一个特殊的抽象类,通过反编译看源码可知
04.接口中方法不用访问修饰符,因为CLR会自动添加,并且不能有方法体
05.如果一个类实现了某个接口,就得实现该接口中所有的方法
06.接口要谨慎使用,防止出现接口污染!
07.接口仅仅代表一种能力,实现该接口的类和接口没有继承关系
08.接口是用来实现的,类是用来继承的。
09.其实很多时候,看似可以不用接口,因为接口就是一个方法的约定,
10.抽象类也可以实现接口,但接口成员必须映射到抽象类的抽象成员。抽象类的派生类如果是非抽象类,则必须通过方法重载来实现接口成员
索引器
为什么要使用索引器?
解析:当一个类中包含数组或集合成员时使用索引器可以大大简化度数组或集合成员的存取操作。
索引器的定义
索引器的定义和属性类似
/*[修饰符] 数据类型 this[索引类型 index]
{
get{//获得属性的代码}
set{ //设置属性的代码}
}
*/索引器的定义语法
demo:
public class Students
{
string[] names = new string[3];
public string this[int index] {
get{return names[index];}
set{names[index]=value;}
}
int[] age = new int[3];
public int this[string Key]
{ get {
for (int i = 0; i < names.Length;i++ )
{
if (Key.Equals(names[i]))
{
return age[i];
}
}
return -1; }
set
{
for (int i = 0; i < names.Length; i++)
{
if (Key.Equals(names[i]))
{
age[i]=value;
}
}
;
}
}
}
demo
Foreach的本质:
为什么数组和集合可以用Foreach遍历?
解析:因为数组和集合都实现了IEnumerable接口,该接口只有一个方法GetEnumerator()所以只要实现了IEnumerable接口的类都可以被Foreach遍历
// 摘要:
// 公开枚举数,该枚举数支持在非泛型集合上进行简单迭代。
[ComVisible(true)]
[Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerable
{
// 摘要:
// 返回一个循环访问集合的枚举数。
//
// 返回结果:
// 一个可用于循环访问集合的 System.Collections.IEnumerator 对象。
[DispId(-4)]
IEnumerator GetEnumerator();
}IEnumerable原型
从上面代码中我们可以看到IEnumerable接口的GetEnumerator()方法返回一个实现了IEnumerator接口的对象!
// 摘要:
// 支持对非泛型集合的简单迭代。
[ComVisible(true)]
[Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerator
{
// 摘要:
// 获取集合中的当前元素。
//
// 返回结果:
// 集合中的当前元素。
object Current { get; } // 摘要:
// 将枚举数推进到集合的下一个元素。
//
// 返回结果:
// 如果枚举数成功地推进到下一个元素,则为 true;如果枚举数越过集合的结尾,则为 false。
//
// 异常:
// System.InvalidOperationException:
// 在创建了枚举数后集合被修改了。
bool MoveNext();
//
// 摘要:
// 将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。
//
// 异常:
// System.InvalidOperationException:
// 在创建了枚举数后集合被修改了。
void Reset();
}IEnumerator原型
当我们使用Foreach遍历一个对象时会先执行该队形的GetIEnumerable方法得到一个迭代器(实现的IEnumerator接口的对象),然后调用给对象的Reset方法来初始枚举数,然后执行该对象的MoveNext()方法得到Bool值如果该方法返回真则调用该对象的Current属性得到值在执行MoveNext()方法直到该方法返回假则退出迭代
Demo:
//可供Foreach遍历的类(实现了IEnmerable接口)
public class MyList:IEnumerable
{
ArrayList list = new ArrayList();
public void Add(object o)
{
list.Add(o);
}
public IEnumerator GetEnumerator()
{
return new MyIenumerator(list);
}
}
//实现了IEnumerator接口的类
public class MyIenumerator:IEnumerator
{
public MyIenumerator(ArrayList list)
{
this.list = list;
}
ArrayList list = new ArrayList();
int I = -1;
public object Current
{
get { return list[I]; }
} public bool MoveNext()
{
bool falg = false;
if (I<list.Count-1)
{
I++;
falg = true;
}
return falg;
} public void Reset()
{ }
}自定义可供foreach遍历的类
接口、索引器、Foreach的本质(学习笔记)的更多相关文章
- RESTful接口设计原则/最佳实践(学习笔记)
RESTful接口设计原则/最佳实践(学习笔记) 原文地址:http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api 1 ...
- java拦截器(Interceptor)学习笔记
1,拦截器的概念 java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了 ...
- PHP以接口方式实现多重继承(完全模拟)--学习笔记
1.UML类图: 2.PHP代码: <?php /** * Created by PhpStorm. * User: andy * Date: 16-11-23 * Time: 下午7:57 ...
- 【接口】【USB】1.学习笔记
1.USB的优点: 可以热插拔,即插上后可以自动识别: 系统总线供电,USB共有四根线,一根电源线,一根地线,一根D+线,一根D-线,D+和D-线是差分输入线: 可以支持多种设备,且扩展容易,通过HU ...
- JVM 类加载器ClassLoader源码学习笔记
类加载 在Java代码中,类型的加载.连接与初始化过程都是在程序运行期间完成的. 类型可以是Class,Interface, 枚举等. Java虚拟机与程序的生命周期 在如下几种情况下,Java虚拟机 ...
- C# 接口中的索引器
索引器可在 接口(C# 参考) 上声明.接口索引器的访问器与类索引器的访问器具有以下方面的不同: 接口访问器不使用修饰符. 接口访问器没有体. 因此,访问器的用途是指示索引器是读写.只读还是只写.以下 ...
- vue.js 学习笔记3——TypeScript
目录 vue.js 学习笔记3--TypeScript 工具 基础类型 数组 元组 枚举 字面量 接口 类类型 类类型要素 函数 函数参数 this对象和类型 重载 迭代器 Symbol.iterat ...
- [原创]java WEB学习笔记75:Struts2 学习之路-- 总结 和 目录
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Directx11学习笔记【二十二】 用高度图实现地形
本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5827714.html 在前面我们曾经实现过简单的地形(Direct ...
- Linux学习笔记——如何使用共享库交叉编译
0.前言 在较为复杂的项目中会利用到交叉编译得到的共享库(*.so文件).在这样的情况下便会产生下面疑问,比如: [1]交叉编译时的共享库是否须要放置于目标板中,假设须要放置在哪个文件 ...
随机推荐
- 剑指offer——03从尾至头打印列表(Python3)
思路:相当于数据结构中的链表就地逆置,可以使用头插法来实现. 代码: class Solution: # 返回从尾部到头部的列表值序列,例如[1,2,3] def printListF ...
- 38.Qt模型/视图结构
1.模型/视图类 2.模型 3.视图 4.代理 1 模型/视图类 InterView框架提供了一些可以直接使用的模型类和视图类,如QStandardModel类,QDirModel类,QStringL ...
- POJ 2239 匈牙利算法
思路:最大匹配 也是很裸的一道题-. // by SiriusRen #include <cstdio> #include <cstring> #include <alg ...
- vs的任务列表
前几天才刚开始看到这个 很多时候,一些任务,怕忘记了,或者已经做好的东西,由于各种原因,暂时不用等等这种情况 这时候,就可以在vs上,随时加到任务列表中,方面下次直接来修改或实现等等 在vs的视图&g ...
- 洛谷P3704 [SDOI2017]数字表格
题目描述 Doris刚刚学习了fibonacci数列.用f[i]f[i] 表示数列的第ii 项,那么 f[0]=0f[0]=0 ,f[1]=1f[1]=1 , f[n]=f[n-1]+f[n-2],n ...
- 达夫设备之js
最近阅读<高性能JavaScript>时,在书中的“达夫设备“ . 对此,有些感悟,同时有些疑问,希望看到的朋友,能帮忙解释下,在此先提前感谢了. 1. 先说自己的理解吧: ”达夫设备“的 ...
- DataBaseFactory基础了解
<add name="Connection str" connectionString="data source=.;pwd=12;uid=sa;database ...
- golden gate的DDL配置
DDL复制的配置 目前只支持oracle和teradata的ddl复制 oracle能复制除了系统对象之外的所有对象 两种配置方法: 基于trigger的DDL:对于生产库有一定影响. 原理: 源库建 ...
- 服务器上安装anaconda
1.在anaconda网站下载安装包: 清华镜像网站:https://repo.continuum.io/archive/index.html 2.下载最新版本为python3 ,Linux64位的: ...
- Python笔记24-----迭代器、生成器的使用(如嵌套列表的展开、树的遍历等)
1.递归yield使用: 嵌套列表展开 def flatten(nested): if type(nested)==list: for sublist in nested: for i in flat ...