簡單整理了各種語言多態性的相關內容以及部分高級特性。
-------------------------
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{...}