关于Interface 和 abstrac 的理解
来源:互联网 发布:手机lol视频软件 编辑:程序博客网 时间:2024/06/14 00:15
我相信有许多同行对于interface和abstract的理解都各不一样,我想说说我个人的理解:
先说最基本概念:
一:interface(接口)
定义:接口只包含方法,属性,事件或索引器的签名。实现接口的类或者结构必须实现接口定义中指定的接口成员;
注意事项:
举例说明:
下面的例子演示了属性的声明,类中包含实现,实现类的任何实例都具有声明的属性:
interfaceIPoint
{
// Property signatures:
int x
{
get;
set;
}
int y
{
get;
set;
}
}
classPoint :IPoint
{
// Fields:
privateint _x;
privateint _y;
// Constructor:
publicPoint(int x,int y)
{
_x = x;
_y = y;
}
// Property implementation:
publicint x
{
get
{
return _x;
}
set
{
_x = value;
}
}
publicint y
{
get
{
return _y;
}
set
{
_y = value;
}
}
}
索引器的例子:
publicinterfaceISomeInterface
{
//声明索引器
intthis[int index]
{
get;
set;
}
}
// 实现接口
classIndexerClass :ISomeInterface
{
privateint[] arr =newint[100];
publicintthis[int index]
{
get
{
return arr[index];
}
set
{
arr[index] = value;
}
}
}
classMainClass
{
staticvoidMain()
{
IndexerClass test = new IndexerClass();
System.Random rand = new System.Random();
for (int i =0; i <10; i++)
{
test[i] = rand.Next();
}
for (int i =0; i <10; i++)
{
System.Console.WriteLine("Element #{0} = {1}", i, test[i]);
}
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
方法和事件的例子就不再写了,大家肯定用的挺多的...
什么是显示接口实现呢?请看这个例子:
如果一个类实现的两个接口包含签名相同的成员,则在该类上实现此成员会导致这两个接口将此成员用作其实现。 如下示例中,所有对 Paint
的调用皆调用同一方法。
classTest
{
staticvoidMain()
{
SampleClass sc = new SampleClass();
IControl ctrl = (IControl)sc;
ISurface srfc = (ISurface)sc;
// 调用同一方法
sc.Paint();
ctrl.Paint();
srfc.Paint();
}
}
interfaceIControl
{
voidPaint();
}
interfaceISurface
{
voidPaint();
}
classSampleClass : IControl,ISurface
{
// ISurface.Paint and IControl.Paint同时调用
publicvoidPaint()
{
Console.WriteLine("Paint method in SampleClass");
}
}
// Output:
// Paint method in SampleClass
// Paint method in SampleClass
// Paint method in SampleClass
但是,如果两个接口成员不执行同一功能,则会导致其中一个接口或两个接口的实现不正确。 创建仅通过接口调用且特定于该接口的类成员,则有可能显式实现接口成员。 这可通过使用接口名称和句点命名类成员来完成。 例如:
publicclassSampleClass :IControl,ISurface
{
void IControl.Paint()
{
System.Console.WriteLine("IControl.Paint");
}
void ISurface.Paint()
{
System.Console.WriteLine("ISurface.Paint");
}
}
类成员 IControl.Paint
仅通过 IControl
接口可用,ISurface.Paint
仅通过 ISurface
可用。 这两个方法实现相互独立,两者均不可直接在类上使用。 例如:
SampleClass obj = new SampleClass();
//obj.Paint(); // 会编译错误
IControl c = (IControl)obj;
c.Paint(); // 用对应的接口调用
ISurface s = (ISurface)obj;
s.Paint(); // Calls ISurface.Paint on SampleClass.
// Output:
// IControl.Paint
// ISurface.Paint
显式实现还用于处理两个接口分别声明名称相同的不同成员(例如属性和方法)的情况:
interface ILeft{ int P { get;}}interface IRight{ int P();}
若要实现两个接口,类必须对属性 P 或方法 P 使用显式实现,或对二者同时使用,从而避免编译器错误。 例如:
class Middle : ILeft, IRight{ public int P() { return 0; } int ILeft.P { get { return 0; } }}
二:抽象类abstract
基本概念:通过在类定义前面放置关键字 abstract
,可以将类声明为抽象类
注意事项:
1:抽象类不能实例化。 抽象类的用途是提供一个可供多个派生类共享的通用基类定义。
2:抽象类也可以定义抽象方法。 方法是将关键字 abstract
添加到方法的返回类型的前面。抽象方法没有实现,所以方法定义后面是分号,而不是常规的方法块。
3: 抽象类的派生类必须实现所有抽象方法。 当抽象类从基类继承虚方法时,抽象类可以使用抽象方法重写该虚方法。
4:抽象类是类,所以只能被单继承
5:无法使用 sealed 修饰符来修改抽象类,因为两个修饰符具有相反的含义。 sealed
修饰符阻止类被继承,而 abstract
修饰符要求类被继承
6:在静态属性上使用 abstract
修饰符是错误的。
抽象方法具有以下功能:
抽象方法是隐式的虚拟方法。
只有抽象类中才允许抽象方法声明。
由于抽象方法声明不提供实际的实现,因此没有方法主体;方法声明仅以分号结尾,且签名后没有大括号 ,实现由替代方法 override 提供,它是非抽象类的成员在抽象方法声明中使用 static 或 virtual 修饰符是错误的。
通过包含使用 override 修饰符的属性声明,可在派生类中重写抽象继承属性。
举例说明:
public class D{ public virtual void DoWork(int i) { }}public abstract class E : D{ public abstract override void DoWork(int i);}public class F : E{ public override void DoWork(int i) { // 新复写内容 }}
如果将 virtual
方法声明为 abstract
,则该方法对于从抽象类继承的所有类而言仍然是虚方法。 继承抽象方法的类无法访问方法的原始实现,因此在上一示例中,类 F 上的 DoWork
无法调用类 D 上的 DoWork
。通过这种方式,抽象类可强制派生类向虚拟方法提供新的方法实现。
举例说明interface和abstract理解上的区别,实质是设计思想上有着不同,比如:有Icar接口和Acar抽象类,车本身就有能开的基本功能,通过接口或者抽象类都可以做到,
internal interface Icar
{
void Driver();
}
public abstract class ACar
{
public abstract void Driver();
}
public class QQ : Icar
{
public void Driver()
{
// ...
}
}
public class QQ1 : ACar
{
public override void Driver()
{
// ...
}
}
但是过了一段时间,我想给车加个自动泊车功能(autohold),你可能会想到这样做:
internal interface Icar
{
void Driver();
void AutoHold();
}
public abstract class ACar
{
public abstract void Driver();
public abstract void AutoHold();
}
接口或者抽象类都加上这个功能不就好了么,认真想想,不是所有的车都会具有这个功能的,只有高端一点的车才会有,所有车本身肯定能开,但不一定会有autohold功能。QQ 是一个Car,继承Acar(是一个car),具有autohold功能,额外添加的功能
我们把autohold功能抽象为一个额外功能接口,让高档的车实现这个接口就可以啦
interface IOtherFaction
{
void AutoHold();
}
public class BMW : ACar, IOtherFaction
{
public override void Driver()
{
// ...车都具有的功能
}
public void AutoHold()
{
//高档车额外的新功能
}
}
public class QQ1 : ACar
{
public override void Driver()
{
// ...车都具有的功能
}
}
我的理解就写到这里,有什么不妥之处,望交流。
- 关于Interface 和 abstrac 的理解
- java之interface与abstrac的理解
- 混乱的关于接口(Interface)的理解!
- 关于对C#的Interface理解
- 深入的理解abstract class和interface
- 深入的理解abstract class和interface
- 关于Interface 和 Abstract的用法
- 关于java中的abstract与interface的理解
- interface的理解
- Java Interface 的理解
- 理解abstract class和interface
- 理解abstract class和interface
- PHP interface和abstract理解
- java abstract class 和 interface的概念分析与理解
- 深入理解Java语言的abstract class和interface
- 由浅到深理解java abstract类和interface的区别
- JAVA中interface的理解
- c#中Interface的理解
- 记牌器程序
- python 文件操作
- 求圆内部面积占比
- Linux下一个简单的进度条
- Matrix derivatives(矩阵求导)
- 关于Interface 和 abstrac 的理解
- dfs, bfs之邻接矩阵无向图
- smarty介绍
- UDP和TCP(传输层)
- Java多线程(2) 线程的状态和属性
- jquery load 的使用:
- 注意细节
- BMap的使用填坑
- Smarty缓存