http://hi.baidu.com/knowtohow/blog/item/520a5e3e2808753e70cf6c46.html
關于C#,C++,Java在繼承,覆蓋和多態,抽象類等幾個方面的比較歸納。
C#,C++用visual studio2005編譯通過;java代碼用JDK1.4.2編譯通過。
一、繼承中的帶參數構造函數
=============================
C#示例:
//myClass.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace myClass
class myFirst{
int value_myFirst;
public myFirst(int f)
{
value_myFirst = f;
}
}
class mySecond : myFirst{
int value_mySecond;
//構造函數傳遞參數時,采用base關鍵字,s在base()中不需重新聲明類型int
public mySecond(int s)
: base(s)
{
value_mySecond = s;
}
}
class Program
{
static void Main(string[] args)
{
}
}
}
============================
C++示例:
#i nclude "stdafx.h"
class myFirst{
private:
int value_myFirst;
public:
myFirst(int f){
value_myFirst = f;
}
};
//繼承需要聲明繼承的方式,此處是public
class mySecond : public myFirst{
private:
int value_mySecond;
public:
//構造函數傳遞參數時,用基類類名,s基類類名()中不需聲明類型int
mySecond(int s) : myFirst(s){
value_mySecond = s;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
=============================
java示例:
package com;
class myFirst{
int value_myFirst;
public myFirst(int f){
value_myFirst = f;
}
}
//繼承采用extends關鍵字
class mySecond extends myFirst{
int value_mySecond;
public mySecond(int s){
//傳遞給基類構造函數時,采用super關鍵字,而且必須是第一條語句。
super(s);
value_mySecond = s;
}
}
public class myCon{
public static void main(String[] args){
}
}
注意:
1.注釋中給出了三者的不同點。
2.另外,C++語法中定義的類后面必須加上分號";"
3.訪問控制權限public等的格式,C#和java比較類似,C++相差很大。
二、方法覆蓋與多態
C#示例:
//myClass.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace myClass
{
class myFirst
{
int value_myFirst;
public myFirst(int f)
{
value_myFirst = f;
}
public void f1()
{
System.Console.WriteLine("myFirst.f1()!");
}
public virtual void f2() //virtual也可以提到最前面
{
System.Console.WriteLine("myFirst.f2()!");
}
}
class mySecond : myFirst
{
int value_mySecond;
public mySecond(int s)
: base(s)
{
value_mySecond = s;
}
//使用關鍵字new覆蓋基類中的同名方法
public new void f1() //new也可以提到最前面
{
System.Console.WriteLine("mySeconde.f1()!");
}
//error當基類函數myFirst.f1()沒有聲明為virtual,abstract時不能override!
//public override void f1()
//{
// System.Console.WriteLine("mySeconde.f1()!");
//}
//基類函數中雖然聲明是virtual,但是仍然可以用new覆蓋。
//public new void f2()
//{
// System.Console.WriteLine("mySeconde.f2()!");
//}
////基類函數中雖然聲明是virtual,用override覆蓋。
public override void f2() //override也可以提到最前面
{
System.Console.WriteLine("mySeconde.f2()!");
}
}
class Program
{
static void Main(string[] args)
{
myFirst mf = new myFirst(1);
mySecond ms = new mySecond(2);
mf.f1(); //myFirst.f1()!
mf.f2(); //myFirst.f2()!
ms.f1(); //mySeconde.f1()!
ms.f2(); //mySeconde.f2()!
mf = ms; //向上轉型之后
mf.f1(); //myFirst.f1()!
//mySeconde.f2()! 這是用override的運行結果;
//如果是new那么,結果是myFirst.f2()!
mf.f2();
}
}
}
=============================
C++示例
#i nclude "stdafx.h"
#i nclude <iostream>
using namespace std;
class myFirst{
private:
int value_myFirst;
public:
myFirst(int f){
value_myFirst = f;
}
void f1(){
cout<<"myFirst.f1()!"<<endl;
}
vitual void f2(){ //聲明為虛函數
cout<<"myFirst.f2()!"<<endl;
}
};
class mySecond : public myFirst{
private:
int value_mySecond;
public:
mySecond(int s) : myFirst(s){
value_mySecond = s;
}
//直接覆蓋基類函數,無需C#中的new
void f1(){
cout<<"mySecond.f1()!"<<endl;
}
//覆蓋基類需函數
void f2(){
cout<<"mySecond.f2()!"<<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
myFirst *mf = new myFirst(1);
mySecond *ms = new mySecond(1);
mf->f1(); //myFirst.f1()!
mf->f2(); //myFirst.f2()!
ms->f1(); //mySecond.f1()!
ms->f2(); //mySecond.f2()!
mf = ms; //向上轉型
mf->f1(); //myFirst.f1()!
mf->f2(); //mySecond.f2()!
myFirst mf1(1); //也可以
mf1.f1();
return 0;
}
=============================
java示例
//myCon.java
package com;
class myFirst{
int value_myFirst;
public myFirst(int f){
value_myFirst = f;
}
public void f1(){
System.out.println("myFirst.f1()!");
}
}
class mySecond extends myFirst{
int value_mySecond;
public mySecond(int s){
super(s);
value_mySecond = s;
}
public void f1(){
System.out.println("mySecond.f1()!");
}
}
class myThird extends myFirst{
int value_myThird;
public myThird(int t){
super(t);
value_myThird = t;
}
public void f1(){
System.out.println("myThird.f1()!");
}
}
public class myCon{
public static void main(String[] args){
myFirst mf = new myFirst(1);
mySecond ms = new mySecond(1);
myThird mt = new myThird(1);
mf.f1(); //myFirst.f1()!
ms.f1(); //mySecond.f1()!
mt.f1(); //myThird.f1()!
//向上轉型,由于java的動態綁定機制,
//使得java能夠調用派生類mySecond的f1()
mf = ms;
mf.f1(); //mySecond.f1()!
mf = mt;
mf.f1(); //myThird.f1()!
}
}
為了實現多態:
1.C#基類方法要聲明為virtual,派生類覆蓋時要用override;
2.C++基類方法要聲明為virtual,派生類方法直接覆蓋;
3.java直接覆蓋就可以實現多態。
三、抽象類
C#示例
上面已經說明,雖然基類方法聲明為virtual,以便派生類用override覆蓋,但是派生類仍然可以用
new關鍵字覆蓋(不具有多態性)。
可以強制讓派生類覆蓋基類的方法,將基類方法聲明為抽象的,采用abstract關鍵字。
抽象方法沒有方法體,由派生類來提供。
如果派生類不實現基類的抽象方法,則派生類也需要聲明為abstract類
//myClass.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace myClass{
//類中只要存在抽象方法,就必須聲明為抽象類
abstract class myFirst
{
int value_myFirst;
public myFirst(int f)
{
value_myFirst = f;
}
//抽象方法沒有方法體,以分號結尾。
public abstract void f1();
public void f2()
{
System.Console.WriteLine("myFirst.f2()!");
}
public virtual void f3()
{
System.Console.WriteLine("myFirst.f3()!");
}
}
class mySecond : myFirst
{
int value_mySecond;
public mySecond(int s)
: base(s)
{
value_mySecond = s;
}
//覆蓋基類抽象方法
public override void f1()
{
System.Console.WriteLine("mySeconde.f1()!");
}
//覆蓋基類一般方法
public new void f2()
{
System.Console.WriteLine("mySeconde.f2()!");
}
//覆蓋基類虛擬方法
public override void f3()
{
System.Console.WriteLine("mySecond.f3()!");
}
}
class Program
{
static void Main(string[] args)
{
//抽象類和接口不能聲明對象
//myFirst mf = new myFirst(1);
mySecond ms = new mySecond(2);
ms.f1(); //mySeconde.f1()!
ms.f2(); //mySeconde.f2()!
ms.f3(); //mySecond.f3()!
//這里向上轉型采用強類型轉換的方式
((myFirst)ms).f1(); //mySeconde.f1()!
((myFirst)ms).f2(); //myFirst.f2()!
((myFirst)ms).f3(); //mySecond.f3()!
}
}
}
=============================
C++示例
純虛函數是在基類中只宣布某個虛函數的原型,并且為了明確通知編譯系統,
該虛函數在基類中不再定義具體操作代碼,而在函數原型結束分號的左側寫
"=0"標識。這個不包含任何代碼的虛函數被成為純虛函數。
抽象類是含有純虛函數的類,這種類不能聲明任何對象,其作用就是為它的
派生類提供一種規定輸入數據和返回類型接口的模板。
從抽象類派生的派生類,必須對基類的純虛函數進行覆蓋;否則編譯系統將
報錯。
基類中虛函數被派生類覆蓋,則派生類對象調用的是派生類中重新定義的函
數代碼。
基類中虛函數沒有被派生類覆蓋,則派生類對象調用的是基類中定義的函數
代碼。
基類的純虛函數在其派生類中必須被覆蓋。
#i nclude "stdafx.h"
#i nclude <iostream>
using namespace std;
class myFirst{ //抽象類
private:
int value_myFirst;
public:
myFirst(int f){
value_myFirst = f;
}
void f1(){ //一般函數
cout<<"myFirst.f1()!"<<endl;
}
virtual void f2(){ //虛函數
cout<<"myFirst.f2()!"<<endl;
}
virtual void f3()=0; //純虛函數
};
class mySecond : public myFirst{
private:
int value_mySecond;
public:
mySecond(int s) : myFirst(s){
value_mySecond = s;
}
void f1(){ //覆蓋基類一般函數
cout<<"mySecond.f1()!"<<endl;
}
void f2(){ //覆蓋基類虛函數
cout<<"mySecond.f2()!"<<endl;
}
void f3(){ //覆蓋基類純虛函數
cout<<"mySecond.f3()!"<<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
//myFirst *mf = new myFirst(1); //抽象類不能創建對象
mySecond *ms = new mySecond(1);
ms->f1(); //mySecond.f1()!
ms->f2(); //mySecond.f2()!
ms->f3(); //mySecond.f3()!
//向上轉型采用強類型轉換
((myFirst *)ms)->f1(); //myFirst.f1()!
((myFirst *)ms)->f2(); //mySecond.f2()!
((myFirst *)ms)->f3(); //mySecond.f3()!
return 0;
}
=============================
java示例
java提供了抽象方法的機制abstract method,這種方法不完整,僅有聲明
沒有方法體
abstract void f();
包含抽象方法的類叫抽象類,如果類中包含一個或多個抽象方法,則該類必
須被聲明為抽象類,用abstract來修飾抽象類。
如果從一個抽象類繼承,并創建這個新類的對象,必須給抽象基類中所有抽
象方法提供方法定義,否則,派生類也是抽象類,也用abstract修飾。
package com;
abstract class myFirst{
int value_myFirst;
public myFirst(int f){
value_myFirst = f;
}
public void f1(){
System.out.println("myFirst.f1()!");
}
public abstract void f2(); //抽象方法
}
//繼承采用extends關鍵字
class mySecond extends myFirst{
int value_mySecond;
public mySecond(int s){
//傳遞給基類構造函數時,采用super關鍵字,而且必須是第一條語句。
super(s);
value_mySecond = s;
}
public void f1(){
System.out.println("mySecond.f1()!");
}
public void f2(){ //覆蓋基類抽象方法
System.out.println("mySecond.f2()!");
}
}
//如果不實現基類抽象方法,那么此派生類也必須用abstract修飾
abstract class myThird extends myFirst{
int value_myThird;
public myThird(int t){
super(t);
value_myThird = t;
}
public void f1(){
System.out.println("myThird.f1()!");
}
}
public class myCon{
public static void main(String[] args){
//myFirst mf = new myFirst(1); //抽象函數不能創建對象
mySecond ms = new mySecond(1);
//myThird mt = new myThird(1);
ms.f1(); //mySecond.f1()!
ms.f2(); //mySecond.f2()!
((myFirst)ms).f1(); //mySecond.f1()!
((myFirst)ms).f2(); //mySecond.f2()!
}
}
關于抽象方法和抽象類java和C#比較類似;
而C++叫純虛函數和抽象類。
四、接口
C++中的沒有接口的概念,它本身就可以多繼承。
java中接口interface比抽象類abstract更進了一步,可看做"純粹的抽象類"。
它允許創建者為一個類建立其形式,方法名,參數列表,返回類型,但沒有
任何方法體。接口中也可以包含成員函數,但是他們都是隱含的public和
final。
創建接口時用interface來代替class,前面可以有public,如果不加訪問權
限,那么它就是默認的包訪問權限。
接口中的方法默認為public。
類實現接口要用implements關鍵字。
接口便于實現多重繼承的效果,此處不作具體討論。
package com;
interface myFirst{
int value_myFirst=1;
public void f1();
}
class mySecond implements myFirst{
int value_mySecond;
public mySecond(int s){
value_mySecond = s;
}
public void f1(){
System.out.println("mySecond.f1()!");
}
}
public class myCon{
static void play(myFirst mf){
mf.f1();
}
public static void main(String[] args){
//myFirst mf = new myFirst(1);
mySecond ms = new mySecond(1);
ms.f1(); //mySecond.f1()!
play(ms); //向上轉型 mySecond.f1()!
((myFirst)ms).f1(); ////向上轉型 mySecond.f1()!
}
}