Sunteți pe pagina 1din 47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

ComparingObjectOrientedFeaturesof
DELPHI,C++,C#andJAVA
Contents
Introduction
ObjectsandClasses
Encapsulation
Inheritance
VirtualMethods
ConstructorsandDestructors/Finalizers
AbstractMethodsandClasses
Interfaces
MethodOverloading
OperatorOverloading
Properties
Exceptions
GenericsandTemplates
FurtherReading

Introduction
ThisdocumentattemptstocomparesomeoftheobjectorientedfeaturesavailableintheDELPHI,C++,
C#andJAVAprogramminglanguages.Introductoryparagraphstoeachsectiontoexplaintheconcept
beingcomparedinthesectionareavailable,butaredesignedtobebrief,introductorydiscussions
only,notcomprehensivedefinitions.Theprimarypurposeoftheseintroductoryparagraphsisto
highlightthedifferencesbetweentheimplementationsoftheconceptinthelanguagesbeing
compared,nottoserveastutorialsexplainingtheconceptbeingcompared.
Unlessotherwisenoted,allsourcesampleslistedbelowweretestedandsuccessfullycompiledwith
thefollowingtools:
DELPHI:BorlandDelphi7EnterpriseEdition
C++:BorlandC++BuilderCompilerandCommandLineToolsfreedownload(bcc32v5.5)
C#:Microsoft.NETFrameworkv1.1SDK
JAVA:Java2SDK,StandardEdition1.4.2_04

ObjectsandClasses
Aclassisastructurethatcontainsdata(alsoknownasfieldsorattributes)andinstructionsfor
manipulatingthatdata(alsoreferredtoasmethodsorbehavior).Takenasawhole,aclassshould
modelarealworldphysicalorconceptualobject.Anobjectisadynamicinstanceofaclass.Thatis,a
classprovidesablueprintforanobject.
Hereareexamplesforhowclassesaredefined:
DELPHI:
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

1/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

Unit1.pas:
unitUnit1;
interface
type
TTest1=class
public
constructorCreate;
destructorDestroy;override;
procedureMethod1;
end;
implementation
{TTest1}
constructorTTest1.Create;
begin
inheritedCreate;
//
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
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

2/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

Test1::Test1(void)
{
//
}
Test1::~Test1(void)
{
//
}
voidTest1::method1(void)
{
//
}

C#:

test1.cs:
publicclassTest1
{
publicTest1(){
//
}
publicvoidMethod1(){
//
}
}

JAVA:

Test1.java:
publicclassTest1{
publicTest1(){
//
}
publicvoidmethod1(){
//
}
}

Encapsulation
Encapsulationreferstothehidingofimplementationdetailssuchthattheonlywaytointeractwithan
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

3/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

objectisthroughawelldefinedinterface.Thisiscommonlydonebydefiningaccesslevels.
DELPHIhas4commonlyusedaccesslevelsformembers:private,protected,publicandpublished.
Membersmarkedasprivateareaccessibletothemembersoftheclassoranymethoddefinedinthe
sameunit'simplementationsection.Membersmarkedasprotectedareaccessiblebyanymethodof
theclassoritsdescendantunitsthedescendantunitscanbedefinedindifferentunits.Public
membersareaccessibletoall.Publishedmembersbehavesimilartopublicmembers,exceptthe
compilergeneratesextraRunTimeTypeInformation(RTTI).Thedefaultaccesslevelispublic.
Theaccesstoaclassisdeterminedbywhichsectionoftheunittheclassisdefinedin:classesdefined
intheinterfacesectionareaccessibletoall,classesdefinedintheimplementationsectionareonly
accessiblebymethodsdefinedinthesameunit.
Inadditiontothese,DELPHI.NETintroducedtheaccesslevelsof"strictprivate"and"strictprotected"
whichessentiallybehavethesameastheclassicprivateandprotectedaccesslevelsexceptunitscope
hasbeenremoved.
HereisaDELPHIcodeexample:

Unit1.pas:
unitUnit1;
interface
type
TTest1=class
private
FPrivateField:Integer;
protected
procedureProtectedMethod;
public
constructorCreate;
destructorDestroy;override;
procedurePublicMethod;
published
procedurePublishedMethod;
end;
implementation
{TTest1}
constructorTTest1.Create;
begin
inheritedCreate;
//
end;
destructorTTest1.Destroy;
begin
//
inheritedDestroy;
end;
procedureTTest1.ProtectedMethod;
begin
//
end;
procedureTTest1.PublicMethod;
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

4/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

begin
//
end;
procedureTTest1.PublishedMethod;
begin
//
end;
end.

C++defines3accesslevels:private,protectedandpublic.Thefollowingdefinitionsaretakenfrom
BjarneStroustrup'sC++Glossary:
privatebase:abaseclassdeclaredprivateinaderivedclass,sothatthebase'spublicmembers
areaccessibleonlyfromthatderivedclass.
privatemember:amemberaccessibleonlyfromitsownclass.
protectedbase:abaseclassdeclaredprotectedinaderivedclass,sothatthebase'spublicand
protectedmembersareaccessibleonlyinthatderivedclassandclassesderivedfromthat.
protectedmember:amemberaccessibleonlyfromclassesderivedfromitsclass.
publicbase:abaseclassdeclaredpublicinaderivedclass,sothatthebase'spublicmembers
areaccessibletotheusersofthatderivedclass.
publicmember:amemberaccessibletoallusersofaclass.
Inadditiontotheseaccesslevels,C++alsohasthenotionofafriendclassandfriendfunctions:
friend:afunctionorclassexplicitlygrantedaccesstomembersofaclassbythatclass.
friendfunction:afunctiondeclaredasfriendinaclasssothatithasthesameaccessasthe
class'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
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

5/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

Test1::Test1(void)
{
//
}
Test1::~Test1(void)
{
//
}
voidTest1::protectedMethod(void)
{
//
}
voidTest1::publicMethod(void)
{
//
}

C#defines5accessmodifiersforclassmembers:private,protected,internal,protectedinternaland
public.Oftheseaccessmodifiers,privateisthedefaultandmembersmarkedassuchareaccessible
onlytotheclassinwhichitisdefined.Amemberdeclaredasprotectedisaccessibletotheclass
whereinitisdeclaredandalsoinanyclasseswhichderivefromthatclass.Theinternalaccess
modifierspecifiesthatthememberisaccessibletoanyclassesdefinedinthesameassembly.A
memberdeclaredasprotectedinternalwillbeaccessiblebyanyderivedclassaswellasanyclasses
definedinthesameassembly.Apublicmemberisaccessibletoall.
Thesameaccessmodifiersareavailableforuseonclassesaswell,thoughprivate,protectedand
protectedinternalareonlyapplicabletonestedclasses.Thedefaultaccesslevelforanonnestedclass
ifnoaccessmodifierisspecifiedisinternal.Thedefaultaccesslevelforanestedclassifnoaccess
modifierisspecifiedisprivate.
HereisaC#codeexample:

test1.cs:
publicclassTest1
{
publicTest1(){
//
}
privateint_privateField;
protectedvoidProtectedMethod(){
//
}
internalvoidInternalMethod(){
//
}
protectedinternalvoidProtectedInternalMethod(){
//
}
}
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

6/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

JAVAdefines4accesslevelsforclassmembers.Thepublicmodifierspecifiesthatthememberis
visibletoall.Theprotectedmodifierspecifiesthatthememberisvisibletosubclassesandtocodein
thesamepackage.Theprivatemodifierspecifiesthatthememberisvisibleonlytocodeinthesame
class.Ifnoneofthesemodifiersareused,thenthedefaultaccesslevelisassumedthatis,themember
isvisibletoallcodeinthepackage.
JAVAalsodefinesthefollowingaccessmodifiersforclasses:public,protectedandprivate.Ofthese,
protectedandprivateareonlyapplicablefornestedclasses.Declaringaclassaspublicmakesthe
classaccessibletoallcode.Ifnoaccessmodifierisspecified,thedefaultaccesslevelofpackagelevel
accessisassumed.
HereisaJAVAcodeexample:

Test1.java:
publicclassTest1{
publicTest1(){
//
}
privateintprivateField;
protectedvoidprotectedMethod(){
//
}
voidpackageMethod(){
//
}
}

Inheritance
Inheritancereferstotheabilitytoreuseaclasstocreateanewclasswithaddedfunctionality.The
newclass,alsoreferredtoasthedescendantclass,derivedclassorsubclass,issaidtoinheritthe
functionalityoftheancestorclass,baseclassorsuperclass.
C++supportsmultipleimplementationinheritancethatis,aderivedclasshasmorethanone
immediatebaseclasstoinherititsimplementationfrom.Incontrasttothis,DELPHI,C#andJAVA
supportsingleimplementationinheritance,whereinthedescendantclassorsubclasscanonlyhave
onedirectancestorclassorsuperclasstoinherititsimplementationfrom.Theydo,however,support
usingmultipleinterfaceinheritance,aninterfacebeinganabstracttypethatdefinesmethodsignatures
butdonothaveanimplementation.
Herearesomecodeexamples:
DELPHI:
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

7/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

Unit1.pas:
unitUnit1;
interface
type
TBaseClass=class(TInterfacedObject)
public
constructorCreate;
destructorDestroy;override;
end;
IFooInterface=interface
procedureFoo;
end;
IBarInterface=interface
functionBar:Integer;
end;
TDerivedClass=class(TBaseClass,IFooInterface,IBarInterface)
procedureFoo;
functionBar:Integer;
end;
implementation
{TBaseClass}
constructorTBaseClass.Create;
begin
inheritedCreate;
//
end;
destructorTBaseClass.Destroy;
begin
//
inheritedDestroy;
end;
{TDerivedClass}
procedureTDerivedClass.Foo;
begin
//
end;
functionTDerivedClass.Bar:Integer;
begin
Result:=0;
end;
end.

C++:

http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

8/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

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(){
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

9/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

//
}
}
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;
}
}

http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

10/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

VirtualMethods
Virtualmethodsallowamethodcall,atruntime,tobedirectedtotheappropriatecode,appropriate
forthetypeoftheobjectinstanceusedtomakethecall.Inessence,themethodisboundatruntime
insteadofatcompiletime.Themethodisdeclaredasvirtualinthebaseclassandthenoverriddenin
thederivedclass.Virtualmethodsareanimportantpartofpolymorphismsincethesamemethodcall
canproduceresultsappropriatetotheobjectinstanceusedtomakethecall.
BothDELPHIandC#requiretheoverridingcodetobeexplicitlydeclaredasanoverride.InC#,the
newkeywordmustbeusedinderivedclassestodefineamethodinthederivedclassthathidesthe
baseclassmethod.InJAVA,allmethodsarevirtualbydefaultunlessthemethodismarkedasfinal.
Also,finalmethodsinJAVAcannotbehidden.
Hereissomeexamplecodeshowingtheuseofvirtualmethods:
DELPHI:

Unit1.pas:
unitUnit1;
interface
type
TBase=class
public
functionNonVirtualMethod:string;
functionVirtualMethod:string;virtual;
end;
TDerived=class(TBase)
public
functionNonVirtualMethod:string;
functionVirtualMethod:string;override;
end;
implementation
{TBase}
functionTBase.NonVirtualMethod:string;
begin
Result:='TBase.NonVirtualMethod';
end;
functionTBase.VirtualMethod:string;
begin
Result:='TBase.VirtualMethod';
end;
{TDerived}
functionTDerived.NonVirtualMethod:string;
begin
Result:='TDerived.NonVirtualMethod';
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

11/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

end;
functionTDerived.VirtualMethod:string;
begin
Result:='TDerived.VirtualMethod';
end;
end.
Project1.dpr:
programProject1;
{$APPTYPECONSOLE}
uses
SysUtils,
Unit1in'Unit1.pas';
var
Foo,Bar:TBase;
begin
Foo:=TBase.Create;
Bar:=TDerived.Create;
try
WriteLn(Foo.NonVirtualMethod);
WriteLn(Foo.VirtualMethod);
WriteLn(Bar.NonVirtualMethod);
WriteLn(Bar.VirtualMethod);
finally
Bar.Free;
Foo.Free;
end;
end.

Thisshouldproducethefollowingoutput:
[c:\borland\delphi7\projects]Project1.exe
TBase.NonVirtualMethod
TBase.VirtualMethod
TBase.NonVirtualMethod
TDerived.VirtualMethod
[c:\borland\delphi7\projects]

C++:

test1.h:
#ifndefTest1_H
#defineTest1_H
#include<string>
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

12/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

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<string>
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<string>
#include<iostream>
usingnamespacestd;
intmain()
{
auto_ptr<Base>foo(newBase);
auto_ptr<Base>bar(newDerived);
cout<<foo>nonVirtualMethod()<<endl;
cout<<foo>virtualMethod()<<endl;
cout<<bar>nonVirtualMethod()<<endl;
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

13/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

cout<<bar>virtualMethod()<<endl;
}
makefile:
#Macros
TOOLSROOT=C:\Borland\BCC55
INCLUDEDIR=$(TOOLSROOT)\Include
LIBDIR=$(TOOLSROOT)\Lib;$(TOOLSROOT)\Lib\PSDK
COMPILER=$(TOOLSROOT)\bin\bcc32.exe
COMPILERSWTS=tWCcI$(INCLUDEDIR)
LINKER=$(TOOLSROOT)\bin\ilink32.exe
LINKERSWTS=apTpexGnL$(LIBDIR)
OBJFILES=test1.objmain.obj
LIBFILES=cw32.libimport32.lib
BASEOUTPUTFILE=main
EXEFILE=$(BASEOUTPUTFILE).exe
#implicitrules
.cpp.obj:

$(COMPILER)$(COMPILERSWTS)$<
#Explicitrules
default:$(EXEFILE)
$(EXEFILE):$(OBJFILES)

$(LINKER)$(LINKERSWTS)c0x32.obj$(OBJFILES),$(EXEFILE),,$(LIBFILES),,
clean:

del$(OBJFILES)
del$(EXEFILE)
del$(BASEOUTPUTFILE).tds

Thisshouldproducethefollowingoutput:
[c:\borland\bcc55\projects]main.exe
Base::nonVirtualMethod
Base::virtualMethod
Base::nonVirtualMethod
Derived::virtualMethod
[c:\borland\bcc55\projects]

C#:

test1.cs:
usingSystem;
publicclassBaseClass
{
publicstringNonVirtualMethod(){
return"BaseClass.NonVirtualMethod";
}
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

14/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

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.exe
BaseClass.NonVirtualMethod
BaseClass.VirtualMethod
BaseClass.NonVirtualMethod
DerivedClass.VirtualMethod
[d:\source\csharp\code]

JAVA:

Test1.java:
classBaseClass{
publicfinalStringfinalMethod(){
return"BaseClass.finalMethod";
}
publicStringvirtualMethod(){
return"BaseClass.virtualMethod";
}
}

http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

15/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

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.exeTest1
BaseClass.finalMethod
BaseClass.virtualMethod
BaseClass.finalMethod
DerivedClass.virtualMethod
[d:\source\java\code]

ConstructorsAndDestructors/Finalizers
Constructorsarespecialmethodsusedtoconstructaninstanceofaclass.Theynormallycontain
initializationcodee.g.codeforsettingdefaultvaluesfordatamembers,allocatingresources,etc..The
objectiveofconstructorsistoallocatememoryfortheobjectandtoinitializetheobjecttoavalidstate
beforeanyprocessingisdone.
Destructorsservetheoppositepurposeofconstructors.Whileconstructorstakecareofallocating
memoryandotherresourcesthattheobjectrequiresduringitslifetime,thedestructor'spurposeisto
ensurethattheresourcesareproperlydeallocatedastheobjectisbeingdestroyed,andthememory
beingusedbytheobjectisfreed.InDELPHIandC++(i.e.unmanagedenvironments)theprogrammer
isresponsibleforensuringthatanobject'sdestructoriscalledoncetheobjectisnolongerneeded.
Finalizersaresomewhatsimilartodestructorsbut(1)theyarenondeterministic,(2)theyarethereto
releaseunmanagedresourcesonly.Thatis,inamanagedenvironment(e.g.JavaVirtualMachine,
.NETCommonLanguageRuntime)finalizersarecalledbythemanagedenvironment,notbythe
programmer.Hence,thereisnowaytodetermineatwhichpointintimeorinwhichorderafinalizer
willbecalled.Also,memory,whichisconsideredamanagedresource,isnotfreedbythefinalizer,
butbythegarbagecollector.Sincemostclasseswrittenwillonlybemanipulatingobjectsinmemory,
mostobjectsinamanagedenvironmentwillnotneedafinalizer.
InDELPHI,constructorsaredefinedusingtheconstructorkeywordanddestructorsaredefinedusing
thedestructorkeyword.DELPHI,byconvention,namesitsconstructorCreateanditsdestructor
Destroy,butthesenamesarenotrequirements.Also,DELPHIconstructorscanbemadevirtualandthe
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

16/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

defaultdestructorDestroyisvirtual.ToinvokeaconstructorinDELPHI,theconvention
ClassName.ConstructorNameisusede.g.ifaclassnamedTMyClasshasaconstructorCreatethen
constructinganinstanceisdoneusing"<variable>:=TMyClass.Create"Toinvokethedestructor,
calltheFreemethod,nottheDestroymethode.g."<variable>.Free".
InC++,C#andJAVA,aconstructorisdefinedbycreatingamethodwiththesamenameastheclass.
C#andJAVArequiretheuseofthe'new'keywordtoinvoketheconstructor.Forexample,
constructinganinstanceofMyClassisdoneusing"<variable>=newMyClass()".C++requiresthe
useofthe'new'keywordiftheobjectistobeallocatedontheheap,otherwisesimplydeclaringa
variableofthesametypeastheclasswithinvoketheconstructorandcreatetheobjectonthestack.In
C++,C#andJAVAconstructorsmustbenamedthesameasthenameoftheclass.
ConstructorsinDELPHIdonotimplicitlycallthecontructorsforthebaseclass.Instead,the
programmermustmakeanexplicitcall.InC++,C#andJAVA,aconstructorwillimplicitlycallthe
constructorsforitsbaseclass(es).
DestructorsinC#followthesameconventionasC++,thatis,thedestructormustbenamedthesame
asthenameoftheclass,butprecededbyatilde(~).(Thissyntaxoftenmisleadsdeveloperswitha
C++backgroundtoexpectaC#destructortobehavelikeaC++destructor(i.e.itcanbecalledina
deterministicfashion)wheninfactitbehaveslikeafinalizer.)ToimplementafinalizerinJava,the
developerneedsonlytooverridethefinalize()methodofjava.lang.Object.
C++objectsallocatedonthestackwillautomaticallyhavetheirdestructorcalledwhentheobject
goesoutofscopeobjectsexplicitlyallocatedintheheapusingthe'new'keywordmusthaveits
destructorinvokedusingthe'delete'keyword.WhilebothC#destructorsandJAVAfinalizersarenon
deterministicC#destructorsareguaranteedtobecalledbythe.NETCLR(exceptincasesofanill
behavedapplicatione.g.onethatcrashes,forcesthefinalizerthreadintoaninfiniteloop,etc.)and
whentheyarecalled,willinturnimplicitlycalltheotherdestructorsintheinheritancechain,from
mostderivedclasstoleastderivedclass.SuchisnotthecasewithJAVAfinalizersfinalizersmust
explicitlyinvokethefinalize()methodofitssuperclassandtheyarenotguaranteedtobeinvoked.
DELPHI,C++,C#andJAVAallprovidedefaultconstructorsifnonearedefinedinthecurrentclass.All
supportoverloadingofconstructors.
DELPHI:

Unit1.pas:
unitUnit1;
interface
type
TBase=class
constructorCreate;
destructorDestroy;override;
end;
TDerived=class(TBase)
constructorCreate;
destructorDestroy;override;
end;
TMoreDerived=class(TDerived)
constructorCreate;
destructorDestroy;override;
end;
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

17/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

implementation
{TBase}
constructorTBase.Create;
begin
WriteLn('InTBase.Create');
inherited;
end;
destructorTBase.Destroy;
begin
WriteLn('InTBase.Destroy');
inherited;
end;
{TDerived}
constructorTDerived.Create;
begin
WriteLn('InTDerived.Create');
inherited;
end;
destructorTDerived.Destroy;
begin
WriteLn('InTDerived.Destroy');
inherited;
end;
{TMoreDerived}
constructorTMoreDerived.Create;
begin
WriteLn('InTMoreDerived.Create');
inherited;
end;
destructorTMoreDerived.Destroy;
begin
WriteLn('InTMoreDerived.Destroy');
inherited;
end;
end.
Project1.dpr:
programProject1;
{$APPTYPECONSOLE}
uses
SysUtils,
Unit1in'Unit1.pas';
var
Foo:TBase;
begin
Foo:=TBase.Create;
Foo.Free;
WriteLn;
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

18/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

Foo:=TDerived.Create;
Foo.Free;
WriteLn;
Foo:=TMoreDerived.Create;
Foo.Free;
end.

Thisshouldproducethefollowingoutput:
[c:\borland\delphi7\projects]Project1.exe
InTBase.Create
InTBase.Destroy
InTDerived.Create
InTBase.Create
InTDerived.Destroy
InTBase.Destroy
InTMoreDerived.Create
InTDerived.Create
InTBase.Create
InTMoreDerived.Destroy
InTDerived.Destroy
InTBase.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
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

19/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

test1.cpp:
#ifndefTest1_H
#include"test1.h"
#endif
#include<iostream>
usingstd::cout;
usingstd::endl;
Base1::Base1(void)
{
cout<<"InBase1::Base1(void)"<<endl;
}
Base1::~Base1(void)
{
cout<<"InBase1::~Base1(void)"<<endl;
}
Base2::Base2(void)
{
cout<<"InBase2::Base2(void)"<<endl;
}
Base2::~Base2(void)
{
cout<<"InBase2::~Base2(void)"<<endl;
}
Derived::Derived(void)
{
cout<<"InDerived::Derived(void)"<<endl;
}
Derived::~Derived(void)
{
cout<<"InDerived::~Derived(void)"<<endl;
}
main.cpp:
#ifndefTest1_H
#include"test1.h"
#endif
#include<iostream>
usingstd::cout;
usingstd::endl;
intmain()
{
Base1a;
cout<<endl;
Base2b;
cout<<endl;
Derivedc;
cout<<endl;
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

20/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

}
makefile:
#Macros
TOOLSROOT=C:\Borland\BCC55
INCLUDEDIR=$(TOOLSROOT)\Include
LIBDIR=$(TOOLSROOT)\Lib;$(TOOLSROOT)\Lib\PSDK
COMPILER=$(TOOLSROOT)\bin\bcc32.exe
COMPILERSWTS=tWCcI$(INCLUDEDIR)
LINKER=$(TOOLSROOT)\bin\ilink32.exe
LINKERSWTS=apTpexGnL$(LIBDIR)
OBJFILES=test1.objmain.obj
LIBFILES=cw32.libimport32.lib
BASEOUTPUTFILE=main
EXEFILE=$(BASEOUTPUTFILE).exe
#implicitrules
.cpp.obj:

$(COMPILER)$(COMPILERSWTS)$<
#Explicitrules
default:$(EXEFILE)
$(EXEFILE):$(OBJFILES)

$(LINKER)$(LINKERSWTS)c0x32.obj$(OBJFILES),$(EXEFILE),,$(LIBFILES),,
clean:

del$(OBJFILES)
del$(EXEFILE)
del$(BASEOUTPUTFILE).tds

Thisshouldproducethefollowingoutput:
[c:\borland\bcc55\projects]main.exe
InBase1::Base1(void)
InBase2::Base2(void)
InBase1::Base1(void)
InBase2::Base2(void)
InDerived::Derived(void)
InDerived::~Derived(void)
InBase2::~Base2(void)
InBase1::~Base1(void)
InBase2::~Base2(void)
InBase1::~Base1(void)
[c:\borland\bcc55\projects]

C#:

test1.cs:
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

21/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

usingSystem;
classBaseClass
{
publicBaseClass(){
Console.WriteLine("InBaseClassconstructor");
}
~BaseClass(){
Console.WriteLine("InBaseClassdestructor");
}
}
classDerivedClass:BaseClass
{
publicDerivedClass(){
Console.WriteLine("InDerivedClassconstructor");
}
~DerivedClass(){
Console.WriteLine("InDerivedClassdestructor");
}
}
classMoreDerivedClass:DerivedClass
{
publicMoreDerivedClass(){
Console.WriteLine("InMoreDerivedClassconstructor");
}
~MoreDerivedClass(){
Console.WriteLine("InMoreDerivedClassdestructor");
}
}
publicclassMainClass
{
publicstaticvoidMain(){
BaseClassfoo=newBaseClass();
Console.WriteLine();
foo=newDerivedClass();
Console.WriteLine();
foo=newMoreDerivedClass();
Console.WriteLine();
}
}

Thisshouldproducesimilaroutput(resultsmayvaryduetothenondeterministicnatureof
finalization):
[d:\source\csharp\code]test1.exe
InBaseClassconstructor
InBaseClassconstructor
InDerivedClassconstructor
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

22/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

InBaseClassconstructor
InDerivedClassconstructor
InMoreDerivedClassconstructor
InMoreDerivedClassdestructor
InDerivedClassdestructor
InBaseClassdestructor
InDerivedClassdestructor
InBaseClassdestructor
InBaseClassdestructor
[d:\source\csharp\code]

JAVA:

Test1.java:
classBaseClass{
publicBaseClass(){
System.out.println("InBaseClassconstructor");
}
protectedvoidfinalize()throwsThrowable{
System.out.println("InBaseClassfinalize()");
super.finalize();
}
}
classDerivedClassextendsBaseClass{
publicDerivedClass(){
System.out.println("InDerivedClassconstructor");
}
protectedvoidfinalize()throwsThrowable{
System.out.println("InDerivedClassfinalize()");
super.finalize();
}
}
classMoreDerivedClassextendsDerivedClass{
publicMoreDerivedClass(){
System.out.println("InMoreDerivedClassconstructor");
}
protectedvoidfinalize()throwsThrowable{
System.out.println("InMoreDerivedClassfinalize()");
super.finalize();
}
}
publicclassTest1{
publicstaticvoidmain(Stringargs[]){
BaseClassfoo=newBaseClass();
System.out.println();
foo=newDerivedClass();
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

23/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

System.out.println();
foo=newMoreDerivedClass();
System.out.println();
}
}

Thisshouldproducesimilaroutput(resultsmayvaryduetothenondeterministicnatureof
finalization):
[d:\source\java\code]java.exeTest1
InBaseClassconstructor
InBaseClassconstructor
InDerivedClassconstructor
InBaseClassconstructor
InDerivedClassconstructor
InMoreDerivedClassconstructor
[d:\source\java\code]

AbstractMethodsandClasses
Anabstractmethodisamethodwhichtheclassdoesnotimplement.InC++terminology,sucha
methodistermedapurevirtualfunction.Aclasswhichcontainsoneormoreabstractmethodsis
oftencalledanabstractclassalthoughinsomecasesthetermabstractclassisreservedforclassesthat
containsonlyabstractmethods.Abstractclassescannotbeinstantiated.Classeswhichderivefroman
abstractclassshouldoverrideandprovideimplementationsfortheabstractmethods,orshould
themselvesbemarkedalsoasabstract.DELPHIusestheabstractkeywordtomarkamethodasabstract.
C#andJAVAusetheabstractkeywordtomarkamethodorclassasabstract.Aclassmarkedas
abstractispermittedbutnotrequiredtohaveabstractmembers.C++usesthe=0notationtoindicate
thatavirtualfunctionisapurevirtualfunction.
DELPHI:

Unit1.pas:
unitUnit1;
interface
type
TAbstractBaseClass=class
public
procedureMethod1;virtual;abstract;
end;
TAbstractIntermediateClass=class(TAbstractBaseClass)
public
procedureMethod1;override;abstract;
procedureMethod2;virtual;
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

24/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

end;
TConcreteClass=class(TAbstractIntermediateClass)
public
procedureMethod1;override;
end;
implementation
{TAbstractIntermediateClass}
procedureTAbstractIntermediateClass.Method2;
begin
//
end;
{TConcreteClass}
procedureTConcreteClass.Method1;
begin
inheritedMethod1;
//
end;
end.

C++:

test1.h:
#ifndefTest1_H
#defineTest1_H
classAbstractBaseClass{
public:
virtualvoidmethod1(void)=0;
};
classAbstractIntermediateClass:publicAbstractBaseClass{
public:
virtualvoidmethod1(void)=0;
virtualvoidmethod2(void);
};
classConcreteClass:publicAbstractIntermediateClass{
public:
virtualvoidmethod1(void);
};
#endif//Test1_H
test1.cpp:
#ifndefTest1_H
#include"test1.h"
#endif

http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

25/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

voidAbstractIntermediateClass::method2(void)
{
//
}
voidConcreteClass::method1(void)
{
//
}

C#:

test1.cs:
publicabstractclassAbstractBaseClass
{
publicabstractvoidMethod1();
}
publicabstractclassAbstractIntermediateClass:AbstractBaseClass
{
publicoverrideabstractvoidMethod1();
publicvirtualvoidMethod2(){
//
}
}
publicclassConcreteClass:AbstractBaseClass
{
publicoverridevoidMethod1(){
//
}
}

JAVA:

Test1.java:
abstractclassAbstractBaseClass{
publicabstractvoidmethod1();
}
abstractclassAbstractIntermediateClassextendsAbstractBaseClass{
publicabstractvoidmethod1();
publicvoidmethod2(){
//
}
}
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

26/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

classConcreteClassextendsAbstractIntermediateClass{
publicvoidmethod1(){
//
}
}

Interfaces
Aninterfaceisanabstracttypethatdefinesmembersbutdoesnotprovideanimplementation.
Interfacesareusedtodefineacontractaclassthatimplementsaninterfaceisexpectedtoadhereto
thecontractprovidedbytheinterfaceandprovideimplementationsforallthemembersdefinedinthe
interface.DELPHI,C#andJAVAsupportinterfaces.C++doesnotthoughanabstractclasscomposed
purelyofpublicpurevirtualmethodscouldserveasimilarpurpose.
(Seetheearliersectiononinheritanceforcodeexamplesofinterfaces.)

MethodOverloading
Methodoverloadingreferstotheabilitytodefineseveralmethodswiththesamenamebutwith
differentsignatures(parametertypes,numberofparameters).DELPHIrequiresthatoverloaded
methodsbemarkedwiththeoverloadkeyword.
DELPHI:

Unit1.pas:
unitUnit1;
interface
type
TFoo=class
public
procedureMethodA;
end;
TBar=class(TFoo)
public
procedureMethodA(constI:Integer);overload;
procedureMethodB(constI:Integer);overload;
procedureMethodB(constI:Integer;constS:string);overload;
end;
TFooBar=class(TBar)
public
procedureMethodA(constS:string);overload;
functionMethodC(constI:Integer):Integer;overload;
functionMethodC(constS:string):Integer;overload;
end;
implementation
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

27/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

{TFoo}
procedureTFoo.MethodA;
begin
//
end;
{TBar}
procedureTBar.MethodB(constI:Integer);
begin
//
end;
procedureTBar.MethodB(constI:Integer;constS:string);
begin
//
end;
procedureTBar.MethodA(constI:Integer);
begin
//
end;
{TFooBar}
procedureTFooBar.MethodA(constS:string);
begin
//
end;
functionTFooBar.MethodC(constI:Integer):Integer;
begin
Result:=0;
end;
functionTFooBar.MethodC(constS:string):Integer;
begin
Result:=0;
end;
end.

C++:

test1.h:
#ifndefTest1_H
#defineTest1_H
#include<string>
usingnamespacestd;
classFoo{
public:
voidmethodA(void);
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

28/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

};
classBar:publicFoo{
public:
voidmethodA(int);
voidmethodB(int);
voidmethodB(int,string);
};
classFooBar:publicBar{
public:
voidmethodA(string);
intmethodC(int);
intmethodC(string);
};
#endif//Test1_H
test1.cpp:
#ifndefTest1_H
#include"test1.h"
#endif
#include<string>
voidFoo::methodA(void)
{
//
}
voidBar::methodA(inti)
{
//
}
voidBar::methodB(inti)
{
//
}
voidBar::methodB(inti,strings)
{
//
}
voidFooBar::methodA(strings)
{
//
}
intFooBar::methodC(inti)
{
return0;
}
intFooBar::methodC(strings)
{
return0;
}

http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

29/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

C#:

test1.cs:
publicclassFoo
{
publicvoidMethodA(){
//
}
}
publicclassBar:Foo
{
publicvoidMethodA(inti){
//
}
publicvoidMethodB(inti){
//
}
publicvoidMethodB(inti,strings){
//
}
}
publicclassFooBar:Bar
{
publicvoidMethodA(strings){
//
}
publicintMethodC(inti){
return0;
}
publicintMethodC(strings){
return0;
}
}

JAVA:

Test1.java:
classFoo{
publicvoidmethodA(){
//
}
}
classBarextendsFoo{
publicvoidmethodA(inti){
//
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

30/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

}
publicvoidmethodB(inti){
//
}
publicvoidmethodB(inti,Strings){
//
}
}
classFooBarextendsBar{
publicvoidmethodA(Strings){
//
}
publicintmethodC(inti){
return0;
}
publicintmethodC(Strings){
return0;
}
}

OperatorOverloading
Operatoroverloadingistheprocessofprovidingnewimplementationsforbuiltinoperators(suchas
'+'and''forexample)whentheoperandsareuserdefinedtypessuchasclasses.Thiscansimplifythe
usageofaclassandmakeitmoreintuitive.
OperatoroverloadingisavailableinC++andC#andhasrecentlybeenaddedintoDELPHI.NET.Itis
notavailableinthecurrentWin32implementationofDELPHI,norisitavailableinJAVA.
Thefollowingexamplescreateasimpleclassformanipulatingcomplexnumbers.Itoverloadsthe'+'
and''operators.
DELPHI.NET:

Unit1.pas:
unitUnit1;
interface
type
TComplexNumber=class
public
Real:Integer;
Imaginary:Integer;
classoperatorAdd(constX,Y:TComplexNumber):TComplexNumber;
classoperatorSubtract(constX,Y:TComplexNumber):TComplexNumber;
functionToString:string;override;
constructorCreate(constReal,Imaginary:Integer);
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

31/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

end;
implementation
uses
SysUtils;
{TComplexNumber}
constructorTComplexNumber.Create(constReal,Imaginary:Integer);
begin
inheritedCreate;
Self.Real:=Real;
Self.Imaginary:=Imaginary;
end;
classoperatorTComplexNumber.Add(constX,
Y:TComplexNumber):TComplexNumber;
begin
Result:=TComplexNumber.Create(X.Real+Y.Real,X.Imaginary+Y.Imaginary);
end;
classoperatorTComplexNumber.Subtract(constX,
Y:TComplexNumber):TComplexNumber;
begin
Result:=TComplexNumber.Create(X.RealY.Real,X.ImaginaryY.Imaginary);
end;
functionTComplexNumber.ToString:string;
begin
if(Self.Imaginary>0)then
Result:=Format('%d+%di',[Self.Real,Self.Imaginary])
else
Result:=Format('%d%di',[Self.Real,Abs(Self.Imaginary)]);
end;
end.
Project1.dpr:
programProject1;
{$APPTYPECONSOLE}
uses
SysUtils,
Unit1in'Unit1.pas';
var
A,B:TComplexNumber;
begin
A:=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:
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

32/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

[d:\source\delphi.net\code]Project1.exe
A=(2+5i),B=(43i)
A+B=(6+2i)
AB=(2+8i)
[d:\source\delphi.net\code]

C++:

test1.h:
#ifndefTest1_H
#defineTest1_H
#include<string>
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<string>
#include<sstream>
#include<cmath>
usingnamespacestd;
stringitos(inti)
{
stringstreams;
s<<i;
returns.str();
}
ComplexNumber::ComplexNumber(intreal=0,intimaginary=0)
{
this>real=real;
this>imaginary=imaginary;
}
ComplexNumberComplexNumber::operator+(constComplexNumber&param)const
{
ComplexNumbertemp;
temp.real=this>real+param.real;
temp.imaginary=this>imaginary+param.imaginary;
returntemp;
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

33/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

}
ComplexNumberComplexNumber::operator(constComplexNumber&param)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";
else
returnitos(real)+""+itos(abs(imaginary))+"i";
}
main.cpp:
#ifndefTest1_H
#include"test1.h"
#endif
#include<iostream>
usingnamespacestd;
intmain()
{
ComplexNumbera(2,5);
ComplexNumberb(4,3);
cout<<"a=("<<a.toString()<<"),b=("<<b.toString()<<")"<<endl;
cout<<"a+b=("<<(a+b).toString()<<")"<<endl;
cout<<"ab=("<<(ab).toString()<<")"<<endl;
}
makefile:
#Macros
TOOLSROOT=C:\Borland\BCC55
INCLUDEDIR=$(TOOLSROOT)\Include
LIBDIR=$(TOOLSROOT)\Lib;$(TOOLSROOT)\Lib\PSDK
COMPILER=$(TOOLSROOT)\bin\bcc32.exe
COMPILERSWTS=tWCcI$(INCLUDEDIR)
LINKER=$(TOOLSROOT)\bin\ilink32.exe
LINKERSWTS=apTpexGnL$(LIBDIR)
OBJFILES=test1.objmain.obj
LIBFILES=cw32.libimport32.lib
BASEOUTPUTFILE=main
EXEFILE=$(BASEOUTPUTFILE).exe
#implicitrules
.cpp.obj:

$(COMPILER)$(COMPILERSWTS)$<
#Explicitrules
default:$(EXEFILE)
$(EXEFILE):$(OBJFILES)

$(LINKER)$(LINKERSWTS)c0x32.obj$(OBJFILES),$(EXEFILE),,$(LIBFILES),,
clean:

del$(OBJFILES)

http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

34/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

del$(EXEFILE)
del$(BASEOUTPUTFILE).tds

Thisshouldproducethefollowingoutput:
[c:\borland\bcc55\projects]main.exe
a=(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));
else
return(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));
}
}

http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

35/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

Thisshouldproducethefollowingoutput:
[d:\source\csharp\code]test1.exe
a=(2+5i),b=(43i)
a+b=(6+2i)
ab=(2+8i)
[d:\source\csharp\code]

Properties
Propertiescanbedescribedasobjectorienteddatamembers.Externaltotheclass,propertieslookjust
likedatamembers.Internally,however,propertiescanbeimplementedasmethods.Properties
promoteencapsulationbyallowingtheclasstohidetheinternalrepresentationofitsdata.Also,by
implementingonlyagetter(alsoknownasanaccessor)methodorasetter(alsoknownasamutator)
method,apropertycanbemadereadonlyorwriteonlyrespectively,thusallowingtheclassto
provideaccesscontrol.
DELPHIandC#havesupportforpropertiesbuiltintothelanguage.C++andJAVAdonothavesupport
forpropertiesbuiltinbutcanlooselyimplementthisbehaviorusingaget/setconvention.
DELPHI:

Unit1.pas:
unitUnit1;
interface
type
TRectangle=class
private
FHeight:Cardinal;
FWidth:Cardinal;
protected
functionGetArea:Cardinal;
public
functionToString:string;virtual;
constructorCreate(constWidth,Height:Cardinal);
propertyArea:CardinalreadGetArea;
propertyHeight:CardinalreadFHeightwriteFHeight;
propertyWidth:CardinalreadFWidthwriteFWidth;
end;
implementation
uses
SysUtils;
{TRectangle}
constructorTRectangle.Create(constWidth,Height:Cardinal);
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

36/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

begin
inheritedCreate;
FHeight:=Height;
FWidth:=Width;
end;
functionTRectangle.GetArea:Cardinal;
begin
Result:=FWidth*FHeight;
end;
functionTRectangle.ToString:string;
begin
Result:=Format('Height:%d,Width:%d,Area:%d',[Height,Width,Area]);
end;
end.
Project1.dpr:
programProject1;
{$APPTYPECONSOLE}
uses
SysUtils,
Unit1in'Unit1.pas';
begin
withTRectangle.Create(2,3)do
try
WriteLn(ToString);
Height:=4;
Width:=3;
WriteLn(ToString);
finally
Free;
end;
end.

Thisshouldproducethefollowingoutput:
[c:\borland\delphi7\projects]Project1.exe
Height:3,Width:2,Area:6
Height:4,Width:3,Area:12
[c:\borland\delphi7\projects]

C#:

test1.cs:
usingSystem;
classRectangle
{
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

37/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

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.exe
Height:3,Width:2,Area:6
Height:4,Width:3,Area:12
[d:\source\csharp\code]

Exceptions
Exceptionsprovideauniformmechanismforhandlingerrors.Exceptionsarecreatedandraisedor
thrownwhenthecodeentersaconditionthatitcannotorshouldnothandlebyitself.Oncethe
exceptionisraisedorthrown,theexceptionhandlingmechanismbreaksoutofthenormalflowof
codeexecutionandsearchesforanappropriateexceptionhandler.Ifanappropriateexceptionhandler
isfound,thentheerrorconditionishandledinanappropriatemannerandnormalcodeexecution
resumes.Otherwise,theapplicationisassumedtobeinanunstable/unpredictablestateandexits
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

38/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

withanerror.
DELPHIprovidestheraisekeywordtocreateanexceptionandatry...exceptandtry...finallyconstruct
(butnounifiedtry...except...finallyconstructthoughatry...finallyblockcanbenestedwithina
try...exceptblocktoemulatethisbehavior)forexceptionhandling.Codewritteninatryblockis
executedandifanexceptionoccurs,theexceptionhandlingmechanismsearchesforanappropriate
exceptblocktohandletheexception.Theonkeywordisusedtospecifywhichexceptionsanexcept
blockcanhandle.Asingleexceptblockcancontainmultipleonkeywords.Iftheonkeywordisnot
used,thentheexceptblockwillhandleallexceptions.Codewritteninafinallyblockisguaranteedto
executeregardlessofwhetherornotanexceptionisraised.

Unit1.pas:
unitUnit1;
interface
uses
SysUtils;
type
EMyException=class(Exception);
TMyClass=class
public
procedureMyMethod;
constructorCreate;
destructorDestroy;override;
end;
implementation
{TMyClass}
procedureTMyClass.MyMethod;
begin
WriteLn('EnteringTMyClass.MyMethod');
raiseEMyException.Create('ExceptionraisedinTMyClass.MyMethod!');
WriteLn('LeavingTMyClass.MyMethod');//thisshouldnevergetexecuted
end;
constructorTMyClass.Create;
begin
inheritedCreate;
WriteLn('InTMyClass.Create');
end;
destructorTMyClass.Destroy;
begin
WriteLn('InTMyClass.Destroy');
inheritedDestroy;
end;
end.
Project1.dpr:
programProject1;
{$APPTYPECONSOLE}
uses
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

39/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

SysUtils,
Unit1in'Unit1.pas';
var
MyClass:TMyClass;
begin
MyClass:=TMyClass.Create;
try
try
MyClass.MyMethod;
except
onEMyExceptiondo
WriteLn(ErrOutput,'CaughtanEMyException!');
end;
finally
MyClass.Free;
end;
end.

Thisshouldproducethefollowingoutput:
[c:\borland\delphi7\projects]Project1.exe
InTMyClass.Create
EnteringTMyClass.MyMethod
CaughtanEMyException!
InTMyClass.Destroy
[c:\borland\delphi7\projects]

C++providesthethrowkeywordforcreatinganexceptionandprovidesatry...catchconstructfor
exceptionhandling.Codewritteninthetryblockisexecutedandifanexceptionisthrown,the
exceptionhandlingmechanismlooksforanappropriatecatchblocktodealwiththeexception.A
singletryblockcanhavemultiplecatchblocksassociatedwithit.Catchblockshavearequired
exceptiondeclarationtospecifywhattypeofexceptionitcanhandle.Anexceptiondeclarationof(...)
meansthatthecatchblockwillcatchallexceptions.
Afunctioncanoptionallyspecifywhatexceptionsitcanthrowviaanexceptionspecificationinthe
functiondeclaration.Thethrowkeywordisalsousedforthispurpose.Ifnoexceptionspecificationis
presentthenthefunctioncanthrowanyexception.

test1.h:
#ifndefTest1_H
#defineTest1_H
#include<string>
usingstd::string;
classMyException{
public:
MyException(string);
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

40/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

stringgetMessage()const;
private:
stringmessage;
};
classMyClass{
public:
MyClass();
~MyClass();
voidmyMethod();
};
#endif//Test1_H
test1.cpp:
#ifndefTest1_H
#include"test1.h"
#endif
#include<iostream>
usingstd::cout;
usingstd::endl;
MyException::MyException(stringerrorMessage)
{
message=errorMessage;
}
stringMyException::getMessage()const
{
returnmessage;
}
MyClass::MyClass()
{
cout<<"InMyClass::MyClass()"<<endl;
}
MyClass::~MyClass()
{
cout<<"InMyClass::~MyClass()"<<endl;
}
voidMyClass::myMethod()
{
cout<<"EnteringMyClass::myMethod()"<<endl;
throwMyException("ExceptionthrowninMyClass::myMethod()!");
cout<<"LeavingMyClass::myMethod()"<<endl;//thisshouldnevergetexecuted
}
main.cpp:
#ifndefTest1_H
#include"test1.h"
#endif
#include<iostream>
usingstd::cerr;
usingstd::endl;
intmain()
{
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

41/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

MyClassmyClass;
try{
myClass.myMethod();
}
catch(MyException){
cerr<<"CaughtaMyException!"<<endl;
}
}
makefile:
#Macros
TOOLSROOT=C:\Borland\BCC55
INCLUDEDIR=$(TOOLSROOT)\Include
LIBDIR=$(TOOLSROOT)\Lib;$(TOOLSROOT)\Lib\PSDK
COMPILER=$(TOOLSROOT)\bin\bcc32.exe
COMPILERSWTS=tWCcI$(INCLUDEDIR)
LINKER=$(TOOLSROOT)\bin\ilink32.exe
LINKERSWTS=apTpexGnL$(LIBDIR)
OBJFILES=test1.objmain.obj
LIBFILES=cw32.libimport32.lib
BASEOUTPUTFILE=main
EXEFILE=$(BASEOUTPUTFILE).exe
#implicitrules
.cpp.obj:

$(COMPILER)$(COMPILERSWTS)$<
#Explicitrules
default:$(EXEFILE)
$(EXEFILE):$(OBJFILES)

$(LINKER)$(LINKERSWTS)c0x32.obj$(OBJFILES),$(EXEFILE),,$(LIBFILES),,
clean:

del$(OBJFILES)
del$(EXEFILE)
del$(BASEOUTPUTFILE).tds

Thisshouldproducethefollowingoutput:
[c:\borland\bcc55\projects]main.exe
InMyClass::MyClass()
EnteringMyClass::myMethod()
CaughtaMyException!
InMyClass::~MyClass()
[c:\borland\bcc55\projects]

C#usesthethrowkeywordtothrowanexceptionandprovidestry...catch,try...finallyand
try...catch...finallyconstructsforexceptionhandling.Codeinthetryblockisexecutedandifan
exceptionisthrown,theexceptionhandlingmechanismsearchesforanappropriatecatchblock.A
singletryblockcanhavemultiplecatchblocksassociatedwithit.Acatchblockcandeclarethe
exceptiontypethatithandles.Ifacatchclausedoesnotspecifytheexceptiontypeitwillcatchall
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

42/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

exceptionsthrown.Codeinafinallyblockwillbeexecutedregardlessofwhetherornotanexception
isthrown.

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.exe
InMyClass.MyClass()
EnteringMyClass.MyMethod()
CaughtaMyException!
Infinallyblock
InMyClass.~MyClass()
[d:\source\csharp\code]

JAVAusesthethrowkeywordtothrowanexceptionandprovidestry...catch,try...finallyand
try...catch...finallyconstructsforexceptionhandling.Codeinsideatryblockisexecutedandifan
exceptionisthrown,theexceptionhandlingmechanismsearchesforanappropriatecatchblock.A
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

43/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

singletryblockcanhavemultiplecatchblocksassociatedwithit.Catchblocksarerequiredtospecify
theexceptiontypethattheyhandle.Codeinafinallyblockwillbeexecutedregardlessofwhetheror
notanexceptionisthrown.
JAVAalsorequiresthatmethodseithercatchorspecifyallcheckedexceptionsthatcanbethrown
withinthescopeofthemethod.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.exeTest1
InMyClass.MyClass()
EnteringmyClass.myMethod()
CaughtaMyException!
Infinallyblock
[d:\source\java\code]

GenericsandTemplates
TemplatesandGenericsareconstructsforparametricpolymorphism.Thatis,theymakecreating
parameterizedtypesforcreatingtypesafecollections.However,theydonotrefertothesamething
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

44/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

i.e.templatesarenotgenericsandgenericsarenottemplates.Formoreinformationonwhatthe
differencesare,refertothefollowingexternallinks:
C++Potential:TemplatesandGenerics
GenericsinC#,Java,andC++
Currently,onlytheC++languagesupportstemplates.Genericsupportisplannedforversion2.0of
theC#languageandforversion1.5oftheJAVAlanguage.
C++:

stacktemplate.h:
#ifndefStackTemplate_H
#defineStackTemplate_H
#defineEMPTYSTACK1
template<classT>
classStack{
public:
Stack(int);
~Stack();
boolpush(constT&);
boolpop(T&);
private:
boolisEmpty()const;
boolisFull()const;
intstackSize;
intstackTop;
T*stackPtr;
};
template<classT>
Stack<T>::Stack(intmaxStackSize)
{
stackSize=maxStackSize;
stackTop=EMPTYSTACK;
stackPtr=newT[stackSize];
}
template<classT>
Stack<T>::~Stack()
{
delete[]stackPtr;
}
template<classT>
boolStack<T>::push(constT&param)
{
if(!isFull()){
stackPtr[++stackTop]=param;
returntrue;
}
returnfalse;
}
template<classT>
boolStack<T>::pop(T&param)
{
if(!isEmpty()){
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

45/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

param=stackPtr[stackTop];
returntrue;
}
returnfalse;
}
template<classT>
boolStack<T>::isEmpty()const
{
returnstackTop==EMPTYSTACK;
}
template<classT>
boolStack<T>::isFull()const
{
returnstackTop==stackSize1;
}
#endif
main.cpp:
#ifndefStackTemplate_H
#include"stacktemplate.h"
#endif
#include<iostream>
usingstd::cout;
usingstd::endl;
intmain()
{
Stack<int>intStack(5);
inti=2;
while(intStack.push(i)){
cout<<"pushing"<<i<<"ontointStack"<<endl;
i+=2;
}
while(intStack.pop(i)){
cout<<"popped"<<i<<"fromintStack"<<endl;
}
cout<<endl;
Stack<float>floatStack(5);
floatf=2.1;
while(floatStack.push(f)){
cout<<"pushing"<<f<<"ontofloatStack"<<endl;
f+=2.1;
}
while(floatStack.pop(f)){
cout<<"popping"<<f<<"fromfloatStack"<<endl;
}
}

Thisshouldproducethefollowingoutput:
[c:\borland\bcc55\projects]main.exe
pushing2ontointStack
pushing4ontointStack
pushing6ontointStack
http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

46/47

09/06/2015

ComparingObjectOrientedFeaturesofDelphi,C++,C#andJava

pushing8ontointStack
pushing10ontointStack
popped10fromintStack
popped8fromintStack
popped6fromintStack
popped4fromintStack
popped2fromintStack
pushing2.1ontofloatStack
pushing4.2ontofloatStack
pushing6.3ontofloatStack
pushing8.4ontofloatStack
pushing10.5ontofloatStack
popping10.5fromfloatStack
popping8.4fromfloatStack
popping6.3fromfloatStack
popping4.2fromfloatStack
popping2.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.asp
StandardECMA334C#LanguageSpecification2ndedition(December2002):
http://www.ecmainternational.org/publications/standards/Ecma334.htm
JAVA:
CodeConventionsfortheJavaProgrammingLanguage:
http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html
TheJavaLanguageSpecification:http://java.sun.com/docs/books/jls/
(Lastupdatedon20050910.)

http://www.derangedcoder.net/programming/general/comparingObjectOrientedFeatures.html

47/47