Jump to content

Comparison of programming languages (object-oriented programming)

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Manus eiffel (talk | contribs) at 20:56, 5 August 2009 (Missing instructions after `from'.). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

Object creation and destruction

creation destruction
C++ (STL) class variable«(parameters)»; or
class *variable = new class«(parameters)»;
delete pointer;
C# class variable = new class(parameters); variable.Dispose();[1]
Java variable.dispose();[1]
Objective-C class *variable = [[class alloc ] init]; or
class *variable = [[class alloc ] initWithFoo:parameter «bar:parameter ...»];
[variable release];
Python variable = class(parameters) del variable [1](Normally not needed)
Visual Basic .NET Dim variable As New class(parameters) variable.Dispose()[1]
Eiffel Instructions:
create variable or
create «{TYPE}» variable.make_foo «(parameters)»

Expressions:
create {TYPE} or
create {TYPE}.make_foo «(parameters)»

[1]
PHP $variable = new class(parameters); unset($variable);
Perl 5 «my »$variable = class->new(parameters); undef($variable);
Ruby variable = class.new«(parameters)» [1]
Windows PowerShell $variable = New-Object «-TypeName» class ««-ArgumentList» parameters» Remove-Variable «-Name» variable
OCaml let variable = new class «parameters» or
let variable = object members end[2]
[1]
F# let variable = «new »class(«parameters»)

File declaration

class interface namespace
C++ (STL) class name« : public parentclasses[3]» { members }; namespace name { members }
C# class name« : parentclass«, interfaces»» { members } interface name { members }
Java class name« extends parentclass»« implements interfaces» { members } package name; members
Objective-C @interface name : parentclass «< protocols >» { instance_fields } method_and_property_declarations @end
@implementation
name method_implementations @end[4]
@protocol name members @end
Python class name(parentclasses[3]):
Tab ↹
members
same, declare methods with pass as body __all__ = [ member1,member2,... ]
Visual Basic .NET Class name« Inherits parentclass»« Implements interfaces»
members
End Class
Interface name
members
End Interface
Namespace name
members
End Namespace
Eiffel class name« inherit parentclasses[3]»
members
end
PHP class name« extends parentclass»« implements interfaces» { members } interface name { members } namespace name; members
Perl package name; «@ISA = qw(parentclasses[3]);» members 1; package name; members
Ruby class name« < parentclass»
members
end
Windows PowerShell
OCaml class name «parameters» = object «(self)» «inherit parentclass «parameters» «inherit parentclass «parameters» ...[3]»» members end
F# type name«(parameters)» «as this» = class «inherit parentclass«(parameters)» «as base»» members «interface interface with implementation «interface interface with implementation ...»» end type name = interface members end namespace name
members

Class members

Constructors and destructors

constructor destructor/finalizer
C++ (STL) class(«parameters») «: initializers[5]» { instructions } ~class() { instructions }
C# class(«parameters») { instructions } ~class() { instructions }[6]
Java void finalize() { instructions }[6]
Eiffel [7] Implementing {DISPOSABLE}.dispose ensures that dispose will be called when object is garbage collected.
Objective-C - (id)init { instructions... return self; } or
- (id)initWithFoo:parameter «bar:parameter ...» { instructions... return self; }
- (void)dealloc { instructions }
Python def __init__(self«, parameters»):
Tab ↹ instructions
def __del__(self):
Tab ↹ instructions
Visual Basic .NET Sub New(«parameters»)
instructions
End Sub
Overrides Sub Finalize()
instructions
End Sub
PHP function __construct(«parameters») { instructions } function __destruct() { instructions }
Perl sub new { my ($class«, parameters») = @_; my $self = {}; instructions ... bless($self, $class); return $self; } sub DESTROY { my ($self) = @_; instructions }
Ruby def initialize«(parameters)»
instructions
end
Windows PowerShell
OCaml initializer instructions[8]
F# do instructions override this.Finalize() = instructions[6]
public private protected friend
C++ (STL) public: type field; private: type field; protected: type field; [9]
C# public type field «= value»; private type field «= value»; protected type field «= value»; internal type field «= value»;
Java type field «= value»;
Eiffel feature
field: TYPE
feature {NONE}
field: TYPE
feature {NONE}
field: TYPE
feature {FRIEND}
field: TYPE
Objective-C @public type field; @private type field; @protected type field; @package type field;
Python self.field = value
Just assign a value to it in a method
self.__field = value
Just assign a value to it in a method
Visual Basic .NET Public field As type «= value» Private field As type «= value» Protected field As type «= value» Friend field As type «= value»
PHP public $field «= value»; private $field «= value»; protected $field «= value»;
Perl $self->{field} = value;
Just assign a value to it in a method
Ruby @field = value
Just assign a value to it in a method
Windows PowerShell Add-Member
«-MemberType »NoteProperty
«-Name »Bar «-Value »value
-InputObject variable
OCaml val «mutable» field = value
F# let «mutable» field = value

Methods

basic/void method value-returning method
C++ (STL)[10] void foo(«parameters») { instructions } type foo(«parameters») { instructions ... return value; }
C#
Java
Eiffel foo ( «parameters» )
do
instructions
end
foo ( «parameters» ): TYPE
do
instructions...
Result := value
end
Objective-C - (void)foo«:parameter «bar:parameter ...»» { instructions } - (type)foo«:parameter «bar:parameter ...»» { instructions... return value; }
Python def foo(self«, parameters»):
Tab ↹
instructions
def foo(self«, parameters»):
Tab ↹
instructions
Tab ↹ return
value
Visual Basic .NET Sub Foo(«parameters»)
instructions
End Sub
Function Foo(«parameters») As type
instructions
...
Return value
End Function
PHP function foo(«parameters») { instructions } function foo(«parameters») { instructions ... return value; }
Perl sub foo { my ($self«, parameters») = @_; instructions } sub foo { my ($self«, parameters») = @_; instructions ... return value; }
Ruby def foo«(parameters)»
instructions
end
def foo«(parameters)»
instructions
expression resulting in return value
end
or
def foo«(parameters
instructions
return value
end
Windows PowerShell Add-Member «-MemberType» ScriptMethod «-Name» foo «-Value» { «param(parameters)» instructions } -InputObject variable Add-Member «-MemberType» ScriptMethod «-Name» foo «-Value» { «param(parameters)» instructions ... return value } -InputObject variable
OCaml method foo «parameters» = expression
F# member this.foo(«parameters») = expression

How to declare a property named "Bar"

read-write read-only write-only
C++ (STL)
C# type Bar {
get {
instructions ... return value; }
set {
instructions } }
type Bar { get { instructions ... return value; } } type Bar { set { instructions } }
Java
Objective-C @property (readwrite) type bar;
and then inside @implementation either
@synthesize bar;
or

- (type)bar { instructions }
- (void)setBar:(type)value { instructions }

@property (readonly) type bar;
and then inside @implementation either
@synthesize bar;
or

- (type)bar { instructions }

Eiffel feature -- Access
x: TYPE assign set_x
feature -- Settings
set_x (a_x: like x) do instructions ensure x_set: verification end
Python def setBar(self, value):
Tab ↹
instructions
def
getBar(self):
Tab ↹
instructions
Tab ↹ return value
bar = property(getBar, setBar)
def getBar(self):
Tab ↹
instructions
Tab ↹ return value
bar = property(getBar)
def setBar(self, value):
Tab ↹
instructions
bar = property(fset = setBar)
Visual Basic .NET Property Bar As type
Get
instructions
Return value
End Get
Set (ByVal
Value As type)
instructions
End Set
End Property
ReadOnly Property Bar As type
Get
instructions
Return value
End Get
End Property
WriteOnly Property Bar As type
Set (ByVal Value As type)
instructions
End Set
End Property
PHP function __get($property) {
switch (
$property) {
case '
Bar' : instructions ... return value;
} }
function __set(
$property, $value) {
switch (
$property) {
case '
Bar' : instructions
} }
function __get($property) {
switch ($
property) {
case '
Bar' : instructions ... return value;
} }
function __set($property, $value) {
switch (
$property) {
case '
Bar' : instructions
} }
Perl
Ruby def bar
instructions
expression resulting in return value
end
def bar=(value)
instructions
end
or
attr_accessor :bar
def bar
instructions
expression resulting in return value
end
or
attr_reader :bar
def bar=(value)
instructions
end
or
attr_writer :bar
Windows PowerShell Add-Member
«-MemberType »ScriptProperty
«-Name »Bar «-Value »{ instructions ... return value }
«-SecondValue »{ instructions }
-InputObject variable
Add-Member
«-MemberType »ScriptProperty
«-Name »Bar «-Value »{ instructions ... return value}
-InputObject variable
Add-Member
«-MemberType »ScriptProperty
«-Name »Bar -SecondValue { instructions }
-InputObject variable
OCaml
F# member this.Bar with get() = expression and set(value) = expression member this.Bar = expression member this.Bar with set(value) = expression
unary binary index type cast
C++ (STL) type operatorsymbol() { instructions } type operatorsymbol(type operand2) { instructions } type operator[](type index) { instructions } operator returntype() { instructions }
C# static type operator symbol(type operand) { instructions } static type operator symbol(type operand1, type operand2) { instructions } type this[type index] {
get{
instructions }
set{
instructions } }
static explicit operator returntype(type operand) { instructions }
Java
Objective-C
Eiffel [11] op_name alias "symbol": TYPE
do instructions end
op_name alias "symbol" (operand: TYPE1): TYPE2
do instructions end
bracket_name alias "[]" (index: INTEGER; ...) TYPE
do instructions end
Python def __opname__(self):
Tab ↹
instructions
Tab ↹ return
value
def __opname__(self, operand2):
Tab ↹
instructions
Tab ↹ return
value
def __getitem__(self, index):
Tab ↹ instructions
Tab ↹ return value
def __setitem__(self, index, value):
Tab ↹ instructions
Visual Basic .NET Shared Operator symbol(operand As type) As type
instructions
End Operator
Shared Operator symbol(operand1 As type, operand2 As type) As type
instructions
End Operator
Default Property Item(Index As type) As type
Get
instructions
End Get
Set(ByVal
Value As type)
instructions
End Set
End Propery
Shared casttype[12] Operator CType(operand As type) As returntype
instructions
End Operator
PHP [13] [14]
Perl use overload "symbol" => sub { my ($self) = @_; instructions }; use overload "symbol" => sub { my ($self, $operand2, $operands_reversed) = @_; instructions };
Ruby def symbol
instructions
expression resulting in return value
end
def symbol(operand2)
instructions
expression resulting in return value
end
def [](index)
instructions
expression resulting in return value
end
def []=(index, value)
instructions
end
Windows PowerShell
OCaml
F# static member (symbol) operand = expression static member (symbol) (operand1, operand2) = expression member this.Item with get(index) = expression and set index value = expression

Member access

How to access members of an object x

object member class member namespace member
method field property
C++ (STL) x.method(parameters) or
ptr->method(parameters)
x.field or
ptr->field
cls::member ns::member
Objective-C [x method«:parameter «bar:parameter ...»»] x->field x.property (2.0 only) or
[x property]
[cls method«:parameter «bar:parameter ...»»]
C# x.method(parameters) x.field x.property cls.member ns.member
Java
Python x.property
Visual Basic .NET
Windows PowerShell [cls]::member
F# cls.member
Eiffel x.method«(parameters)» x.field {cls}.member
Ruby x.property cls.member
PHP x->method(parameters) x->field x->property cls::member ns\member
Perl x->method«(parameters)» x->{field} cls->method«(parameters)» ns::member
OCaml x#method «parameters»

Member availability

Has member? Handler for missing member
Method Field Method Field
C++ (STL)
Objective-C [x respondsToSelector:@selector(method)] forwardInvocation:
C#
Java
Eiffel
Python hasattr(x, "method") and callable(x.method) hasattr(x, "field") __getattr__()
Visual Basic .NET
Windows PowerShell
F#
Eiffel
Ruby x.respond_to?(:method) method_missing()
PHP method_exists(x, "method") property_exists(x, "field") __call() __get() / __set()
Perl x->can("method") defined x->{field} AUTOLOAD
OCaml

Special variables

current object current object's parent object null reference
C++ (STL) *this [15] NULL
C# this base[16] null
Java super[16]
Objective-C self super nil
Python self[17] super(current_class_name, self)[3]
super() (3.x only)
None
Visual Basic .NET Me MyBase Nothing
Eiffel Current Precursor «{superclass}» «(args)»[16][18] Void
PHP $this parent[16] NULL
Perl $self[17] $self->SUPER[16] undef
Ruby self super«(args)»[19] nil
Windows PowerShell $this $NULL
OCaml self[20] super[21] [22]
F# this base[16] null

Special methods

String representation Object copy Value equality Object comparison Hash code Object ID
C++ (STL) x == y[23]
C# x.ToString() x.Clone() x.Equals(y) x.CompareTo(y) x.GetHashCode()
Java x.toString() x.clone()[24] x.equals(y) x.compareTo(y) x.hashCode() System.identityHashCode(x)
Objective-C [x description] [x copy][25] [x isEqual:y] [x compare:y] [x hash]
Python str(x)[26] copy.copy(x)[27] x == y[28] cmp(x ,y)[29] hash(x)[30] id(x)
Visual Basic .NET x.ToString() x.Clone() x.Equals(y) x.CompareTo(y) x.GetHashCode()
Eiffel x.out x.twin x.is_equal(y) When x is COMPARABLE, one can simply do x < y When x is HASHABLE, one can simply do x.hash_code When x is IDENTIFIED, one can simply do x.object_id
PHP sprintf("%s", x)[31] clone x[32] x == y spl_object_hash(x)
Perl "$x"[33]
Ruby x.to_s x.dup or
x.clone
x == y or
x.eql?(y)
x <=> y x.hash x.object_id
Windows PowerShell x.ToString() x.Clone() x.Equals(y) x.CompareTo(y) x.GetHashCode()
OCaml Oo.copy x x = y Hashtbl.hash x Oo.id x
F# x.ToString() x.Clone() x.Equals(y) x.CompareTo(y) x.GetHashCode()

Type manipulation

Get object type Is instance of (includes subtypes) Upcasting Downcasting
C++ (STL) typeid(x) dynamic_cast<type *>(&x) != NULL [34] (type) x or dynamic_cast<type*>(ptr)
C# x.GetType() x is type (type) x
Java x.getClass() x instanceof class
Objective-C [x class] [x isKindOfClass:[class class]]
Visual Basic .NET x.GetType() TypeOf x Is type CType(x, type)
Eiffel x.generating_type attached {TYPE} x attached {TYPE} x as down_x
Python type(x) isinstance(x, type) [35]
PHP get_class(x) x instanceof class
Perl ref(x) x->isa("class")
Ruby x.class or
x.type
x.instance_of?(type) or
x.kind_of?(type)
Windows PowerShell x.GetType() x -is [type] [34] [type]x
OCaml [36] (x :> type)
F# x.GetType() x :? type (x :?> type)


Contracts

Precondition Postcondition Check Invariant Loop
C++ (STL)
C#
Java
Objective-C
Visual Basic .NET
Eiffel f
require tag: expression
do end
f
do
ensure
tag: expression
end
f
do
check tag: expression end
end
class X
invariant tag: expression
end
from instructions
invariant
tag: expression
until
expr
loop
instructions
variant
tag: expression
end
Python
PHP
Perl
Ruby
Windows PowerShell
OCaml
F#

See also

Notes

  1. ^ a b c d e f g This language uses garbage collection to release unused memory.
  2. ^ OCaml objects can be created directly without going through a class.
  3. ^ a b c d e f This language supports multiple inheritance. A class can have more than one parent class
  4. ^ Usually the @interface portion is placed into a header file, and the @interface portion is placed into a separate source code file.
  5. ^ An optional comma-separated list of initializers for member objects and parent classes goes here. The syntax for initializing member objects is "member_name(parameters)" This works even for primitive members, in which case one parameter is specified and that value is copied into the member. The syntax for initializing parent classes is "class_name(parameters)". If an initializer is not specified for a member or parent class, then the default constructor is used.
  6. ^ a b c This is a finalizer rather than a destructor. It is called by the garbage collector when an object is about to be garbage-collected. There is no guarantee on when it will be called or if it will be called at all.
  7. ^ Any Eiffel procedure can be used as a creation procedure, aka constructors.
  8. ^ This "initializer" construct is rarely used. Fields in OCaml are usually initialized directly in their declaration. Only when additional imperative operations are needed is "initializer" used. The "parameters to the constructor" in other languages are instead specified as the parameters to the class in OCaml. See the class declaration syntax for more details.
  9. ^ In C++, you don't declare specific fields to be accessible by outside things. Rather, you declare outside functions and classes to be friends to have access to the class's fields. See friend function and friend class for more details.
  10. ^ The declaration and implementation of methods in C++ are usually separate. Methods are declared inside the class definition (which is usually included in a header file) using the syntax
    type foo(«parameters»);
    The implementation of methods is usually provided in a separate source file, with the following syntax
    type class::foo(«parameters») { instructions }
    Although the body of a method could be included with the declaration inside the class definition, as shown in the table here, this is generally a bad idea. Because the class definition will need to be included with every source file which uses the fields or methods of the class, having code in the class definition will cause the method code to be compiled with every source file, increasing the size of the code. There are some circumstances, however, where it is useful to include the body of a method with the declaration. One reason is that the compiler will try to inline methods that are included in the class declaration; so if you have a very short one-liner method, it may make it faster to allow the compiler to inline it, by including the body along with the declaration. Also, if you have a template class or method, then all the code must be included with the declaration, because only with the code can the template be instantiated.
  11. ^ Although Eiffel does not support overloading of operators, it can define operators
  12. ^ Where casttype is either Widening(may not cause data loss) or Narrowing(data loss possible).
  13. ^ PHP does not support operator overloading natively, but support can be added using the "operator" PECL package.
  14. ^ Your class needs to implement the ArrayAccess interface.
  15. ^ C++ doesn't have a "super" keyword, because multiple inheritance is possible, and so it may be ambiguous which base class is desired. Instead, you can use the BaseClassName::member syntax to access an overridden member in the specified base class. Microsoft Visual C++ provides a non-standard keyword "__super" for this purpose; but this is not supported in other compilers.[1]
  16. ^ a b c d e f The keyword here is not a value in itself and it can only be used to access a method of the superclass.
  17. ^ a b In this language, instance methods are passed the current object as the first parameter, which is conventionally named "self", but this is not required to be the case.
  18. ^ "Precursor" in Eiffel is actually a call to the method of the same name in the superclass. So Precursor(args) is equivalent to "super.currentMethodName(args)" in Java. There is no way of calling a method of different name in the superclass.
  19. ^ "super" in Ruby, unlike in other languages, is actually a call to the method of the same name in the superclass. So super(args) in Ruby is equivalent to "super.currentMethodName(args)" in Java. There is no way of calling a method of different name in the superclass.
  20. ^ In OCaml, an object declaration can optionally start with a parameter which will be associated with the current object. This parameter is conventionally named "self", but this is not required to be the case. It is good practice to put a parameter there so that one can call one's own methods.
  21. ^ In OCaml, an inheritance declaration ("inherit") can optionally be associated with a value, with the syntax "inherit parent_class «parameters» as super". Here "super" is the name we gave to the variable associated with this parent object. It can be named something else.
  22. ^ However, if you really wanted the ability to have an "optional" value in OCaml, you would wrap the value inside an option type, whose values are None and Some x, which could be used to represent "null reference" and "non-null reference to an object" as in other languages.
  23. ^ assuming that "x" and "y" are the objects (and not a pointer). Can be customized by overloading the object's == operator
  24. ^ Only accessible from within the class itself, since the clone() method inherited from Object is protected, unless the class overrides the method and makes it public. If you use the clone() inherited from Object, your class will need to implement the Cloneable interface to allow cloning.
  25. ^ Implemented by the object's copyWithZone: method
  26. ^ Can be customized by the object's __str__() method
  27. ^ Can be customized by the object's __copy__() method
  28. ^ Can be customized by the object's __eq__() method
  29. ^ Can be customized by the object's __cmp__() method
  30. ^ Can be customized by the object's __hash__() method
  31. ^ Can be customized by the object's __toString() method
  32. ^ Can be customized by the object's __clone() method
  33. ^ Can be customized by overloading the object's string-convertion operator
  34. ^ a b Upcasting is implicit in this language. A subtype instance can be used where a supertype is needed.
  35. ^ Casting between types is not necessary.
  36. ^ This language doesn't give run-time type information. It is unnecessary because it is statically typed and downcasting is not possible.