View
241
Download
3
Embed Size (px)
DESCRIPTION
Object-Oriented Features comparative between Delphi, Java, C++ and C#
Citation preview
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 1/47
ComparingObjectOrientedFeaturesofDELPHI,C++,C#andJAVA
Contents
IntroductionObjectsandClassesEncapsulationInheritanceVirtualMethodsConstructorsandDestructors/FinalizersAbstractMethodsandClassesInterfacesMethodOverloadingOperatorOverloadingPropertiesExceptionsGenericsandTemplatesFurtherReading
Introduction
ThisdocumentattemptstocomparesomeoftheobjectorientedfeaturesavailableintheDELPHI,C++,C#andJAVAprogramminglanguages.Introductoryparagraphstoeachsectiontoexplaintheconceptbeingcomparedinthesectionareavailable,butaredesignedtobebrief,introductorydiscussionsonly,notcomprehensivedefinitions.Theprimarypurposeoftheseintroductoryparagraphsistohighlightthedifferencesbetweentheimplementationsoftheconceptinthelanguagesbeingcompared,nottoserveastutorialsexplainingtheconceptbeingcompared.
Unlessotherwisenoted,allsourcesampleslistedbelowweretestedandsuccessfullycompiledwiththefollowingtools:
DELPHI:BorlandDelphi7EnterpriseEditionC++:BorlandC++BuilderCompilerandCommandLineToolsfreedownload(bcc32v5.5)C#:Microsoft.NETFrameworkv1.1SDKJAVA:Java2SDK,StandardEdition1.4.2_04
ObjectsandClassesAclassisastructurethatcontainsdata(alsoknownasfieldsorattributes)andinstructionsformanipulatingthatdata(alsoreferredtoasmethodsorbehavior).Takenasawhole,aclassshouldmodelarealworldphysicalorconceptualobject.Anobjectisadynamicinstanceofaclass.Thatis,aclassprovidesablueprintforanobject.
Hereareexamplesforhowclassesaredefined:
DELPHI:
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 2/47
Unit1.pas:unitUnit1;
interface
typeTTest1=classpublicconstructorCreate;destructorDestroy;override;procedureMethod1;end;
implementation
{TTest1}
constructorTTest1.Create;begininheritedCreate;//end;
destructorTTest1.Destroy;begin//inheritedDestroy;end;
procedureTTest1.Method1;begin//end;
end.
C++:
test1.h:#ifndefTest1_H#defineTest1_H
classTest1{public:Test1(void);~Test1(void);voidmethod1(void);};#endif//Test1_H
test1.cpp:#ifndefTest1_H#include"test1.h"#endif
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 3/47
Test1::Test1(void){//}
Test1::~Test1(void){//}
voidTest1::method1(void){//}
C#:
test1.cs:publicclassTest1{publicTest1(){//}
publicvoidMethod1(){//}}
JAVA:
Test1.java:publicclassTest1{publicTest1(){//}
publicvoidmethod1(){//}}
Encapsulation
Encapsulationreferstothehidingofimplementationdetailssuchthattheonlywaytointeractwithan
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 4/47
objectisthroughawelldefinedinterface.Thisiscommonlydonebydefiningaccesslevels.
DELPHIhas4commonlyusedaccesslevelsformembers:private,protected,publicandpublished.Membersmarkedasprivateareaccessibletothemembersoftheclassoranymethoddefinedinthesameunit'simplementationsection.Membersmarkedasprotectedareaccessiblebyanymethodoftheclassoritsdescendantunitsthedescendantunitscanbedefinedindifferentunits.Publicmembersareaccessibletoall.Publishedmembersbehavesimilartopublicmembers,exceptthecompilergeneratesextraRunTimeTypeInformation(RTTI).Thedefaultaccesslevelispublic.
Theaccesstoaclassisdeterminedbywhichsectionoftheunittheclassisdefinedin:classesdefinedintheinterfacesectionareaccessibletoall,classesdefinedintheimplementationsectionareonlyaccessiblebymethodsdefinedinthesameunit.
Inadditiontothese,DELPHI.NETintroducedtheaccesslevelsof"strictprivate"and"strictprotected"whichessentiallybehavethesameastheclassicprivateandprotectedaccesslevelsexceptunitscopehasbeenremoved.
HereisaDELPHIcodeexample:
Unit1.pas:unitUnit1;
interface
typeTTest1=classprivateFPrivateField:Integer;protectedprocedureProtectedMethod;publicconstructorCreate;destructorDestroy;override;procedurePublicMethod;publishedprocedurePublishedMethod;end;
implementation
{TTest1}
constructorTTest1.Create;begininheritedCreate;//end;
destructorTTest1.Destroy;begin//inheritedDestroy;end;
procedureTTest1.ProtectedMethod;begin//end;
procedureTTest1.PublicMethod;
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 5/47
begin//end;
procedureTTest1.PublishedMethod;begin//end;
end.
C++defines3accesslevels:private,protectedandpublic.ThefollowingdefinitionsaretakenfromBjarneStroustrup'sC++Glossary:
privatebase:abaseclassdeclaredprivateinaderivedclass,sothatthebase'spublicmembersareaccessibleonlyfromthatderivedclass.privatemember:amemberaccessibleonlyfromitsownclass.protectedbase:abaseclassdeclaredprotectedinaderivedclass,sothatthebase'spublicandprotectedmembersareaccessibleonlyinthatderivedclassandclassesderivedfromthat.protectedmember:amemberaccessibleonlyfromclassesderivedfromitsclass.publicbase:abaseclassdeclaredpublicinaderivedclass,sothatthebase'spublicmembersareaccessibletotheusersofthatderivedclass.publicmember:amemberaccessibletoallusersofaclass.
Inadditiontotheseaccesslevels,C++alsohasthenotionofafriendclassandfriendfunctions:
friend:afunctionorclassexplicitlygrantedaccesstomembersofaclassbythatclass.friendfunction:afunctiondeclaredasfriendinaclasssothatithasthesameaccessastheclass'memberswithouthavingtobewithinthescopeoftheclass.
HereisaC++codeexample:
test1.h:#ifndefTest1_H#defineTest1_H
classTest1{private:intprivateField;protected:voidprotectedMethod(void);public:Test1(void);~Test1(void);voidpublicMethod(void);};#endif//Test1_H
test1.cpp:#ifndefTest1_H#include"test1.h"#endif
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 6/47
Test1::Test1(void){//}
Test1::~Test1(void){//}
voidTest1::protectedMethod(void){//}
voidTest1::publicMethod(void){//}
C#defines5accessmodifiersforclassmembers:private,protected,internal,protectedinternalandpublic.Oftheseaccessmodifiers,privateisthedefaultandmembersmarkedassuchareaccessibleonlytotheclassinwhichitisdefined.Amemberdeclaredasprotectedisaccessibletotheclasswhereinitisdeclaredandalsoinanyclasseswhichderivefromthatclass.Theinternalaccessmodifierspecifiesthatthememberisaccessibletoanyclassesdefinedinthesameassembly.Amemberdeclaredasprotectedinternalwillbeaccessiblebyanyderivedclassaswellasanyclassesdefinedinthesameassembly.Apublicmemberisaccessibletoall.
Thesameaccessmodifiersareavailableforuseonclassesaswell,thoughprivate,protectedandprotectedinternalareonlyapplicabletonestedclasses.Thedefaultaccesslevelforanonnestedclassifnoaccessmodifierisspecifiedisinternal.Thedefaultaccesslevelforanestedclassifnoaccessmodifierisspecifiedisprivate.
HereisaC#codeexample:
test1.cs:publicclassTest1{publicTest1(){//}
privateint_privateField;
protectedvoidProtectedMethod(){//}
internalvoidInternalMethod(){//}
protectedinternalvoidProtectedInternalMethod(){//}}
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 7/47
JAVAdefines4accesslevelsforclassmembers.Thepublicmodifierspecifiesthatthememberisvisibletoall.Theprotectedmodifierspecifiesthatthememberisvisibletosubclassesandtocodeinthesamepackage.Theprivatemodifierspecifiesthatthememberisvisibleonlytocodeinthesameclass.Ifnoneofthesemodifiersareused,thenthedefaultaccesslevelisassumedthatis,thememberisvisibletoallcodeinthepackage.
JAVAalsodefinesthefollowingaccessmodifiersforclasses:public,protectedandprivate.Ofthese,protectedandprivateareonlyapplicablefornestedclasses.Declaringaclassaspublicmakestheclassaccessibletoallcode.Ifnoaccessmodifierisspecified,thedefaultaccesslevelofpackagelevelaccessisassumed.
HereisaJAVAcodeexample:
Test1.java:publicclassTest1{publicTest1(){//}
privateintprivateField;
protectedvoidprotectedMethod(){//}
voidpackageMethod(){//}}
Inheritance
Inheritancereferstotheabilitytoreuseaclasstocreateanewclasswithaddedfunctionality.Thenewclass,alsoreferredtoasthedescendantclass,derivedclassorsubclass,issaidtoinheritthefunctionalityoftheancestorclass,baseclassorsuperclass.
C++supportsmultipleimplementationinheritancethatis,aderivedclasshasmorethanoneimmediatebaseclasstoinherititsimplementationfrom.Incontrasttothis,DELPHI,C#andJAVAsupportsingleimplementationinheritance,whereinthedescendantclassorsubclasscanonlyhaveonedirectancestorclassorsuperclasstoinherititsimplementationfrom.Theydo,however,supportusingmultipleinterfaceinheritance,aninterfacebeinganabstracttypethatdefinesmethodsignaturesbutdonothaveanimplementation.
Herearesomecodeexamples:
DELPHI:
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 8/47
Unit1.pas:unitUnit1;
interface
typeTBaseClass=class(TInterfacedObject)publicconstructorCreate;destructorDestroy;override;end;
IFooInterface=interfaceprocedureFoo;end;
IBarInterface=interfacefunctionBar:Integer;end;
TDerivedClass=class(TBaseClass,IFooInterface,IBarInterface)procedureFoo;functionBar:Integer;end;
implementation
{TBaseClass}
constructorTBaseClass.Create;begininheritedCreate;//end;
destructorTBaseClass.Destroy;begin//inheritedDestroy;end;
{TDerivedClass}
procedureTDerivedClass.Foo;begin//end;
functionTDerivedClass.Bar:Integer;beginResult:=0;end;
end.
C++:
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 9/47
test1.h:#ifndefTest1_H#defineTest1_H
classBase1{public:voidfoo(void);};
classBase2{public:intbar(void);};
classDerivedClass:publicBase1,publicBase2{public:DerivedClass(void);~DerivedClass(void);};#endif//Test1_H
test1.cpp:#ifndefTest1_H#include"test1.h"#endif
voidBase1::foo(void){//}
intBase2::bar(void){return0;}
DerivedClass::DerivedClass(void){//}
DerivedClass::~DerivedClass(void){//}
C#:
test1.cs:publicclassBaseClass{publicBaseClass(){
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 10/47
//}}
publicinterfaceIFooInterface{voidFoo();}
publicinterfaceIBarInterface{intBar();}
publicclassDerivedClass:BaseClass,IFooInterface,IBarInterface{publicvoidFoo(){//}
publicintBar(){return0;}}
JAVA:
Test1.java:classBaseClass{publicBaseClass(){//}}
interfaceFooInterface{voidfoo();}
interfaceBarInterface{intbar();}
classDerivedClassextendsBaseClassimplementsFooInterface,BarInterface{publicvoidfoo(){//}
publicintbar(){return0;}}
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 11/47
VirtualMethods
Virtualmethodsallowamethodcall,atruntime,tobedirectedtotheappropriatecode,appropriateforthetypeoftheobjectinstanceusedtomakethecall.Inessence,themethodisboundatruntimeinsteadofatcompiletime.Themethodisdeclaredasvirtualinthebaseclassandthenoverriddeninthederivedclass.Virtualmethodsareanimportantpartofpolymorphismsincethesamemethodcallcanproduceresultsappropriatetotheobjectinstanceusedtomakethecall.
BothDELPHIandC#requiretheoverridingcodetobeexplicitlydeclaredasanoverride.InC#,thenewkeywordmustbeusedinderivedclassestodefineamethodinthederivedclassthathidesthebaseclassmethod.InJAVA,allmethodsarevirtualbydefaultunlessthemethodismarkedasfinal.Also,finalmethodsinJAVAcannotbehidden.
Hereissomeexamplecodeshowingtheuseofvirtualmethods:
DELPHI:
Unit1.pas:unitUnit1;
interface
typeTBase=classpublicfunctionNonVirtualMethod:string;functionVirtualMethod:string;virtual;end;
TDerived=class(TBase)publicfunctionNonVirtualMethod:string;functionVirtualMethod:string;override;end;
implementation
{TBase}
functionTBase.NonVirtualMethod:string;beginResult:='TBase.NonVirtualMethod';end;
functionTBase.VirtualMethod:string;beginResult:='TBase.VirtualMethod';end;
{TDerived}
functionTDerived.NonVirtualMethod:string;beginResult:='TDerived.NonVirtualMethod';
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 12/47
end;
functionTDerived.VirtualMethod:string;beginResult:='TDerived.VirtualMethod';end;
end.
Project1.dpr:programProject1;
{$APPTYPECONSOLE}
usesSysUtils,Unit1in'Unit1.pas';
varFoo,Bar:TBase;
beginFoo:=TBase.Create;Bar:=TDerived.Create;tryWriteLn(Foo.NonVirtualMethod);WriteLn(Foo.VirtualMethod);WriteLn(Bar.NonVirtualMethod);WriteLn(Bar.VirtualMethod);finallyBar.Free;Foo.Free;end;end.
Thisshouldproducethefollowingoutput:
[c:\borland\delphi7\projects]Project1.exeTBase.NonVirtualMethodTBase.VirtualMethodTBase.NonVirtualMethodTDerived.VirtualMethod
[c:\borland\delphi7\projects]
C++:
test1.h:#ifndefTest1_H#defineTest1_H
#include
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 13/47
usingnamespacestd;
classBase{public:stringnonVirtualMethod(void);virtualstringvirtualMethod(void);};
classDerived:publicBase{public:stringnonVirtualMethod(void);virtualstringvirtualMethod(void);};#endif//Test1_H
test1.cpp:#ifndefTest1_H#include"test1.h"#endif#include
stringBase::nonVirtualMethod(void){stringtemp="Base::nonVirtualMethod";returntemp;}
stringBase::virtualMethod(void){stringtemp="Base::virtualMethod";returntemp;}
stringDerived::nonVirtualMethod(void){stringtemp="Derived::nonVirtualMethod";returntemp;}
stringDerived::virtualMethod(void){stringtemp="Derived::virtualMethod";returntemp;}
main.cpp:#ifndefTest1_H#include"test1.h"#endif#include#include
usingnamespacestd;
intmain(){auto_ptrfoo(newBase);auto_ptrbar(newDerived);cout
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 14/47
cout
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 15/47
publicvirtualstringVirtualMethod(){return"BaseClass.VirtualMethod";}}
publicclassDerivedClass:BaseClass{newpublicstringNonVirtualMethod(){return"DerivedClass.NonVirtualMethod";}
publicoverridestringVirtualMethod(){return"DerivedClass.VirtualMethod";}}
publicclassMainClass{publicstaticvoidMain(){BaseClassfoo=newBaseClass();BaseClassbar=newDerivedClass();Console.WriteLine(foo.NonVirtualMethod());Console.WriteLine(foo.VirtualMethod());Console.WriteLine(bar.NonVirtualMethod());Console.WriteLine(bar.VirtualMethod());}}
Thisshouldproducethefollowingoutput:
[d:\source\csharp\code]test1.exeBaseClass.NonVirtualMethodBaseClass.VirtualMethodBaseClass.NonVirtualMethodDerivedClass.VirtualMethod
[d:\source\csharp\code]
JAVA:
Test1.java:classBaseClass{publicfinalStringfinalMethod(){return"BaseClass.finalMethod";}
publicStringvirtualMethod(){return"BaseClass.virtualMethod";}}
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 16/47
classDerivedClassextendsBaseClass{publicStringvirtualMethod(){return"DerivedClass.virtualMethod";}}
publicclassTest1{publicstaticvoidmain(Stringargs[]){BaseClassfoo=newBaseClass();BaseClassbar=newDerivedClass();System.out.println(foo.finalMethod());System.out.println(foo.virtualMethod());System.out.println(bar.finalMethod());System.out.println(bar.virtualMethod());}}
Thisshouldproducethefollowingoutput:
[d:\source\java\code]java.exeTest1BaseClass.finalMethodBaseClass.virtualMethodBaseClass.finalMethodDerivedClass.virtualMethod
[d:\source\java\code]
ConstructorsAndDestructors/Finalizers
Constructorsarespecialmethodsusedtoconstructaninstanceofaclass.Theynormallycontaininitializationcodee.g.codeforsettingdefaultvaluesfordatamembers,allocatingresources,etc..Theobjectiveofconstructorsistoallocatememoryfortheobjectandtoinitializetheobjecttoavalidstatebeforeanyprocessingisdone.
Destructorsservetheoppositepurposeofconstructors.Whileconstructorstakecareofallocatingmemoryandotherresourcesthattheobjectrequiresduringitslifetime,thedestructor'spurposeistoensurethattheresourcesareproperlydeallocatedastheobjectisbeingdestroyed,andthememorybeingusedbytheobjectisfreed.InDELPHIandC++(i.e.unmanagedenvironments)theprogrammerisresponsibleforensuringthatanobject'sdestructoriscalledoncetheobjectisnolongerneeded.
Finalizersaresomewhatsimilartodestructorsbut(1)theyarenondeterministic,(2)theyaretheretoreleaseunmanagedresourcesonly.Thatis,inamanagedenvironment(e.g.JavaVirtualMachine,.NETCommonLanguageRuntime)finalizersarecalledbythemanagedenvironment,notbytheprogrammer.Hence,thereisnowaytodetermineatwhichpointintimeorinwhichorderafinalizerwillbecalled.Also,memory,whichisconsideredamanagedresource,isnotfreedbythefinalizer,butbythegarbagecollector.Sincemostclasseswrittenwillonlybemanipulatingobjectsinmemory,mostobjectsinamanagedenvironmentwillnotneedafinalizer.
InDELPHI,constructorsaredefinedusingtheconstructorkeywordanddestructorsaredefinedusingthedestructorkeyword.DELPHI,byconvention,namesitsconstructorCreateanditsdestructorDestroy,butthesenamesarenotrequirements.Also,DELPHIconstructorscanbemadevirtualandthe
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 17/47
defaultdestructorDestroyisvirtual.ToinvokeaconstructorinDELPHI,theconventionClassName.ConstructorNameisusede.g.ifaclassnamedTMyClasshasaconstructorCreatethenconstructinganinstanceisdoneusing":=TMyClass.Create"Toinvokethedestructor,calltheFreemethod,nottheDestroymethode.g.".Free".
InC++,C#andJAVA,aconstructorisdefinedbycreatingamethodwiththesamenameastheclass.C#andJAVArequiretheuseofthe'new'keywordtoinvoketheconstructor.Forexample,constructinganinstanceofMyClassisdoneusing"=newMyClass()".C++requirestheuseofthe'new'keywordiftheobjectistobeallocatedontheheap,otherwisesimplydeclaringavariableofthesametypeastheclasswithinvoketheconstructorandcreatetheobjectonthestack.InC++,C#andJAVAconstructorsmustbenamedthesameasthenameoftheclass.
ConstructorsinDELPHIdonotimplicitlycallthecontructorsforthebaseclass.Instead,theprogrammermustmakeanexplicitcall.InC++,C#andJAVA,aconstructorwillimplicitlycalltheconstructorsforitsbaseclass(es).
DestructorsinC#followthesameconventionasC++,thatis,thedestructormustbenamedthesameasthenameoftheclass,butprecededbyatilde(~).(ThissyntaxoftenmisleadsdeveloperswithaC++backgroundtoexpectaC#destructortobehavelikeaC++destructor(i.e.itcanbecalledinadeterministicfashion)wheninfactitbehaveslikeafinalizer.)ToimplementafinalizerinJava,thedeveloperneedsonlytooverridethefinalize()methodofjava.lang.Object.
C++objectsallocatedonthestackwillautomaticallyhavetheirdestructorcalledwhentheobjectgoesoutofscopeobjectsexplicitlyallocatedintheheapusingthe'new'keywordmusthaveitsdestructorinvokedusingthe'delete'keyword.WhilebothC#destructorsandJAVAfinalizersarenondeterministicC#destructorsareguaranteedtobecalledbythe.NETCLR(exceptincasesofanillbehavedapplicatione.g.onethatcrashes,forcesthefinalizerthreadintoaninfiniteloop,etc.)andwhentheyarecalled,willinturnimplicitlycalltheotherdestructorsintheinheritancechain,frommostderivedclasstoleastderivedclass.SuchisnotthecasewithJAVAfinalizersfinalizersmustexplicitlyinvokethefinalize()methodofitssuperclassandtheyarenotguaranteedtobeinvoked.
DELPHI,C++,C#andJAVAallprovidedefaultconstructorsifnonearedefinedinthecurrentclass.Allsupportoverloadingofconstructors.
DELPHI:
Unit1.pas:unitUnit1;
interface
typeTBase=classconstructorCreate;destructorDestroy;override;end;
TDerived=class(TBase)constructorCreate;destructorDestroy;override;end;
TMoreDerived=class(TDerived)constructorCreate;destructorDestroy;override;end;
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 18/47
implementation
{TBase}
constructorTBase.Create;beginWriteLn('InTBase.Create');inherited;end;
destructorTBase.Destroy;beginWriteLn('InTBase.Destroy');inherited;end;
{TDerived}
constructorTDerived.Create;beginWriteLn('InTDerived.Create');inherited;end;
destructorTDerived.Destroy;beginWriteLn('InTDerived.Destroy');inherited;end;
{TMoreDerived}
constructorTMoreDerived.Create;beginWriteLn('InTMoreDerived.Create');inherited;end;
destructorTMoreDerived.Destroy;beginWriteLn('InTMoreDerived.Destroy');inherited;end;
end.
Project1.dpr:programProject1;
{$APPTYPECONSOLE}
usesSysUtils,Unit1in'Unit1.pas';
varFoo:TBase;
beginFoo:=TBase.Create;Foo.Free;WriteLn;
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 19/47
Foo:=TDerived.Create;Foo.Free;WriteLn;
Foo:=TMoreDerived.Create;Foo.Free;end.
Thisshouldproducethefollowingoutput:
[c:\borland\delphi7\projects]Project1.exeInTBase.CreateInTBase.Destroy
InTDerived.CreateInTBase.CreateInTDerived.DestroyInTBase.Destroy
InTMoreDerived.CreateInTDerived.CreateInTBase.CreateInTMoreDerived.DestroyInTDerived.DestroyInTBase.Destroy
[c:\borland\delphi7\projects]
C++:
test1.h:#ifndefTest1_H#defineTest1_H
classBase1{public:Base1(void);~Base1(void);};
classBase2{public:Base2(void);~Base2(void);};
classDerived:publicBase1,publicBase2{public:Derived(void);~Derived(void);};#endif//Test1_H
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 20/47
test1.cpp:#ifndefTest1_H#include"test1.h"#endif
#include
usingstd::cout;usingstd::endl;
Base1::Base1(void){cout
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 21/47
}
makefile:#Macros
TOOLSROOT=C:\Borland\BCC55INCLUDEDIR=$(TOOLSROOT)\IncludeLIBDIR=$(TOOLSROOT)\Lib;$(TOOLSROOT)\Lib\PSDKCOMPILER=$(TOOLSROOT)\bin\bcc32.exeCOMPILERSWTS=tWCcI$(INCLUDEDIR)LINKER=$(TOOLSROOT)\bin\ilink32.exeLINKERSWTS=apTpexGnL$(LIBDIR)OBJFILES=test1.objmain.objLIBFILES=cw32.libimport32.libBASEOUTPUTFILE=mainEXEFILE=$(BASEOUTPUTFILE).exe
#implicitrules.cpp.obj: $(COMPILER)$(COMPILERSWTS)$0)thenResult:=Format('%d+%di',[Self.Real,Self.Imaginary])elseResult:=Format('%d%di',[Self.Real,Abs(Self.Imaginary)]);end;
end.
Project1.dpr:programProject1;
{$APPTYPECONSOLE}
usesSysUtils,Unit1in'Unit1.pas';
varA,B:TComplexNumber;
beginA:=TComplexNumber.Create(2,5);B:=TComplexNumber.Create(4,3);WriteLn(Format('A=(%s),B=(%s)',[A,B]));WriteLn(Format('A+B=(%s)',[A+B]));WriteLn(Format('AB=(%s)',[AB]));end.
Thisshouldproducethefollowingoutput:
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 33/47
[d:\source\delphi.net\code]Project1.exeA=(2+5i),B=(43i)A+B=(6+2i)AB=(2+8i)
[d:\source\delphi.net\code]
C++:
test1.h:#ifndefTest1_H#defineTest1_H
#include
usingnamespacestd;
classComplexNumber{public:intreal;intimaginary;ComplexNumberoperator+(constComplexNumber&)const;ComplexNumberoperator(constComplexNumber&)const;virtualstringtoString(void)const;ComplexNumber(int,int);};#endif//Test1_H
test1.cpp:#ifndefTest1_H#include"test1.h"#endif#include#include#include
usingnamespacestd;
stringitos(inti){stringstreams;simaginary=imaginary;}
ComplexNumberComplexNumber::operator+(constComplexNumber¶m)const{ComplexNumbertemp;temp.real=this>real+param.real;temp.imaginary=this>imaginary+param.imaginary;returntemp;
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 34/47
}
ComplexNumberComplexNumber::operator(constComplexNumber¶m)const{ComplexNumbertemp;temp.real=this>realparam.real;temp.imaginary=this>imaginaryparam.imaginary;returntemp;}
stringComplexNumber::toString()const{if(this>imaginary>0)returnitos(real)+"+"+itos(imaginary)+"i";elsereturnitos(real)+""+itos(abs(imaginary))+"i";}
main.cpp:#ifndefTest1_H#include"test1.h"#endif#include
usingnamespacestd;
intmain(){ComplexNumbera(2,5);ComplexNumberb(4,3);cout
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 35/47
del$(EXEFILE) del$(BASEOUTPUTFILE).tds
Thisshouldproducethefollowingoutput:
[c:\borland\bcc55\projects]main.exea=(2+5i),b=(43i)a+b=(6+2i)ab=(2+8i)
[c:\borland\bcc55\projects]
C#:
test1.cs:usingSystem;
classComplexNumber{publicintReal;publicintImaginary;
publicComplexNumber(intreal,intimaginary){this.Real=real;this.Imaginary=imaginary;}
publicstaticComplexNumberoperator+(ComplexNumbera,ComplexNumberb){returnnewComplexNumber(a.Real+b.Real,a.Imaginary+b.Imaginary);}
publicstaticComplexNumberoperator(ComplexNumbera,ComplexNumberb){returnnewComplexNumber(a.Realb.Real,a.Imaginaryb.Imaginary);}
publicoverridestringToString(){if(this.Imaginary>0)return(string.Format("{0}+{1}i",this.Real,this.Imaginary));elsereturn(string.Format("{0}{1}i",this.Real,Math.Abs(this.Imaginary)));}}
publicclassMainClass{publicstaticvoidMain(){ComplexNumbera=newComplexNumber(2,5);ComplexNumberb=newComplexNumber(4,3);Console.WriteLine(string.Format("a=({0}),b=({1})",a,b));Console.WriteLine(string.Format("a+b=({0})",a+b));Console.WriteLine(string.Format("ab=({0})",ab));}}
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 36/47
Thisshouldproducethefollowingoutput:
[d:\source\csharp\code]test1.exea=(2+5i),b=(43i)a+b=(6+2i)ab=(2+8i)
[d:\source\csharp\code]
Properties
Propertiescanbedescribedasobjectorienteddatamembers.Externaltotheclass,propertieslookjustlikedatamembers.Internally,however,propertiescanbeimplementedasmethods.Propertiespromoteencapsulationbyallowingtheclasstohidetheinternalrepresentationofitsdata.Also,byimplementingonlyagetter(alsoknownasanaccessor)methodorasetter(alsoknownasamutator)method,apropertycanbemadereadonlyorwriteonlyrespectively,thusallowingtheclasstoprovideaccesscontrol.
DELPHIandC#havesupportforpropertiesbuiltintothelanguage.C++andJAVAdonothavesupportforpropertiesbuiltinbutcanlooselyimplementthisbehaviorusingaget/setconvention.
DELPHI:
Unit1.pas:unitUnit1;
interface
typeTRectangle=classprivateFHeight:Cardinal;FWidth:Cardinal;protectedfunctionGetArea:Cardinal;publicfunctionToString:string;virtual;constructorCreate(constWidth,Height:Cardinal);propertyArea:CardinalreadGetArea;propertyHeight:CardinalreadFHeightwriteFHeight;propertyWidth:CardinalreadFWidthwriteFWidth;end;
implementation
usesSysUtils;
{TRectangle}
constructorTRectangle.Create(constWidth,Height:Cardinal);
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 37/47
begininheritedCreate;FHeight:=Height;FWidth:=Width;end;
functionTRectangle.GetArea:Cardinal;beginResult:=FWidth*FHeight;end;
functionTRectangle.ToString:string;beginResult:=Format('Height:%d,Width:%d,Area:%d',[Height,Width,Area]);end;
end.
Project1.dpr:programProject1;
{$APPTYPECONSOLE}
usesSysUtils,Unit1in'Unit1.pas';
beginwithTRectangle.Create(2,3)dotryWriteLn(ToString);Height:=4;Width:=3;WriteLn(ToString);finallyFree;end;end.
Thisshouldproducethefollowingoutput:
[c:\borland\delphi7\projects]Project1.exeHeight:3,Width:2,Area:6Height:4,Width:3,Area:12
[c:\borland\delphi7\projects]
C#:
test1.cs:usingSystem;
classRectangle{
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 38/47
privateuint_height;privateuint_width;
publicRectangle(uintwidth,uintheight){_width=width;_height=height;}
publicuintArea{get{return_width*_height;}}
publicuintHeight{get{return_height;}set{_height=value;}}
publicuintWidth{get{return_width;}set{_width=value;}}
publicoverridestringToString(){returnstring.Format("Height:{0},Width:{1},Area:{2}",Height,Width,Area);}}
publicclassMainClass{publicstaticvoidMain(){RectangleMyRectangle=newRectangle(2,3);Console.WriteLine(MyRectangle);MyRectangle.Height=4;MyRectangle.Width=3;Console.WriteLine(MyRectangle);}}
Thisshouldproducethefollowingoutput:
[d:\source\csharp\code]test1.exeHeight:3,Width:2,Area:6Height:4,Width:3,Area:12
[d:\source\csharp\code]
Exceptions
Exceptionsprovideauniformmechanismforhandlingerrors.Exceptionsarecreatedandraisedorthrownwhenthecodeentersaconditionthatitcannotorshouldnothandlebyitself.Oncetheexceptionisraisedorthrown,theexceptionhandlingmechanismbreaksoutofthenormalflowofcodeexecutionandsearchesforanappropriateexceptionhandler.Ifanappropriateexceptionhandlerisfound,thentheerrorconditionishandledinanappropriatemannerandnormalcodeexecutionresumes.Otherwise,theapplicationisassumedtobeinanunstable/unpredictablestateandexits
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 39/47
withanerror.
DELPHIprovidestheraisekeywordtocreateanexceptionandatry...exceptandtry...finallyconstruct(butnounifiedtry...except...finallyconstructthoughatry...finallyblockcanbenestedwithinatry...exceptblocktoemulatethisbehavior)forexceptionhandling.Codewritteninatryblockisexecutedandifanexceptionoccurs,theexceptionhandlingmechanismsearchesforanappropriateexceptblocktohandletheexception.Theonkeywordisusedtospecifywhichexceptionsanexceptblockcanhandle.Asingleexceptblockcancontainmultipleonkeywords.Iftheonkeywordisnotused,thentheexceptblockwillhandleallexceptions.Codewritteninafinallyblockisguaranteedtoexecuteregardlessofwhetherornotanexceptionisraised.
Unit1.pas:unitUnit1;
interface
usesSysUtils;
typeEMyException=class(Exception);
TMyClass=classpublicprocedureMyMethod;constructorCreate;destructorDestroy;override;end;
implementation
{TMyClass}
procedureTMyClass.MyMethod;beginWriteLn('EnteringTMyClass.MyMethod');raiseEMyException.Create('ExceptionraisedinTMyClass.MyMethod!');WriteLn('LeavingTMyClass.MyMethod');//thisshouldnevergetexecutedend;
constructorTMyClass.Create;begininheritedCreate;WriteLn('InTMyClass.Create');end;
destructorTMyClass.Destroy;beginWriteLn('InTMyClass.Destroy');inheritedDestroy;end;
end.
Project1.dpr:programProject1;
{$APPTYPECONSOLE}
uses
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 40/47
SysUtils,Unit1in'Unit1.pas';
varMyClass:TMyClass;
beginMyClass:=TMyClass.Create;trytryMyClass.MyMethod;exceptonEMyExceptiondoWriteLn(ErrOutput,'CaughtanEMyException!');end;finallyMyClass.Free;end;end.
Thisshouldproducethefollowingoutput:
[c:\borland\delphi7\projects]Project1.exeInTMyClass.CreateEnteringTMyClass.MyMethodCaughtanEMyException!InTMyClass.Destroy
[c:\borland\delphi7\projects]
C++providesthethrowkeywordforcreatinganexceptionandprovidesatry...catchconstructforexceptionhandling.Codewritteninthetryblockisexecutedandifanexceptionisthrown,theexceptionhandlingmechanismlooksforanappropriatecatchblocktodealwiththeexception.Asingletryblockcanhavemultiplecatchblocksassociatedwithit.Catchblockshavearequiredexceptiondeclarationtospecifywhattypeofexceptionitcanhandle.Anexceptiondeclarationof(...)meansthatthecatchblockwillcatchallexceptions.
Afunctioncanoptionallyspecifywhatexceptionsitcanthrowviaanexceptionspecificationinthefunctiondeclaration.Thethrowkeywordisalsousedforthispurpose.Ifnoexceptionspecificationispresentthenthefunctioncanthrowanyexception.
test1.h:#ifndefTest1_H#defineTest1_H
#include
usingstd::string;
classMyException{public:MyException(string);
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 41/47
stringgetMessage()const;private:stringmessage;};
classMyClass{public:MyClass();~MyClass();voidmyMethod();};#endif//Test1_H
test1.cpp:#ifndefTest1_H#include"test1.h"#endif
#include
usingstd::cout;usingstd::endl;
MyException::MyException(stringerrorMessage){message=errorMessage;}
stringMyException::getMessage()const{returnmessage;}
MyClass::MyClass(){cout
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 42/47
MyClassmyClass;try{myClass.myMethod();}catch(MyException){cerr
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 43/47
exceptionsthrown.Codeinafinallyblockwillbeexecutedregardlessofwhetherornotanexceptionisthrown.
usingSystem;
classMyException:Exception{};
classMyClass{publicMyClass(){Console.WriteLine("InMyClass.MyClass()");}
~MyClass(){Console.WriteLine("InMyClass.~MyClass()");}
publicvoidMyMethod(){Console.WriteLine("EnteringMyClass.MyMethod()");thrownewMyException();Console.WriteLine("LeavingMyClass.MyMethod()");//thisshouldnevergetexecuted}}
publicclassMainClass{publicstaticvoidMain(){MyClassmyClass=newMyClass();try{myClass.MyMethod();}catch(MyException){Console.Error.WriteLine("CaughtaMyException!");}finally{Console.WriteLine("Infinallyblock");//willalwaysgetexecuted}}}
Thisshouldproducesimilaroutput:
[d:\source\csharp\code]test1.exeInMyClass.MyClass()EnteringMyClass.MyMethod()CaughtaMyException!InfinallyblockInMyClass.~MyClass()
[d:\source\csharp\code]
JAVAusesthethrowkeywordtothrowanexceptionandprovidestry...catch,try...finallyandtry...catch...finallyconstructsforexceptionhandling.Codeinsideatryblockisexecutedandifanexceptionisthrown,theexceptionhandlingmechanismsearchesforanappropriatecatchblock.A
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 44/47
singletryblockcanhavemultiplecatchblocksassociatedwithit.Catchblocksarerequiredtospecifytheexceptiontypethattheyhandle.Codeinafinallyblockwillbeexecutedregardlessofwhetherornotanexceptionisthrown.
JAVAalsorequiresthatmethodseithercatchorspecifyallcheckedexceptionsthatcanbethrownwithinthescopeofthemethod.Thisisdoneusingthethrowsclauseofthemethoddeclaration.
Test1.java:classMyExceptionextendsException{};
classMyClass{publicMyClass(){System.out.println("InMyClass.MyClass()");}protectedvoidfinalize()throwsThrowable{System.out.println("InMyClass.finalize()");}publicvoidmyMethod()throwsMyException{System.out.println("EnteringmyClass.myMethod()");thrownewMyException();}}
publicclassTest1{publicstaticvoidmain(Stringargs[]){MyClassmyClass=newMyClass();try{myClass.myMethod();}catch(MyExceptione){System.err.println("CaughtaMyException!");}finally{System.out.println("Infinallyblock");//willalwaysgetexecuted}}}
Thisshouldproducesimilaroutput:
[d:\source\java\code]java.exeTest1InMyClass.MyClass()EnteringmyClass.myMethod()CaughtaMyException!Infinallyblock
[d:\source\java\code]
GenericsandTemplates
TemplatesandGenericsareconstructsforparametricpolymorphism.Thatis,theymakecreatingparameterizedtypesforcreatingtypesafecollections.However,theydonotrefertothesamething
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 45/47
i.e.templatesarenotgenericsandgenericsarenottemplates.Formoreinformationonwhatthedifferencesare,refertothefollowingexternallinks:
C++Potential:TemplatesandGenericsGenericsinC#,Java,andC++
Currently,onlytheC++languagesupportstemplates.Genericsupportisplannedforversion2.0oftheC#languageandforversion1.5oftheJAVAlanguage.
C++:
stacktemplate.h:#ifndefStackTemplate_H#defineStackTemplate_H
#defineEMPTYSTACK1
templateclassStack{public:Stack(int);~Stack();boolpush(constT&);boolpop(T&);private:boolisEmpty()const;boolisFull()const;intstackSize;intstackTop;T*stackPtr;};
templateStack::Stack(intmaxStackSize){stackSize=maxStackSize;stackTop=EMPTYSTACK;stackPtr=newT[stackSize];}
templateStack::~Stack(){delete[]stackPtr;}
templateboolStack::push(constT¶m){if(!isFull()){stackPtr[++stackTop]=param;returntrue;}returnfalse;}
templateboolStack::pop(T¶m){if(!isEmpty()){
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 46/47
param=stackPtr[stackTop];returntrue;}returnfalse;}
templateboolStack::isEmpty()const{returnstackTop==EMPTYSTACK;}
templateboolStack::isFull()const{returnstackTop==stackSize1;}
#endif
main.cpp:#ifndefStackTemplate_H#include"stacktemplate.h"#endif#include
usingstd::cout;usingstd::endl;
intmain(){StackintStack(5);inti=2;while(intStack.push(i)){cout
09/06/2015 ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html 47/47
pushing8ontointStackpushing10ontointStackpopped10fromintStackpopped8fromintStackpopped6fromintStackpopped4fromintStackpopped2fromintStack
pushing2.1ontofloatStackpushing4.2ontofloatStackpushing6.3ontofloatStackpushing8.4ontofloatStackpushing10.5ontofloatStackpopping10.5fromfloatStackpopping8.4fromfloatStackpopping6.3fromfloatStackpopping4.2fromfloatStackpopping2.1fromfloatStack
[c:\borland\bcc55\projects]
FurtherReading
Formoreinformation,refertothefollowinglinks:
DELPHI:DelphiBasics:http://www.delphibasics.co.uk/ObjectPascalStyleGuide:http://community.borland.com/soapbox/techvoyage/article/1,1795,10280,00.html
C++:BjarneStroustrup'shomepageTheC++ProgrammingLanguage:http://www.research.att.com/~bs/C++.html
C#:MSDNC#LanguageSpecification:http://msdn.microsoft.com/library/default.asp?url=/library/enus/csspec/html/CSharpSpecStart.aspStandardECMA334C#LanguageSpecification2ndedition(December2002):http://www.ecmainternational.org/publications/standards/Ecma334.htm
JAVA:CodeConventionsfortheJavaProgrammingLanguage:http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.htmlTheJavaLanguageSpecification:http://java.sun.com/docs/books/jls/
(Lastupdatedon20050910.)