基础拾遗:
引用CLR VIA C#(类和接口继承)
在Microsoft.Net Framwork中,有一个名为System.Object的类,它定义了4个公共实例方法:ToString, Equals, GetHashCode和GetType。该类是其他所有类的根或者说最终基类。换言之,所有类都继承了Object的4个实例方法。这还意味着能操作 Object类的实例的代码实际能操作任何类的实例。1.接口的特性
1.1.接口是一个引用类型,通过接口可以实现多重继承。
1.2.接口成员是自动公开的(public),且不能包含任何访问修饰符(public、protected、internal、private),否则 编译器会报错。
1.3.接口类似于抽象基类,不能直接实例化接口;接口中的方法都是抽象方法,实现接口的任何非抽象类型都必须实现接口的所有成员:
当显式实现该接口的成员时,实现的成员不能通过类实例访问,只能通过接口实例访问。
当隐式实现该接口的成员时,实现的成员可以通过类实例访问,也可以通过接口实例访问,但是实现的成员必须是公有的。
1.4.接口不能包含常量、字段、运算符、实例构造函数、析构函数或类型、不能包含静态成员,只能包含方法、属性、事件、索引等成员。
1.5.接口成员不能有static、abstract、override、virtual修饰符,使用new修饰符不会报错,但会给出警告说不需要关键字new。
1.6.在声明接口成员的时候,不准为接口成员编写具体的可执行代码,也就是说,只要在对接口进行声明时指明接口的成员名称和参数就可以了。
2.接口与抽象类
2.1下面让我们来对接口与抽象类做个对比。如有不同意见欢迎讨论。
interface |
abstract class |
|
实例化 |
不可以 |
不可以 |
派生类实现 |
必须实现所有契约 |
实现没实现的方法 |
继承 |
接口支持多继承 |
必须抽象类不能实现多继承 |
抽象 |
接口只能定义抽象规则 |
抽象类既可以定义规则,还可能提供已实现的成员。但不能使用new关键字,也不能被密封,原因是抽象类不能被实例化 |
概念 |
接口是一组行为规范 |
抽象类是一个不完全的类 |
回调 |
接口可以用于支持回调 |
抽象类不能实现回调,因为继承不支持 |
成员 |
接口只包含方法、属性、索引器、事件的签名,但不能定义字段和包含实现的方法 |
抽象类可以定义字段、属性、包含有实现的方法 |
数据类型 |
接口可以作用于值类型和引用类型。例如,Struct就可以继承接口,而不能继承类 |
抽象类只能作用于引用类型 |
构造方法 |
没有构造方法 |
有构造方法 |
静态方法 |
没有静态方法(默认public static final类型) |
包含静态方法 |
修饰符 |
默认public没有其他修饰符。 |
可以是public,protected |
2.2.抽象类和接口的使用:
2.2.1. 如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单的方法来控制组件版本;
2.2.2.如果创建的功能将在大范围的全异对象间使用,则使用接口。如果要设计小而简练的功能块,则使用接口;
2.2.3.如果要设计大的功能单元,则使用抽象类.如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类;
2.2.4.抽象类主要用于关系密切的对象;而接口适合为不相关的类提供通用功能。
3.接口声明
3.1.接口使用 interface 关键字声明,它与类的声明类似。接口声明默认是 public 的;
3.2.根据约定,接口类型名称要以大写字母I开头;
public interface ITransactions { // 接口成员 void showTransaction(); double getAmount(); }
注:3.3.对CLR而言,定义接口就像定义类型,也就是说,CLR会为接口类型对象定义一个内部数据结构,同时可用反射机制来查询接口类型的功能。
3.4.为什么不能指定接口中方法的修饰符?
接口中的方法用来定义对象之间通信的契约,指定接口中的方法为私有或保护没有意义。它们默认为公有方法。
4.接口的实现
C#中的接口提供了一种实现运行时的多态。
4.1.案例
using System.Collections.Generic; using System.Linq; using System.Text; namespace InterfaceApplication { public interface ITransactions { // 接口成员 void showTransaction(); double getAmount(); } public class Transaction : ITransactions { private string tCode; private string date; private double amount; public Transaction() { tCode = " "; date = " "; amount = 0.0; } public Transaction(string c, string d, double a) { tCode = c; date = d; amount = a; } public double getAmount() { return amount; } public void showTransaction() { Console.WriteLine("Transaction: {0}", tCode); Console.WriteLine("Date: {0}", date); Console.WriteLine("Amount: {0}", getAmount()); } } class Tester { static void Main(string[] args) { Transaction t1 = new Transaction("001", "8/10/2012", 78900.00); Transaction t2 = new Transaction("002", "9/10/2012", 451900.00); t1.showTransaction(); t2.showTransaction(); Console.ReadKey(); } } }
当上面的代码被编译和执行时,它会产生下列结果:
Transaction: 001
Date: 8/10/2012
Amount: 78900
Transaction: 002
Date: 9/10/2012
Amount: 451900
4.2接口的隐式实现与显示实现
4.2.1隐式实现
interface IAnimal { void Dog(); } class Animal:IAnimal { public void Dog() { //# } }
//通过类调用 Animal animal = new Animal(); animal.Dog(); //或者通过接口调用 IAnimal animal = new Animal(); animal.Dog();
以上:类与接口都能调用的为隐式实现。
4.2.2.显示实现
interface IAnimal { void Dog(); } class Animal:IAnimal { void IAnimal.Dog() { //# } }
IAnimal animal = new Animal(); animal.Dog();
Animal animal = new Animal(); (animal as IAnimal).Dog();
以上:用类的方法调用需要强制转换的实现为显示实现。
是不是感觉显示实现多余项目中也从来不曾遇到过???
4.3.接口隐式实现,显示实现的场景
4.3.1.当类实现一个接口时,通常使用隐式接口实现,这样可以方便的访问接口方法和类自身具有的方法和属性。
4.3.2.当类实现多个接口时,并且接口中包含相同的方法签名,此时使用显式接口实现。即使没有相同的方法签名,仍推荐使用显式接口,因为可以标识出哪个方法属于哪个接口。
4.3.3隐式接口实现,类和接口都可访问接口中方法。显式接口实现,只能通过接口访问。
5.接口的继承
5.1.接口继承和类继承不同:
5.1.1.类继承不仅是说明继承,而且也是实现继承;而接口继承只是说明继承。
5.1.2.C#中类继承只允许单继承,但是接口继承允许多继承,一个子接口可以有多个父接口(用","分割)。
5.2.接口的继承也形成接口之间的层次结构
interface IProgram { void Fun(); } interface IAProgram:IProgram { } class Program : IAProgram { void IProgram.Fun() { Console.WriteLine("I am IProgram Fun."); } staticvoid Main(string[] args) { Program pro =new Program(); ((IAProgram)pro).Fun(); Console.Read(); } }
6.接口的覆盖
通过接口,可以指定组件必须实现的方法,但不实际指定如何实现方法。抽象类可以创建行为的定义,同时提供用于继承类的一些公共实现。对于在组件中实现多态行为,接口和抽象类都是很有用的工具。
现在我们把一个抽象类被允许把接口方法映射到抽象方法中:
interface ICompute { void Add(); void Subtract(); } abstract class Compute : ICompute { void ICompute.Add() { ComputeAdd(); } void ICompute.Subtract() { ComputeSubtract(); } protected abstract void ComputeAdd(); protected abstract void ComputeSubtract(); }
这里,从Compute派生的非抽象类要覆盖ComputeAdd和 ComputeSubtract, 因此提供了ICompute的实际实现程序。
7.接口泛型
不多说:基础拾忆------泛型详解