面向对象的小故事
面向对象程序语言中最重要的概念无疑是class,所谓一切皆对象.(不过要是老天天呆电脑前写代码研究面向对象语言,那要真找对象找老婆就很成问题.可不是满世界的美女们都皆是你对象.) 类是一个抽象的概念,和我们现实生活中对事物分类起名差不多,比如美女,帅哥,二奶,官二代这样的名词就是一个类,代表具有相似属性的一类事物.每一个类实例化之后就是对象.就像美女这一类人中具体的某个美女才是一个对象,有可能成为你的对象.现实世界中的所有事情事件都能分成一类一类的,一个叫维特根斯坦的老兄呆监狱里的时候闲得蛋痛就琢磨着从语言学逻辑学的角度来把整个世界五马分尸,分为一些啥原子事件.然后这些原子事件通过些逻辑组合能形成一个复杂的现实世界.他的那本书叫<逻辑哲学论>.据传闻面向对象的思想就是从他的思想演化来的,不过传说就跟绯闻一样,真真假假谁知道啊.很多聪明人想问题时可能会得出些相同结论.有人说莱布尼兹发明二进制也是受易经的启发,那八卦图上有着二进制的原理
抽象类和接口的比较 从语法的层面讲抽象类(abstract class)和接口(interface)区别不大,可以都看成一种特殊的类.只有从设计的层面考虑才有比较重要的意义,那只有做构架师时才去考虑的事了啊,像我们这样命苦的码农还是老实的把语法搞懂,把代码敲好.抽象类是完全体现类的概念,对某一类具有相同属性事物的抽象,只不过它是为了做父类,让子类继承的.所以很多函数可以只声明在那里,不用去定义实现.而接口不是完全体现类的概念,不是对相同的属性的抽象,还是定义一系列行为准则.所谓接口顾名思义,我们平时装灯泡啊,电脑上的USB接口,耳塞接口都是有个统一标准的,你的U盘可以插任何电脑上,如果没有个这样的统一的接口标准,那没法插的啊。接口一般在不同的project之间调用时用的较多点,把project里面其他东西都封装了,你知道接口就行,特别是C++如果要调用C#的com组件的话,com组件要强制要用到接口的.所以用的时候你只管调用接口中的函数就行,怎么实现就不用管了.当然接口是不能实例化的,但你可以通过接口指针指向实现了接口的类,在C#中没有指针的话就可以这样InfaceClass instance = new ClassCompleteInterface(); 这其实和指针蛮像的.C++中每个class都可以有个头文件,头文件其实蛮像接口的.也是体现了接口那种思想.不过在C#中没有头文件的概念了.不过C#中有个partial class的概念,这样一个class的代码可以分布在多个文件中,如果你想模拟出c++的头文件,可以用它做到.
除了在不同的project中比较有用,接口在同一个project中也同样有用了.特别在C#中由于class不能像C++中一样实现多重继承,只能单继承,但接口可以多继承.所以如果项目要扩充些功能,要在某个类中新添加些功能.可以先添加一个接口,声明需要实现些啥功能,然后在原来某个class中继承这个接口,并实现它.站在设计者的角度,一个是要隐藏实现细节,就是所谓的封装.另一个就是便于扩展,添加新内容进去.
设计者们在设计时先是数据建模,把一个系统抽象出来然后分割成一小块一小块的.每一小块就对应一个class.当然他们设计时可不去管具体的代码实现细节,所以设计出来的class都基本上是些函数的声明.也就是一个个的抽象类,接口(这个不一定是代码中的概念,到最后转化成代码时可能会是抽象函数,接口,但也可能是一般的类)
上面是讲的概念性的东西,现在来讲下语法细节 C# 接口用法 public delegate void IamPointer(string input); //这个自然不是必需的,只是为了下面使用事件而在此定义的.
interface Weiwenhp
{
//string name; //这样会出错,接口中不使用字段
int Number{ get; set; } //属性
void DoIt(string cmd); //函数
int this[int index] { get; set; } //索引器
event IamPointer MyEvent; //事件
}
1.接口不能实例化,但假如有个类Arwen继承了Weiwenhp.你可以这样用Weiwenhp instance = new Arwen(); //这样不会出错的.Weiwenhp instance = new Weiwenhp();自然不行
2.定义接口时可用访问修饰符public 或internal.默认是internal(只能程序集内访问).但接口里面的函数等声明不能用任何访问修饰符.
3.接口中只能有函数,属性,索引器,事件的声明.后三者都是C#中新添加的特性.属性和索引器可以简单的理解为一种特殊的函数,封装class内部的字段,对外提示一个接口.属性一般封装基本类型,索引器一般封装数组类型.事件可以简单理解为对代理的封装,而代理有点类似函数指针.另外接口中是不能有静态函数和虚函数的声明
C# 抽象类 和一般类基本上一样,只不过定义时加个修饰符abstract.比如 abstract class MyClass{ }
和一般类只有几个细小的区别
1..首先自然是不能实例化,但可以像接口一样那样实例化.另外类中可以用到抽象函数(但也可以没有抽象函数),比如public abstract void Fun(); //一般的类是不能用抽象函数的
2.抽象类内部的函数等访问修饰符不能为private,因为它的设计目的就是让别人来继承它的.由于类内部不加修饰符时默认都是private,所以抽抽象类中所有函数,等都要加修饰符.当然字段除外,它可以是private.
3.除了上面的区别外,抽象类完全跟一般类一样.其实你拿个一般的类过来,直接加个abstract 就变成个抽象类.一点问题都不会有.
C++接口
据说标准C++中是没有interface的,平时用到的interface实际上是通过一些宏来实现的,背后的原理还是虚纯基类.这个还有待研究
C++抽象类 C++的抽象类跟C#的抽象类区别还是比较大的.C#中抽象类的标志就是class前面有个abstract就行了.然后class内部就跟一般类差不多.
而C++抽象类不会用到abstract关键字,它的标志是在class内部至少要有一个纯虚函数(这是C++独有的概念),C#中没有.
举个例子
class Arwen
{
int age;
public:
virtual void Fun(int num) = 0; //这就是纯虚函数了.
}
|