资源描述
1.索引器 索引器就是一类特殊的属性,通过它们你就可以像引用数组一样访问对象元素的功能。显然,这一功能在创建集合类的场合特别有用,而在其他某些情况下,比如处理大型文件或者抽象某些有限资源等,能让类具有类似数组的行为当然也是非常有用的。本文就会引领你设置类来采用索引器。 索引器的定义如下所示: 修饰符 数据类型 this int index 访问函数体代码 自己写的一个类的简单的索引:namespace InterfaceTest class indexx public string nn = ; public int dd= 0; public indexx(string name, int id) nn=name; dd = id; class sindex private indexx Try = new indexx10; public indexx thisint index get if (index = 0 | index = 0 | index 10) Tryindex = value; public class app public static void Main() sindex sin = new sindex(); sin1 = new indexx(qym, 4312); Console.WriteLine(name is 0 and id is 1, sin1.nn, sin1.dd); Console.ReadLine(); 2.重载运算符重载运算符的格式为:Public static 返回类型 operator 运算符(参数表)示例代码:namespace InterfaceTest public class Reload public int x, y; public Reload() x = y = 0; public Reload(int i,int j) this.x = i; this.y = j; public static Reload operator +(Reload rr, Reload dd) Reload nn = new Reload(); nn.x = rr.x + dd.x; nn.y = rr.y + dd.y; return nn; public static Reload operator +(Reload rr, int d) Reload nn = new Reload(); nn.x = rr.x + d; nn.y = rr.y + d; return nn; public class Run public static void Main() Reload xx = new Reload(23, 43); Reload yy = new Reload(); int g = 10; / Reload uu = new Reload(); / Reload ii = new Reload(); Reload uu = xx + yy; Reload ii = xx + g; Console.WriteLine(xx+yys x=0 and y=1, uu.x, uu.y); Console.WriteLine(xx+gs x=0 and y=1, ii.x, ii.y); Console.ReadLine(); 3.多态性 C#的多态性是指当对不同类的对象执行相同的方法时,系统能根据不同类的对象正确辨别调用各对象所属类的相应方法,从而产生不同的结果。 多态性是通过”虚方法重载”来实现在程序中调用相应对象所属类中的方法,而不是调用基类的方法。虚方法重载就是将基类的某个方法在其派生类中重新定义,而方法名和方法的参数都不改变。虚方法即加修饰符virtual,派生类中用override进行覆盖。 非虚方法真正执行的功能是编译时的对象所属的类中的方法;虚方法面向运行时它实际所属的类的对象,也即虚方法真正执行的功能是运行时的实际对象所属的类中的方法。 New关键字用于派生类对象希望调用派生类中定义的与其基类同名,但作用效果不同的方法;虚方法用于自动实现派生类对象调用自己类中的与基类同名、但作用效果不同的方法。 示例代码:namespace InterfaceTest class VirtualTest public class Employeee public string name; public long idcard; public double salary; public double increase; public Employeee(string n, long i, double m) name = n; idcard = i; salary = m; public void Print() Console.WriteLine(姓名:0, name); Console.WriteLine(身份证号:0, idcard); Console.WriteLine(基本工资:0, salary); Console.WriteLine(增加工资额:0, increase); public virtual void Raise(double percent) increase = percent * salary; public class WorkEmp : Employeee public WorkEmp(string i, long j, double k) : base(i, j, k) public override void Raise(double percent) Console.WriteLine(n普通员工工资增加数额计算:); base.increase = base.salary * percent; public class BachelorEmp : Employeee public BachelorEmp(string i, long j, double k) : base(i, j, k) public override void Raise(double percent) Console.WriteLine(n本科员工工资增加数额计算:); base.Raise(percent); base.increase = base.increase*2; public class MasterEmp : Employeee public MasterEmp(string i, long j, double k) : base(i, j, k) public override void Raise(double percent) Console.WriteLine(n硕士员工工资增加数额计算:); base.Raise(percent); base.increase = base.increase * 3; public class Application public static void Main() Employeee jia = new Employeee(sasa,0,0); WorkEmp aa = new WorkEmp(qym, 54371221, 2000); jia = aa; jia.Raise(0.05); jia.Print(); BachelorEmp bb = new BachelorEmp(qym, 54371221, 2000); jia = bb; jia.Raise(0.05); jia.Print(); MasterEmp cc = new MasterEmp(qym, 54371221, 2000); jia = cc; jia.Raise(0.05); jia.Print(); Console.ReadLine(); 4.类转化is和关键字as Is运算符来检查用户自定义的类类型的使用方法。 As运算符的功能与强制类型的转换类似,可以将一个对象强制转换为另一个类型。as格式如下: 变量 as 数据类型 示例代码和运行结果如下:namespace InterfaceTest class Testisas public class Person public string name; public Person() public Person(string na) this.name = na; public virtual void Showname() Console.Write(Person: 0, name); public class Employee : Person public short hireyear; public Employee() : base() public Employee(string i) : base(i) public override void Showname() Console.Write(Employee: 0, name); public class Manager : Person public short hireyear; public Manager() : base() public Manager(string i) : base(i) public override void Showname() Console.Write(Manager: 0, name); public class App public static void Main() Person pp = new Person3; for (int i = 0; i != 3; +i) Console.WriteLine(Please Enter the Type of Person: E/M?); string ee=Console.ReadLine(); if (ee = m | ee = M) Console.WriteLine(Please Enter the Name of Manager:); Manager mag = new Manager(Console.ReadLine(); ppi = mag as Person; else if (ee = e | ee = E) Console.WriteLine(Please Enter the Name of Employee:); Employee emp = new Employee(Console.ReadLine(); ppi = emp as Person; else -i; for (int i = 0; i != 3; +i) if (ppi is Manager) Console.WriteLine(Manager:+ppi.name); if (ppi is Employee) Console.WriteLine(Employee: + ppi.name); / / ppi.Showname(); / Console.WriteLine(n); / Console.ReadLine(); 5. 代理和多重代理 C#中的代理作用类似于C/C+中的函数指针,代理同接口一样,也是一种引用类型。用关键字delegate定义一个代理,格式如下: 代码属性 修饰符 delegate 返回类型 代理名 (形式参数列表) 由于代理是封闭的,所以不可以派生出新的代理。代理的最大作用是它可以在运行期间决定调用哪个方法,并且不但可以调用对象的实例化方法,还可以调用类的静态方法。 代理与接口在使用上有所不同:当调用单一方法或要为指定的标识和返回类型实现一些方法的时候,通常使用代理;而接口用于声明多个带有不同的标识和返回类型的相关方法。 多重代理:首先创建将要调用的代理实例,并向该实例的调用链表中添加其他代理实例,最后显示代理实例的调用链表,并通过代理实例来调用方法。 使用多重代理的唯一限制是:方法链表中的方法必须具有相同的参数,并且这些方法的返回类型必须定义为void。 使用代理的步骤: 1)先定义代理名并指出调用的方法需要传递的参数2)实例化此代理,并指出调用的方法3)调用格式:实例化对象(需传参数) 实例代码和结果如下:namespace InterfaceTest delegate void MyDelegate(); class DelegateTest public static void StMethod1() Console.WriteLine(调用第一个静态方法.); public static void StMethod2() Console.WriteLine(调用第二个静态方法.); public void InsMethod1() Console.WriteLine(调用第一个实例方法.); public void InsMethod2() Console.WriteLine(调用第二个实例方法.); class Apppp static void PlayDelegate(MyDelegate d) Console.WriteLine(代理0的调用链表为:, d); Delegate cc = d.GetInvocationList(); for (int i = 0; i != cc.Length; +i) Console.WriteLine(第0个元素的目标为:1, i, cci.Target = null ? null : cci.Target); Console.WriteLine(调用方法为:0, cci.Method); Console.WriteLine(当前的目标为0,调用方法为1, d.Target = null ? null : d.Target, d.Method); static void Main() MyDelegate myde = new MyDelegate(DelegateTest.StMethod1); myde += new MyDelegate(DelegateTest.StMethod2); DelegateTest dt = new DelegateTest(); myde += new MyDelegate(dt.InsMethod1); myde += new MyDelegate(dt.InsMethod2); PlayDelegate(myde); Console.WriteLine(); Console.WriteLine(代理实例调用的方法有:); myde(); Console.ReadLine(); 6. 抽象类 问题越上层越抽象,抽象类定义如下:Abstract class 类名 /抽象类的成员定义 抽象方法: public abstract void 方法名(方法参数); 抽象方法也是一种虚方法,在派生类中必须通过方法重写来覆盖。抽象类不能实例化,所以不能用new来生成实例。一个抽象类必须包含抽象方法或者抽象属性。在 其派生类中,不允许使用base关键字访问基类中的抽象方法。 示例代码和运行结果:namespace InterfaceTest class AbstractTest abstract class template protected int a; protected int b; public template(int a, int b) this.a = a; this.b = b; public void getresult() add(a, b); sub(a, b); mul(a, b); div(a, b); Console.ReadLine(); abstract protected void add(int a, int b); abstract protected void sub(int a, int b); abstract protected void mul(int a, int b); abstract protected void div(int a, int b); class caculator : template public caculator(int a, int b) : base(a, b) protected override void add(int a, int b) int r = a + b; Console.WriteLine(0+1=2n, a, b, r); protected override void sub(int a, int b) int r = a - b; Console.WriteLine(0-1=2n, a, b, r); protected override void mul(int a, int b) int r = a * b; Console.WriteLine(0*1=2n, a, b, r); protected override void div(int a, int b) if (b = 0) Console.WriteLine(input error); else int r; r = a / b; Console.WriteLine(0/1=2n, a, b, r); public class CCff public static void Main() caculator cc = new caculator(50, 2); cc.getresult(); 7.密封类和密封方法 是C#提供了阻止类被继承的技术。定义密封类使用sealed修饰符,这种被定义的类不能派生出其他类,也即它不能被继承。定义密封类的一般格式为:Sealed class 类名 /类成员定义 密封类一定不能作为抽象类,因为抽象类是用来派生其他类的。 同理,密封方法可以阻止在派生类中对该方法进行重载。密封方法必须对基类的虚方法进行重写,提供具体的实现方法。 示例代码:using System;class A public virtual void F() Console.WriteLine(A.F); public virtual void G() Console.WriteLine(A.G); class B: A sealed override public void F() Console.WriteLine(B.F); override public void G() Console.WriteLine(B.G); class C: B override public void G() Console.WriteLine(C.G); 类 B 提供两个重写方法:具有 sealed 修饰符的 F 方法和不具有此修饰符的 G 方法。通过使用 sealed 修饰符,B 就可以防止 C 进一步重写 F。8.继承 C#只支持单继承。派生类直接继承其基类成员,并隐式包含其直接基类中除构造函数和析构函数外的所有成员。继承具有可传递性。 派生类可在其基类的基础上添加新成员,但它不能删除所继承的成员和定义。在派生类中,可以通过定义与所继承的基类成员具有相同名称或标识符的新成员来隐藏所继承的成员,从而使所继承的成员在派生类中不可被访问。9.接口接口可以是命名空间或类的成员,并且可以包含下列成员的签名: 方法、属性、索引器和事件。接口是实现多继承,定义了类必须做什么,而不是怎么做。一个接口可从一个或多个基接口继承。当基类型列表包含基类和接口时,基类必须是列表中的第一项。要实现接口的类必须实现接口中的所有成员,但类还可以定义自己的额外成员。在接口成员的声明中不需要任何访问修饰符,而在类中相应的接口成员实现定义中则都用public修饰符。 接口定义: 代码属性 修饰符 interface 接口名:基接口列表 /接口成员定义 一个类实现多个接口的代码如下所示:namespace InterfaceTest class IMClass public interface Ishape double Area(); double GramLength(); int Sides get; public interface IShapePlay void play(); public class Square: Ishape,IShapePlay private int sides; public int SideLength; public Square() sides = 4; public int Sides get return sides; public double Area() return (double)(SideLength * SideLength); public double GramLength() return (double)(SideLength * sides); public void play() Console.WriteLine(n 计算正方形结果如下:); Console.WriteLine(边长:0, this.SideLength); Console.WriteLine(边数:0, this.Sides); Console.WriteLine(面积:0, this.Area(); public class aoo public static void Main() Square sq = new Square(); sq.SideLength = 8; sq.play(); Console.ReadLine(); 实现接口的类可以显式实现该接口的成员。当显式实现某成员时,不能通过类实例访问该成员,而只能通过该接口的实例访问该成员。本教程包含两个示例。第一个示例阐释如何显式实现和访问接口成员。第二个示例展示如何实现具有相同成员名的两个接口。示例一:interface IDimensions float Length(); float Width(); class Box : IDimensions float lengthInches; float widthInches; public Box(float length, float width) lengthInches = length; widthInches = width; / Explicit interface member implementation: float IDimensions.Length() return lengthInches; / Explicit interface member implementation: float IDimensions.Width() return widthInches; public static void Main() / Declare a class instance myBox: Box myBox = new Box(30.0f, 20.0f) IDimensions myDimensions = (IDimensions)myBox System.Console.WriteLine(Length: 0, myDimensions.Length(); System.Console.WriteLine(Width: 0, myDimensions.Width(); 实例二:interface IEnglishDimensions float Length(); float Width(); / Declare the metric units interface: interface IMetricDimensions float Length(); float Width(); / Declare the Box class that implements the two interfaces: / IEnglishDimensions and IMetricDimensions: class Box : IEnglishDimensions, IMetricDimensions float lengthInches; float widthInches; public Box(float length, float width) lengthInches = length; widthInches = width; / Explicitly implement the members of IEnglishDimensions: float IEnglishDimensions.Length() return lengthInches; float IEnglishDimensions.Width() return widthInches; / Explicitly implement the members of IMetricDimensions: float IMetricDimensions.Length() return lengthInches * 2.54f; float IMetricDimensions.Width() return widthInches * 2.54f; public static void Main() / Declare a class instance myBox: Box myBox = new Box(30.0f, 20.0f); IEnglishDimensions eDimensions = (IEnglishDimensions)myBox; IMetricDimensions mDimensions = (IMetricDimensions)myBox; System.Console.WriteLine(Length(in): 0, eDimensions.Length(); System.Console.WriteLine(Width (in): 0, eDimensions.Width(); System.Console.WriteLine(Length(cm): 0, mDimensions.Length(); System.Console.WriteLine(Width (cm): 0, mDimensions.Width(); 接口能够映射到虚方法和抽象方法上。对于虚接口,代码如下:interface IA void play(); class Father : IA public virtual void play() Console.WriteLine(调用基类的方法play(); class Son : Father public override void play() Console.WriteLine(调用派生类的方法play(); 如果为显示接口成员,则实现时不能被定义为虚成员。但可以在显示接口成员实现的过程中调用类的一个虚方法,由于可以在派生类中覆盖这个虚方法,所以同样可以达到调用不同方法的目的。class Father : IA public virtual void play() Console.WriteLine(调用基类的方法play(); void IA.play() Console.WriteLine(调用虚方法VirtualPlay(); VirtualPlay(); 接口成员映射到抽象方法上:interface IA void F(); void G(); abstract class AbsClass : IA public abstract void F(); public abstract void G();10.事件 C# 中的“事件”是当对象发生某些有趣的事情时,类向该类的客户提供通知的一种方法。事件最常见的用途是用于图形用户界面;通常,表示界面中的控件的类具有一些事件,当用户对控件进行某些操作(如单击某个按钮)时,将通知这些事件。 事件是类允许客户为其提供方法(事件发生时应调用这些方法)的委托的一种方法。事件发生时,将调用其客户提供给它的委托。 实例代码如下:namespace InterfaceTest class EventTest public delegate void ChangedEventHandler(object sender, EventArgs e);/定义一个事件的委托, /object sender, EventArgs e 为事件输入参数 public class ListWithChangedEvent:ArrayList public event ChangedEventHandler Changed;/定义委托对象名,并声明是事件的委托,定义在事件的内部 protected virtual void OnChanged(EventArgs e) if (Changed != null) Changed(this, e);/执行委托事件 public override int Add(object value) int i = base.Add(value); OnChanged(EventArgs.Empty); return i; public override void Clear() base.Clear(); OnChanged(EventArgs.Empty); public override object thisint index set baseindex = value; OnChanged(EventArgs.Empty); class EventListener private ListWithChangedEvent List;/类对象 public EventListener(ListWithChangedEvent list) List = list; List.Changed += new ChangedEventHandler(ListChanged);/声明委托的函数 private void ListChanged(object sender, EventArgs e) Console.WriteLine(This is called when the eve
展开阅读全文