简单整理了各种语言多态性的相关内容以及部分高级特性。
-------------------------
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{...}