在C#中,我们用interface关键字来定义一个接口,为其指定一个名称和一组实例方法签名。Framework类库中几个接口的定义如下:
public interface IDisposable
...{
void Dispose();
}
public interface IEnumaerable
...{
IEnumerator GetEnumerator();
}
public interface IEnumerable<T> : IEnumaerable
...{
IEnumerator<T> GetEnumerator();
}
public interface ICollection<T> : IEnumaerable<T>, IEnumaerable
...{
void Add(T item);
void Clear();
Boolean Contains(T item);
void CopyTo(T[] array, Int32 arrayIndex);
Boolean Remove(T item);
Int32 Count ...{ get; }
Boolean IsReadOnly ...{ get; }
}
...{
void Dispose();
}
public interface IEnumaerable
...{
IEnumerator GetEnumerator();
}
public interface IEnumerable<T> : IEnumaerable
...{
IEnumerator<T> GetEnumerator();
}
public interface ICollection<T> : IEnumaerable<T>, IEnumaerable
...{
void Add(T item);
void Clear();
Boolean Contains(T item);
void CopyTo(T[] array, Int32 arrayIndex);
Boolean Remove(T item);
Int32 Count ...{ get; }
Boolean IsReadOnly ...{ get; }
}
一个接口定义可以“继承”自其他接口。不过,这里只是相当松散地使用“继承”一词,因为接口继承的工作方式和类继承完全不一样。我个人更愿意把接口继承想象为包含其他接口的约定。 例如,ICollection<T>接口定义便包含了IEnumerable<T>和IEnumerable 这两个接口的约定。这意味着:
- 继承自ICollection<T>接口的任何一个类必须实现ICollection<T>, IEnumerable<T> 和 IEnumerable这3个接口定义的所有方法
-
期望一个对象的类型实现ICollection<T>接口的任何代码都可以假设该对象的类型还实现了IEnumerable<T> 和IEnumerable接口的方法。
C#编译器要求将实现了接口的方法标记为public。CLR要求将借口方法标记为virtual。如果不在源代码中将接口方法显示标记为virtual,编译器会把方法标记为virtual和sealed,这会阻止派生类重写接口方法。如果将方法显式标记为virtual,编译器会把方法标记为virtual(保留为unsealed),这样一来,派生类就可以重写这个接口方法。
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
...{
class Program
...{
static void Main(string[] args)
...{
Base b = new Derived();
b.Dispose(); // Derived
((IDisposable)b).Dispose(); // Derived
}
}
public interface IDisposable
...{
void Dispose();
}
internal class Base : IDisposable
...{
virtual public void Dispose()
...{
Console.WriteLine("Base!");
}
}
internal class Derived : Base
...{
public override void Dispose()
...{
Console.WriteLine("Derived!");
}
}
}
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
...{
class Program
...{
static void Main(string[] args)
...{
Base b = new Derived();
b.Dispose(); // Derived
((IDisposable)b).Dispose(); // Derived
}
}
public interface IDisposable
...{
void Dispose();
}
internal class Base : IDisposable
...{
virtual public void Dispose()
...{
Console.WriteLine("Base!");
}
}
internal class Derived : Base
...{
public override void Dispose()
...{
Console.WriteLine("Derived!");
}
}
}
如果接口方法为sealed,派生类就不能重写这个方法。不过,派生类可以重新继承同一个接口,并可以为该接口的方法提供自己的实现,使用”new ”表明该方法重新实现了接口方法
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
...{
class Program
...{
static void Main(string[] args)
...{
/**//******************************/
Base b = new Base();
b.Dispose();
((IDisposable)b).Dispose();
/**//******************************/
Derived d = new Derived();
d.Dispose();
((IDisposable)d).Dispose();
/**//******************************/
b = new Derived();
b.Dispose();
((IDisposable)b).Dispose();
}
}
public interface IDisposable
...{
void Dispose();
}
internal class Base : IDisposable
...{
//Dispose方法被隐式标记为sealed, 不能被重写
public void Dispose()
...{
Console.WriteLine("Base!");
}
}
internal class Derived : Base, IDisposable
...{
//这个方法不能重写Base的Dispose方法
//'new'用于表明该方法重新实现了IDisposable的Dispose方法
new public void Dispose()
...{
Console.WriteLine("Derived!");
}
}
}
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
...{
class Program
...{
static void Main(string[] args)
...{
/**//******************************/
Base b = new Base();
b.Dispose();
((IDisposable)b).Dispose();
/**//******************************/
Derived d = new Derived();
d.Dispose();
((IDisposable)d).Dispose();
/**//******************************/
b = new Derived();
b.Dispose();
((IDisposable)b).Dispose();
}
}
public interface IDisposable
...{
void Dispose();
}
internal class Base : IDisposable
...{
//Dispose方法被隐式标记为sealed, 不能被重写
public void Dispose()
...{
Console.WriteLine("Base!");
}
}
internal class Derived : Base, IDisposable
...{
//这个方法不能重写Base的Dispose方法
//'new'用于表明该方法重新实现了IDisposable的Dispose方法
new public void Dispose()
...{
Console.WriteLine("Derived!");
}
}
}