深入继承——抽象类和接口
一、基本概念
抽象类:又叫抽象基类:在定义的时候使用 abstract 关键字标记的一般类。他可包含一般类所包含的所有特性,例如字段,属性,方法,另外还包含一个很特殊的方法,叫抽象方法(这些方法基本上是没有执行代码的函数标题,而派生于该类的类就必须提供执行的代码),而且不能被实例化,主要用在类的定义和部分实现这方面,所以需要在扩充类中完整的扩充并实现功能.
抽象方法:
例如 :
public abstract class
{
}
public class
{
}
接口:其实也是一种特殊的抽象类,用 interface 关键字标记,没有 class 关键字,可以包含方法、属性和事件,但是方法也只能是虚拟方法,任何派生于该接口的类就必须提供执行的代码.任何接口成员前面都不能加修饰符.接口可用的修饰符有 new,public,protected,internal,private,但是同一声明中修饰符只能有一个,new关键字只能出现在镶套接口中,表示复写继承来同名成员.
【注意】接口和类一样,可以被继承和发展,但不同的是,派生类可以继承基类的方法实现,而派生接口只是继承父接口的方法说明,却没有继承父接口的实现.
语法:
interface Ibook
{
}
接口相关知识:
1.声明在接口中的方法,不可以包含方法的内容区块,简单来说就是不能有大括号存在,例如下面
public interface Ibook
{
}
2. 实现接口的类就要这样写
{
}
3 .
(1)实现一个接口就必须完成接口里的所有方法。
(2)在实现的类中又有几点必须遵循:
(3)接口内的方法不能用 virtual
接口的映射:(interface mapping)
接口成员必须由类来加以实现,那么我们就把在类中定位接口成员的实现称之为接口的映射.
映射说白了就是一一对应的关系,什么一一对应呢?我们这里说的是接口的映射,那么肯定就是接口成员和类中实现相应的接口成员之间的对应关系了。
【注意事项】
1.接口映射时不但包括他自己的成员,同时也包括了他所有继承接口的成员
2.映射时,显式的实现成员比其他的更有优先权
3.private,protected,static被这些修饰过的成员不能参与接口的实现。
下面针对抽象类和接口做一个详细的对比
| |
| |
| |
| |
| |
| |
| |
- 如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单易行的方法来控制组件版本。通过更新基类,所有继承类都随更改自动更新。另一方面,接口一旦创建就不能更改。如果需要接口的新版本,必须创建一个全新的接口。
- 如果创建的功能将在大范围的全异对象间使用,则使用接口。抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。
- 如果要设计小而简练的功能块,则使用接口。如果要设计大的功能单元,则使用抽象类。
- 如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。抽象类允许部分实现类,而接口不包含任何成员的实现。
virtual:
override:
二、接口的继承相关用法:
(1)接口的定义属性方法事件以及继承类的申明:
public interface Ia
{ string A{ get;set; } //申明接口属性
}
public class Sun : Ia
{ public event C Cname; //实现他的事件
}
(2)继承父接口就要继承父接口的所有属性和方法:
interface I_A
interface I_B
interface I_C : I_A,I_B { }
public class I_D : IC
{ int a;
}
(3)外部对接口的访问(如果出现同名的参数或者方法,必须显式的指出他的父接口)
public interface I_A
{ int A{get;set}
}
public interface I_B
{
}
public interface I_C : I_A,I_B { }
public class I_D
{ public void Sum(I_C ic)
}
(4)外部类中对多重继承中的成员访问问题:
public interface I_A
{ string F(string A);
}
public interface I_B : I_A
{ new string F(string A);
}
public interface I_C : I_A
{ string T();
}
public interface I_D : I_B,I_C { };
public class I_F
{
((I_C)id).F("A接口的方法"); //强行访问C接口隐式的A接口F方法
((I_D)id).F("B接口的方法"); //直接访问D接口隐式的又被new的B接口F方法,而不是访问A接口中的
}
(5)显式实现接口成员不能从类实例访问,但可以在类内部访问。当类使用者不需要使用该接口成员时以及多个接口之间有同名成员时,这个就特别有用。
public interface I_A
{
public class I_B : I_A
{ private string name;
}
(6)类继承类中的接口方法提供为虚的,表示接受任何扩充类的复写,复写可用override关键字
public interface I_A
{ string GetUrl();
}
public class I_B : I_A
{ public virtual string GetUrl()
}
public class I_C : I_B,I_A
{ string
}
public class I_D : I_B
{ public override string GetUrl()
}
public class I_E : I_B
{ public new string GetUrl()
}
(7)不同接口同名成员的访问:
public interface I_A
{ string G();}
public interface I_B
{ string G();}
public class I_C : I_A,I_B
{
}
(8)多个接口同名成员属性和方法的访问(一个属性一个方法):
public interface I_A
{ string
public interface I_B : I_A
{ string A();}
public class I_C : I_B
{ string I_B.A()
}
(9) 显式实现的方法无法使用修饰符,同样可以使用虚方法Virtaul:在这个显式实现中调用另一个方法,然后这个被调用的方法再是虚方法
public interface I_A
(10)用抽象类来继承接口:
interface I_A
{
abstract class I_B1 : I_A
{
}
class I_B2 : I_B1
{
}
转自:http://blog.sina.com.cn/s/blog_4a93ccea0100cwqv.html