简单整理了各种语言多态性的相关内容以及部分高级特性。
------------------------- Delphi ------------------------- 【重载】 加overload
【虚基类】 delphi不支持多继承,所以没有虚基类这一说。
【虚函数】 父类的虚函数定义有两种方式: (1)procedure Draw; virtual; (2)procedure Draw; dynamic; 两者基本是一样的,前者速度优化,后者容量优化。
子类用override覆盖就行了: procedure Draw; override;
【纯虚函数】 父类定义如下 procedure fly(); virtual; abstract;
子类使用如下: procedure fly(); override;
【抽象类】 不清楚DELPHI有没有这个概念,印象中好像没有提及过。
【接口】 IFoo=interface ['{2137BF60-AA33-11D0-A9BF-9A4537A42701}'] function F1:Integer; end;
IBar=interface ['{2137BF61-AA33-11D0-A9BF-9A4537A42701}'] function F1:Interger; end;
【属性】 TMyObject=class private: SomeValue:Integer; procedure SetSomeValue(AValue:Integer); public: property Value:Integer read SomeValue write SetSomeValue; end;
procedure TMyObject.SetSomeValue(AValue:Integer); begin if SomeValue<>AValue then SomeValue:=AValue; end;
---------------------- C++ ---------------------- 【重载】 定义同名不同参的函数就行了,没有专门的关键字。
【虚基类】 多继承时用virtual关键字声明继承方式,避免基类中同类成员的多拷贝。 class A //定义基类A { A(int i){} //基类构造函数,有一个参数 … }; classB:virtual public A //A作为B的虚基类 { B(int n):A(n){} //B类构造函数,在初始化表中对虚基类初始化 … }; classC:virtual public A //A作为C的虚基类 { C(int n):A(n){} //C类构造函数,在初始化表中对虚基类初始化 … }; classD:publicB,publicC //类D的构造函数,在初始化表中对所有基类初始化 { D(int n):A(n),B(n),C(n){} … }
【虚函数】 在父类中用virtual声明函数,并实现函数的定义; 在子类中重载此函数,可以实现动态联编。 父类包含虚函数: class Point { public: Point(double i,double j) {x=i;y=j;} virtual double Area() const {return 0.0;} private: double x,y; };
子类中覆盖虚函数: class Rectangle:public Point { public: Rectangle(double i,double j,double k,double 1); virtual double Area() const { return w*h;} private: double w,h; };
调用这个函数实现动态联编: void fun(Point &s) { cout<<s.Area()<<endl; }
【纯虚函数】 用关键字virtual声明的函数,并且不实现函数的定义。 例如下面的类中定义了两个纯虚函数, class point { public: point(int i=0,int j=0) {x0=i;y0=j;} virtual void set()=0; virtual void draw()=0; protected: int x0,y0; };
【抽象类】 称带有纯虚函数的类为抽象类,只能作为基类。 抽象类是一种特殊的类,它是为了抽象和设计的目的而建立的,它处于继承层次结构的较上层,抽象类是不能定义对象的,在实际中为了强调一个类是抽象类,可将该类的构造函数说明为保护的访问控制权限。 class Shape { public: virtual float area() const{return 0.0;} virtual float volume() const{return 0.0;} virtual void shapeName() const =0; };
子类中若不重载父类中的函数,则子类也是抽象类。
【接口】 形式上就是把抽象类中的class换成interface,可以从其他接口继承,当然最主要的被别的类继承。 如COM中常用的IUnknown接口声明如下: interface IUnknown{ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv)=0; virtual ULONG STDMETHODCALLTYPE AddRef(void)=0; virtual ULOND STDMETHODCALLTYPE Release(vod)=0; }; C++中一般用抽象类来实现接口。
【属性】 标准C++中没这东东。
-------------------------- C# -------------------------- 【重载】 定义同名不同参的函数就行了,没有专门的关键字,和C++一样。
【虚基类】 单继承下不流行这玩意。
【虚函数】 在父类中用virtual声明函数,并实现函数的定义; public virtual bool SQLExe(bool b) { return true; } 在子类中用override覆盖此函数,可以实现动态联编。
【纯虚函数】 用关键字abstract声明的函数,并且不实现函数的定义,必须存在于抽象类中。 public abstract bool f(); 在子类中用override覆盖此函数。
【抽象类】 用abstract声明,父类中可包含虚函数声明,并不实现虚函数的定义,只能作为基类。 public abstract class cl { public cl(){} public abstract bool f(); }
【接口】 和类定义类似,用interface说明。 [attributes] [modifiers] interface identifier [:base-list] {interface-body}[;] 1、attributes(可选):附加的定义性信息。 2、modifiers(可选): 允许使用的修饰符有 new 和四个访问修饰符。 分别是:new、public、protected、internal、 private。 在一个接口定义中同一修饰符不允许出现多次,new 修饰符只能出现在嵌套接口中,表示覆盖了继承而来的同名成员。 public, protected, internal, and private 修饰符定义了对接口的访问权限。 3、指示器和事件。 4、identifier:接口名称。 5、base-list(可选):包含一个或多个显式基接口的列表,接口间由逗号分隔。 6、interface-body:对接口成员的定义。 7、接口可以是命名空间或类的成员,并且可以包含下列成员的签名: 方法、属性、索引器 。 8、一个接口可从一个或多个基接口继承。
允许实现多个接口
例如一个带事件的接口定义如下: public delegate void StringListEvent(IStringList sender); public interface IStringList { void Add(string s); int Count { get; } event StringListEvent Changed; string this[int index] { get; set; } }
【属性】 private int myheight;
public int MyHeight { get{ return this.myheight; } set { this.myheight = value; } }
-------------------------- JAVA --------------------------
【重载】 函数同名不同参就行了。
【虚基类】 单继承不流行这玩意!
【虚函数】 没有这个概念,java自动实现了动态联编,不信你试试!
【纯虚函数】 在JAVA里叫抽象函数,不叫纯虚函数,必须定义在抽象类里面,而且没有方法体。例如: abstract class Demo { abstract void method1(); abstract void method2(); … }
【抽象类】 abstract class Demo { abstract void method1(); abstract void method2(); … }
【接口】 知道有了抽象类,为什么还要接口吗?因为java是单继承,但是接口可以继承多个! 实现多数设计模式的关键技术: interface Demo { void method1(); void method2(); … }
【final类】
final类不能被继承 如果你认为一个类的定义已经很完美,不需要再生成它的子类,这时也应把它修饰为final类 final class classname{...}

|