I think we are all successful people.

当别人拿着高工资而你却还做着底层工作人员的时候是否应会觉得不服,那你应该该想想为什么了。

 

今天给大家带来的知识:

(1)接口的理解

(2)索引器的理解

(3)foreach的本质

(4)匿名内部类

(5)运算符重载

 

一:接口的理解

接口是一种数据类型,它是可扩展性,利用接口可以实现多态;接口只能定义方法不能定义变量。

命名接口大都是以I开头(Interface)

定义接口:

01.接口就是为了约束方法的格式(参数和返回值类型)而存在的
02.接口可以实现多继承,弥补单继承的缺陷。
03.接口可以看成是一个特殊的抽象类,通过反编译看源码可知
04.接口中方法不用访问修饰符,因为CLR会自动添加,并且不能有方法体
05.如果一个类实现了某个接口,就得实现该接口中所有的方法
06.接口要谨慎使用,防止出现接口污染!
07.接口仅仅代表一种能力,实现该接口的类和接口没有继承关系
08.接口是用来实现的,类是用来继承的。
09.其实很多时候,看似可以不用接口,因为接口就是一个方法的约定,表明你这个类必须要有某些方法,但是不写接口也可以有这些方法,用了接口,就可以使用
接口变量,统一调用,实现多态

关键字:interface

接口:接口  是继承关系

子类:接口 是实现关系

抽象类和接口的区别:

  当需要的各个对象之间存在父子类关系时,可以考虑使用抽象类,

  当各个对象之间不存在继承关系,只是有相同的能力时,而已考虑使用接口

接口的通俗理解:

01.飞机会飞,鸟会飞,他们都继承了同一个接口“飞”;但是F22属于飞机抽象类,鸽子属于鸟抽象类。

02.就像铁门木门都是门(抽象类),你想要个门我给不了(不能实例化),但我可以给你个具体的铁门或木门(多态);而且只能是门,你不能说它是窗(单继承);

      一个门可以有锁(接口)也可以有门铃(多实现)。 门(抽象类)定义了你是什么,接口(锁)规定了你能做什么(一个接口最好只能做一件事,你不能要求锁也

  能发出声音 (接口污染))

例子:

//定义一个接口
namespace 接口
{
   public interface IFly
    {
       string Say(string msg);
    }
}
//定义一个Plane类
class Plane:IFly,IPlay
//两个接口是继承关系
    {

        public string Say(string msg)
        {
            Console.WriteLine("我是一只小飞机小呀小飞机");
            return "飞机阿";
        }

        public string Eat(string msg)
        {
            return "我吃汽油";
        }
    }

//定义一个Bird类
public class Bird:IFly,IPlay
    {
        public string Say(string msg)
        {
            Console.WriteLine("我是一只小小鸟");
            return "小鸟!";
        }

        public string Eat(string msg)
        {
            return "虫子";
        }
    }

  

//实现
class Program
    {
        static void Main(string[] args)
        {
            IFly[] flys = {
                          new Bird(),
                          new Plane(),
                          };
            foreach(IFly fly in flys)
            {
                Console.WriteLine( fly.Say("天气不错"));
               
            }
            Console.ReadLine();
        }
    }

接口是组件之间的协议,描述了组件对外提供的服务。从技术上讲接口是一组包含了函数型方法的数据结构。通过这组数据结构,客户代码可以调用组件对象的功能。

接口可以从父接口中继承。接口的继承首先是说明性继承,不是实现性继承,它的实现需要通过类或结构来实现;其次接口继承可以是多继承。

由于接口允许多继承,在可能发生二义性的地方可以采用全权名来避免。可以用类来实现接口。在类中定位接口成员的实现称之为接口映射。类必须为接口的所有成员

提供具体的实现,包括接口中显式定义的成员,以及接口从父接口中继承而来的成员。同样,在对接口的实现过程中可以采用显式接口成员执行体来避免产生二义性。

派生类可以对基类已经实现的接口进行重实现。抽象类也可以实现接口,但接口成员必须映射到抽象类的抽象成员。抽象类的派生类如果是非抽象类,则必须通过方法

重载来实现接口成员。

 

二:索引器

语法:

 

 [修饰符] 数据类型 this[索引类型 index]

  {

    get{//获得属性的代码}                                             

    set{ //设置属性的代码}

  }

  

例:public string this[int index]

this:当前类的实例

namespace 自定义索引器
{
    class Student
    {
        //定义一个集合
       private string[] name = new string[2];
        //定义一个索引器
       public string this[int index]
       {
           get { return name[index]; }
           set { name[index] = value; }
       }
    }
}

  

namespace 自定义索引器
{
    class Program
    {
        static void Main(string[] args)
        {
            Student stu = new Student();
            stu[0] = "亿";
            stu[1] = "二";
            Console.WriteLine(stu[0]);
            Console.WriteLine(stu[1]);
            Console.ReadLine();
        }
    }
}

  

三:foreach本质

foreach原理:本质:集合实现了一个IEnumerable接口

例子:

namespace foreach本质
{
  public  class MyIEnumertor:IEnumerator
    {
      ArrayList list = new ArrayList();
      public MyIEnumertor(ArrayList mylist)
      {
          list = mylist;
      }
      private int i = -1;

      public object Current
      {
          get { return list[i]; }
      }

      public bool MoveNext()
      {
          bool flag = false;
          if(i<list.Count-1)
          {
              i++;
              flag = true;
          }
          return flag;
      }

      public void Reset()
      {
          i = -1;
      }
    }
}

 

namespace foreach本质
{
    public class MyCollection : MyIEnumertor
    {
        ArrayList list = new ArrayList();
        public void Add(object o )
        {
            list.Add(o);
        }
        public MyIEnumertor GetEnumerator()
        {
            return new MyIEnumertor(list);
        }
    }
}

  

namespace foreach本质
{
    class Program
    {
        static void Main(string[] args)
        {
            MyCollection list = new MyCollection();
            list.Add("111");
            list.Add("222");
            foreach(object item in list)
            {
                Console.WriteLine(item);
            }
            ArrayList list2 = new ArrayList();
            foreach(object item in list2)
            {
            
            }
            Console.ReadLine();
        }
    }
}
为什么数组和集合可以使用foreach遍历?
解析:因为数组和集合都实现了IEnumerable接口,该接口中只有一个方法,GetEnumerator(),该方法返回类型为IEnumerator类型
02.数组类型是从抽象基类型 Array 派生的引用类型。由于此类型实现了 IEnumerable,因此可以对 C# 中的所有数组使用 foreach 迭代。
 
四:匿名内部类
语法:
var stu = new {Name = "xxx"};

  

var stu = new {Name = "贾宝玉", Age = 4};
var tom = new {Name = "林黛玉", Age = 5};
02.匿名类在底层还会被CLR编译成一个有名字的类(看源码)
03.匿名类型提供了一种方便的方法,可用来将一组只读属性封装到单个对象中,而无需首先显式定义一个类型。 类型名由编译器生成,并且不能在源代码级使用。 每个属性的类型由编译器推断。
可通过使用 new 运算符和对象初始值创建匿名类型
 
五:运算符重载
C# 允许用户定义的类型通过使用 operator 关键字定义静态成员函数来重载运算符。
public static int operator+(work d1,work d2)
{
      return d1.ID+d2.ID;          
}
Work work1=new Work(){Name = "张三",ID = 1};
Work work2 = new Work() { Name = "张三2", ID = 1 };
Console.WriteLine(work1+work2);

  

补充知识点:
01.Java中==和Equals区别
02.C#中==和Equals区别

01.==比较的是地址  Equals比较的是存储的值

02.C#中String类的==和Equals等价

 

 

如果对大家有帮助希望大家多多支持,期待下次的作品~

  

  

 

posted on 2016-04-13 14:49  张BC  阅读(204)  评论(0编辑  收藏  举报
We are all best creamIT.