1. 概述
本章包括 设计和实现接口、创建和使用基类 以及 使用.net类库提供的标准接口。
2. 主要内容
2.1 设计和实现接口
一个接口包含公共的方法、属性、事件、索引器。类和结构都可以实现接口。
interface IExample
{
string GetResult();
int Value { get; set; }
event EventHandler ResultRetrived;
int this[string index] { get; set; }
}
class ExampleImplementation : IExample
{
//只能都是public实现
public string GetResult()
{
return "result";
}
public int Value { get; set; }
public event EventHandler CalculationPerformed;
public event EventHandler ResultRetrived;
public int this[string index]
{
get { return 42; }
set {}
}
}
2.2 创建和使用基类
① 使用 virtual 和 override 关键字,可以在子类中重写父类的方法。
② 如果父类的方法没有标记为virtual,子类中可以用 new 关键字显示隐藏父类的方法。new方法只能被子类对象自己调用。
③ 抽象类和密封类
abstract class Base
{
public virtual void MethodWithImplementation() {//...}
public abstract void AbstractMethod();
}
class Derived : Base
{
public override void AbstractMethod() {//...}
}
与抽象类对应的是密封类,密封类不能被继承,所有成员必须提供实现。结构体(struct)就是一种隐式的密封类。
2.3 使用.net类库提供的标准接口
① IComparable: 只有一个方法( int ComparaTo(object obj) ). 用于提供排序支持。有泛型版本。
class Order : IComparable
{
public DateTime Created { get; set; }
public int ComparaTo(object obj)
{
if (obj == null) return 1;
Order o = obj as Order;
if (o == null)
throw new ArgumentException("Object is not a Order.");
return this.Created.ComparaTo(o.Created);
}
}
List<Order> orders = new List<Order>
{
new Order { Created = new DateTime(2012, 12, 1); }
new Order { Created = new DateTime(2012, 12, 2); }
new Order { Created = new DateTime(2012, 12, 3); }
};
orders.Sort();
② IEnumerable
IEnumerable 和 IEnumerator 接口用于实现遍历模式。
class Person
{
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public string FirstName { get; set; }
public string LastName { get; set; }
public override string ToString()
{
return FirstName + " " + LastName;
}
}
class People : IEnumerable<Person>
{
public People(Person[] people)
{
this.people = people;
}
Person[] people;
public IEnumerator<Person> GetEnumerator()
{
for (int index = 0; index < people.Length; index++)
{
yield return people[index];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
*yield关键字只能用于迭代块(iterators)中,编译器会将这段代码转化成状态机,并生成相应的集合遍历代码。
③ IDisposable: 用于跟外部资源或非托管代码更好的协同工作。只有一个Dispose方法,用于释放非托管的资源。
④ IUnknown
一般情况下,只需添加COM对象引用,编译器就会生成相应的交互类。
如果由于某些原因无法生成,就需要自己写交互类。这个时候就会用到IUnknown接口。
3. 总结
① 接口声明了一些必须被实现的公共成员。
② 基类可以将方法标记为virtual,这样子类就可以重写这些方法,增加或者修改具体实现。
③ 抽象类不能被实例化,只能当做基类使用。
④ 密封类不能被继承。
⑤ .net类库提供了一些默认接口供使用:IComparable, IEnumerable, IDisposable, IUnknown.