Polymorphism: Difference between revisions
Content added Content deleted
Drkameleon (talk | contribs) (Added Arturo implementation) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 7: | Line 7: | ||
=={{header|ActionScript}}== |
=={{header|ActionScript}}== |
||
< |
<syntaxhighlight lang="actionscript">package |
||
{ |
{ |
||
public class Point |
public class Point |
||
Line 45: | Line 45: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="actionscript">package { |
||
public class Circle extends Point |
public class Circle extends Point |
||
{ |
{ |
||
Line 72: | Line 72: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
This example is constructed using a parent package and a child package. The parent package defines the Point type. The child package defines the Circle type. |
This example is constructed using a parent package and a child package. The parent package defines the Point type. The child package defines the Circle type. |
||
< |
<syntaxhighlight lang="ada">package Shapes is |
||
type Point is tagged private; |
type Point is tagged private; |
||
procedure Print(Item : in Point); |
procedure Print(Item : in Point); |
||
Line 92: | Line 92: | ||
Y : Integer := 0; |
Y : Integer := 0; |
||
end record; |
end record; |
||
end Shapes;</ |
end Shapes;</syntaxhighlight> |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_Io; use Ada.Text_Io; |
||
package body Shapes is |
package body Shapes is |
||
Line 169: | Line 169: | ||
end Create; |
end Create; |
||
end Shapes;</ |
end Shapes;</syntaxhighlight> |
||
The following is the child package defining the Circle type. |
The following is the child package defining the Circle type. |
||
< |
<syntaxhighlight lang="ada">package Shapes.Circles is |
||
type Circle is new Point with private; |
type Circle is new Point with private; |
||
procedure Print(Item : Circle); |
procedure Print(Item : Circle); |
||
Line 188: | Line 188: | ||
R : Integer := 0; |
R : Integer := 0; |
||
end record; |
end record; |
||
end Shapes.Circles;</ |
end Shapes.Circles;</syntaxhighlight> |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_Io; use Ada.Text_IO; |
||
package body Shapes.Circles is |
package body Shapes.Circles is |
||
Line 294: | Line 294: | ||
end Create; |
end Create; |
||
end Shapes.Circles;</ |
end Shapes.Circles;</syntaxhighlight> |
||
The following procedure is an entry point for a program, serving the same purpose as the main function in C. |
The following procedure is an entry point for a program, serving the same purpose as the main function in C. |
||
< |
<syntaxhighlight lang="ada">with Shapes.Circles; use Shapes.Circles; |
||
use Shapes; |
use Shapes; |
||
Line 305: | Line 305: | ||
P.Print; |
P.Print; |
||
C.Print; |
C.Print; |
||
end Shapes_Main;</ |
end Shapes_Main;</syntaxhighlight> |
||
=={{header|Aikido}}== |
=={{header|Aikido}}== |
||
< |
<syntaxhighlight lang="aikido"> |
||
class Point (protected x=0.0, protected y=0.0) { |
class Point (protected x=0.0, protected y=0.0) { |
||
public function print { |
public function print { |
||
Line 335: | Line 335: | ||
c.print() |
c.print() |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
{{works with|ALGOL 68G|Any - tested with release 2.8.win32}} |
{{works with|ALGOL 68G|Any - tested with release 2.8.win32}} |
||
< |
<syntaxhighlight lang="algol68"># Algol 68 provides for polymorphic operators but not procedures # |
||
# define the CIRCLE and POINT modes # |
# define the CIRCLE and POINT modes # |
||
Line 433: | Line 433: | ||
PRINT c1; newline( stand out ) |
PRINT c1; newline( stand out ) |
||
END</ |
END</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 442: | Line 442: | ||
=={{header|Arturo}}== |
=={{header|Arturo}}== |
||
< |
<syntaxhighlight lang="rebol">define :point [x,y][ |
||
init: [ |
init: [ |
||
ensure -> is? :floating this\x |
ensure -> is? :floating this\x |
||
Line 471: | Line 471: | ||
print p |
print p |
||
print c</ |
print c</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 492: | Line 492: | ||
{{works with|AutoHotkey 1.1}} |
{{works with|AutoHotkey 1.1}} |
||
AutoHotkey does not support private or protected properties and thus does not need assignment and accessor methods. Assignment and accessor methods, as well as direct assignment and access, are shown. For more information see [http://ahkscript.org/docs/Objects.htm Objects]. |
AutoHotkey does not support private or protected properties and thus does not need assignment and accessor methods. Assignment and accessor methods, as well as direct assignment and access, are shown. For more information see [http://ahkscript.org/docs/Objects.htm Objects]. |
||
< |
<syntaxhighlight lang="autohotkey">MyPoint := new Point(1, 8) |
||
MyPoint.Print() |
MyPoint.Print() |
||
MyCircle := new Circle(4, 7, 9) |
MyCircle := new Circle(4, 7, 9) |
||
Line 564: | Line 564: | ||
this.r := aValue |
this.r := aValue |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|BASIC}}== |
=={{header|BASIC}}== |
||
Line 571: | Line 571: | ||
=={{header|BBC BASIC}}== |
=={{header|BBC BASIC}}== |
||
{{works with|BBC BASIC for Windows}} |
{{works with|BBC BASIC for Windows}} |
||
< |
<syntaxhighlight lang="bbcbasic"> INSTALL @lib$ + "CLASSLIB" |
||
REM Create parent class with void 'doprint' method: |
REM Create parent class with void 'doprint' method: |
||
Line 608: | Line 608: | ||
PROC(mycircle.doprint) |
PROC(mycircle.doprint) |
||
PROC_discard(mycircle{}) |
PROC_discard(mycircle{}) |
||
END</ |
END</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 619: | Line 619: | ||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
class Point |
class Point |
||
{ |
{ |
||
Line 650: | Line 650: | ||
c.print(); |
c.print(); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
< |
<syntaxhighlight lang="cpp">#include <cstdio> |
||
#include <cstdlib> |
#include <cstdlib> |
||
Line 708: | Line 708: | ||
return EXIT_SUCCESS; |
return EXIT_SUCCESS; |
||
}</ |
}</syntaxhighlight> |
||
'''Pattern:''' [[CRTP|Curiously Recurring Template Pattern]] |
'''Pattern:''' [[CRTP|Curiously Recurring Template Pattern]] |
||
< |
<syntaxhighlight lang="cpp">#include <cstdio> |
||
#include <cstdlib> |
#include <cstdlib> |
||
Line 783: | Line 783: | ||
delete c; |
delete c; |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Ceylon}}== |
=={{header|Ceylon}}== |
||
< |
<syntaxhighlight lang="ceylon">import ceylon.language { |
||
consolePrint = print |
consolePrint = print |
||
} |
} |
||
Line 838: | Line 838: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
Clojure 1.2. |
Clojure 1.2. |
||
< |
<syntaxhighlight lang="lisp">(defprotocol Printable |
||
(print-it [this] "Prints out the Printable.")) |
(print-it [this] "Prints out the Printable.")) |
||
Line 860: | Line 860: | ||
(defn create-circle |
(defn create-circle |
||
"Redundant consturctor function." |
"Redundant consturctor function." |
||
[x y r] (Circle. x y r))</ |
[x y r] (Circle. x y r))</syntaxhighlight> |
||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
< |
<syntaxhighlight lang="lisp">(defclass point () |
||
((x :initarg :x :initform 0 :accessor x) |
((x :initarg :x :initform 0 :accessor x) |
||
(y :initarg :y :initform 0 :accessor y))) |
(y :initarg :y :initform 0 :accessor y))) |
||
Line 885: | Line 885: | ||
(c (make-instance 'circle :radius 5))) |
(c (make-instance 'circle :radius 5))) |
||
(print-shape p) |
(print-shape p) |
||
(print-shape c))</ |
(print-shape c))</syntaxhighlight> |
||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang="d">import std.stdio: writeln; |
||
class Point { |
class Point { |
||
Line 923: | Line 923: | ||
writeln(p); |
writeln(p); |
||
writeln(c); |
writeln(c); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
< |
<syntaxhighlight lang="delphi">type |
||
{ TPoint } |
{ TPoint } |
||
Line 1,032: | Line 1,032: | ||
begin |
begin |
||
ShowMessage('MyPoint'); |
ShowMessage('MyPoint'); |
||
end;</ |
end;</syntaxhighlight> |
||
< |
<syntaxhighlight lang="delphi">var |
||
MyPoint: TMyPoint; |
MyPoint: TMyPoint; |
||
Circle: TCircle; |
Circle: TCircle; |
||
Line 1,050: | Line 1,050: | ||
FreeAndNil(MyPoint); |
FreeAndNil(MyPoint); |
||
end; |
end; |
||
end;</ |
end;</syntaxhighlight> |
||
=={{header|E}}== |
=={{header|E}}== |
||
< |
<syntaxhighlight lang="e">def makePoint(x, y) { |
||
def point implements pbc { |
def point implements pbc { |
||
to __printOn(out) { out.print(`<point $x,$y>`) } |
to __printOn(out) { out.print(`<point $x,$y>`) } |
||
Line 1,075: | Line 1,075: | ||
} |
} |
||
return circle |
return circle |
||
}</ |
}</syntaxhighlight> |
||
(It is unidiomatic to have mutation operations on an object of this sort in E, so this example has variation operations instead. __optUncall is used for serialization, and is the closest analogue to a copy constructor. E does not have destructors, but only post-mortem finalizers (which are registered after the object is created). The "extends" is only implementation inheritance; it is not necessary to enable polymorphism.) |
(It is unidiomatic to have mutation operations on an object of this sort in E, so this example has variation operations instead. __optUncall is used for serialization, and is the closest analogue to a copy constructor. E does not have destructors, but only post-mortem finalizers (which are registered after the object is created). The "extends" is only implementation inheritance; it is not necessary to enable polymorphism.) |
||
< |
<syntaxhighlight lang="e">def p := makePoint(0.5, 0.5) |
||
def c := makeCircle(1, 1, 2) |
def c := makeCircle(1, 1, 2) |
||
println(p) |
println(p) |
||
println(c)</ |
println(c)</syntaxhighlight> |
||
=={{header|EchoLisp}}== |
=={{header|EchoLisp}}== |
||
< |
<syntaxhighlight lang="scheme"> |
||
(struct Point ((real:x 0) (real:y 0))) |
(struct Point ((real:x 0) (real:y 0))) |
||
(struct Circle ((real:x 0) (real:y 0) (real:r 1))) |
(struct Circle ((real:x 0) (real:y 0) (real:r 1))) |
||
Line 1,128: | Line 1,128: | ||
(print (Circle 0 0 10)) |
(print (Circle 0 0 10)) |
||
→ ⭕️ center:[0 0] radius:10 diameter:62.83185307179586 |
→ ⭕️ center:[0 0] radius:10 diameter:62.83185307179586 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Eiffel}}== |
=={{header|Eiffel}}== |
||
< |
<syntaxhighlight lang="eiffel ">class |
||
POINT |
POINT |
||
inherit |
inherit |
||
Line 1,195: | Line 1,195: | ||
Result := "Point: x = " + x.out + " y = " + y.out |
Result := "Point: x = " + x.out + " y = " + y.out |
||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
< |
<syntaxhighlight lang="eiffel ">class |
||
CIRCLE |
CIRCLE |
||
Line 1,278: | Line 1,278: | ||
non_negative_radius: r >= 0 |
non_negative_radius: r >= 0 |
||
end</ |
end</syntaxhighlight> |
||
< |
<syntaxhighlight lang="eiffel ">class |
||
APPLICATION |
APPLICATION |
||
Line 1,314: | Line 1,314: | ||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,337: | Line 1,337: | ||
Solution of this problem in Ela is similar to Haskell, as soon as Ela shares with Haskell the same features - namely, classes (typeclasses) and algebraic types. |
Solution of this problem in Ela is similar to Haskell, as soon as Ela shares with Haskell the same features - namely, classes (typeclasses) and algebraic types. |
||
< |
<syntaxhighlight lang="ela">type Point = Point x y |
||
instance Show Point where |
instance Show Point where |
||
Line 1,379: | Line 1,379: | ||
circleZ = Circle 0 0 |
circleZ = Circle 0 0 |
||
circleEmpty = Circle 0 0 0</ |
circleEmpty = Circle 0 0 0</syntaxhighlight> |
||
Class Show is defined in prelude and is effectively an abstraction for all "printable" entities. |
Class Show is defined in prelude and is effectively an abstraction for all "printable" entities. |
||
Line 1,385: | Line 1,385: | ||
Normally, algebraic types are analyzed using pattern matching, however, it is possible to provide a support for an "accessor style" approach by providing an instance for class Name (which is also defined in prelude). With this instance it is possible to write code like so: |
Normally, algebraic types are analyzed using pattern matching, however, it is possible to provide a support for an "accessor style" approach by providing an instance for class Name (which is also defined in prelude). With this instance it is possible to write code like so: |
||
< |
<syntaxhighlight lang="ela">c = circleX 12 |
||
c.x //Evaluates to 12</ |
c.x //Evaluates to 12</syntaxhighlight> |
||
=={{header|Elena}}== |
=={{header|Elena}}== |
||
ELENA 5.0 : |
ELENA 5.0 : |
||
< |
<syntaxhighlight lang="elena">import extensions; |
||
class Point |
class Point |
||
Line 1,435: | Line 1,435: | ||
p.print(); |
p.print(); |
||
c.print() |
c.print() |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,447: | Line 1,447: | ||
Due to the use of optional parameters, we only need one constructor for every class. No accessors are necessary because we use public read-only properties. (Mutable properties are possible, too, but should be avoided in idiomatic code.) |
Due to the use of optional parameters, we only need one constructor for every class. No accessors are necessary because we use public read-only properties. (Mutable properties are possible, too, but should be avoided in idiomatic code.) |
||
< |
<syntaxhighlight lang="fsharp">type Printable = |
||
abstract member Print : unit -> unit |
abstract member Print : unit -> unit |
||
Line 1,461: | Line 1,461: | ||
interface Printable with |
interface Printable with |
||
member t.Print() = |
member t.Print() = |
||
printfn "Circle(x:%f, y:%f, r:%f)" t.center.x t.center.y t.radius</ |
printfn "Circle(x:%f, y:%f, r:%f)" t.center.x t.center.y t.radius</syntaxhighlight> |
||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
< |
<syntaxhighlight lang="factor">QUALIFIED: io ! there already is print in io |
||
GENERIC: print ( shape -- ) |
GENERIC: print ( shape -- ) |
||
Line 1,476: | Line 1,476: | ||
C: <circle> circle |
C: <circle> circle |
||
M: circle print drop "Circle" io:print ;</ |
M: circle print drop "Circle" io:print ;</syntaxhighlight> |
||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
{{works with|4tH|3.62.0}} |
{{works with|4tH|3.62.0}} |
||
There are numerous, mutually incompatible object oriented frameworks for Forth. This one works with the FOOS preprocessor extension of [[4tH]]. Variadic functions in Forth are usually implemented by passing the number of parameters. Since it is highly unlikely that objects are allocated that low in memory it works. Note that X, Y and Z are passed in reverse order, which is quite common for any Forth program. |
There are numerous, mutually incompatible object oriented frameworks for Forth. This one works with the FOOS preprocessor extension of [[4tH]]. Variadic functions in Forth are usually implemented by passing the number of parameters. Since it is highly unlikely that objects are allocated that low in memory it works. Note that X, Y and Z are passed in reverse order, which is quite common for any Forth program. |
||
< |
<syntaxhighlight lang="forth">include lib/memcell.4th |
||
include 4pp/lib/foos.4pp |
include 4pp/lib/foos.4pp |
||
Line 1,569: | Line 1,569: | ||
Circle2 => print |
Circle2 => print |
||
Circle1 new Circle Circle3 |
Circle1 new Circle Circle3 |
||
Circle3 => print</ |
Circle3 => print</syntaxhighlight> |
||
Line 1,576: | Line 1,576: | ||
Needs the FMS-SI (single inheritance) library code located here: |
Needs the FMS-SI (single inheritance) library code located here: |
||
http://soton.mpeforth.com/flag/fms/index.html |
http://soton.mpeforth.com/flag/fms/index.html |
||
< |
<syntaxhighlight lang="forth">include FMS-SI.f |
||
:class point |
:class point |
||
Line 1,625: | Line 1,625: | ||
.. c1.radius ? \ print just radius |
.. c1.radius ? \ print just radius |
||
p1 get .. c1.center put \ change just center using a point |
p1 get .. c1.center put \ change just center using a point |
||
100 .. c1.radius ! \ change just radius </ |
100 .. c1.radius ! \ change just radius </syntaxhighlight> |
||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
Fortran provides OO features with the type mechanism. This example works with the Intel 11.1.069 compiler. |
Fortran provides OO features with the type mechanism. This example works with the Intel 11.1.069 compiler. |
||
< |
<syntaxhighlight lang="fortran"> |
||
module geom |
module geom |
||
Line 1,760: | Line 1,760: | ||
end program inh |
end program inh |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">package main |
||
import "fmt" |
import "fmt" |
||
Line 1,843: | Line 1,843: | ||
} |
} |
||
// Destructors are never used in Go. Objects are garbage collected.</ |
// Destructors are never used in Go. Objects are garbage collected.</syntaxhighlight> |
||
=={{header|Golo}}== |
=={{header|Golo}}== |
||
< |
<syntaxhighlight lang="golo">#!/usr/bin/env golosh |
||
---- |
---- |
||
This module demonstrates Golo's version of polymorphism. |
This module demonstrates Golo's version of polymorphism. |
||
Line 1,918: | Line 1,918: | ||
shape: print() |
shape: print() |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Groovy}}== |
=={{header|Groovy}}== |
||
< |
<syntaxhighlight lang="groovy">@Canonical |
||
@TupleConstructor(force = true) |
@TupleConstructor(force = true) |
||
@ToString(includeNames = true) |
@ToString(includeNames = true) |
||
Line 1,938: | Line 1,938: | ||
void print() { println toString() } |
void print() { println toString() } |
||
Number r |
Number r |
||
}</ |
}</syntaxhighlight> |
||
Test Code: |
Test Code: |
||
< |
<syntaxhighlight lang="groovy">def p = new Point(x: 3, y: 4) |
||
def c = new Circle(x: 4, y: 3, r: 5) |
def c = new Circle(x: 4, y: 3, r: 5) |
||
Line 1,947: | Line 1,947: | ||
v2.print() |
v2.print() |
||
assert v1 == v2 |
assert v1 == v2 |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Verifying Point(x:3, y:4) == Point(x:3, y:4) |
<pre>Verifying Point(x:3, y:4) == Point(x:3, y:4) |
||
Line 1,955: | Line 1,955: | ||
Polymorphism is achieved through the type class Show |
Polymorphism is achieved through the type class Show |
||
< |
<syntaxhighlight lang="haskell">data Point = Point Integer Integer |
||
instance Show Point where |
instance Show Point where |
||
show (Point x y) = "Point at "++(show x)++","++(show y) |
show (Point x y) = "Point at "++(show x)++","++(show y) |
||
Line 1,985: | Line 1,985: | ||
--Constructor that sets x and r to 0 |
--Constructor that sets x and r to 0 |
||
c0OnYAxis = flip (Circle 0) 0</ |
c0OnYAxis = flip (Circle 0) 0</syntaxhighlight> |
||
== Icon and {{header|Unicon}} == |
== Icon and {{header|Unicon}} == |
||
Line 1,993: | Line 1,993: | ||
There is no destructor, as Unicon manages object destruction itself. The copy constructor is emulated by a method. Notice the 'initially' clauses. These act like constructors, in that they accept input parameters during instance construction. These parameters are null if not used, and so the initial field values are set to 0 if the entered value is null (tested using the '/' symbol). |
There is no destructor, as Unicon manages object destruction itself. The copy constructor is emulated by a method. Notice the 'initially' clauses. These act like constructors, in that they accept input parameters during instance construction. These parameters are null if not used, and so the initial field values are set to 0 if the entered value is null (tested using the '/' symbol). |
||
< |
<syntaxhighlight lang="unicon">class Circle (x, y, r) |
||
# make a new copy of this instance |
# make a new copy of this instance |
||
method copy () |
method copy () |
||
Line 2,056: | Line 2,056: | ||
c4.print () |
c4.print () |
||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Inform 7}}== |
=={{header|Inform 7}}== |
||
Line 2,062: | Line 2,062: | ||
Accessors are not needed since property values are public. Constructors and destructors are not needed since objects are statically allocated and initialized. |
Accessors are not needed since property values are public. Constructors and destructors are not needed since objects are statically allocated and initialized. |
||
< |
<syntaxhighlight lang="inform7">Space is a room. |
||
A point is a kind of thing. |
A point is a kind of thing. |
||
Line 2,080: | Line 2,080: | ||
print the origin; |
print the origin; |
||
print the circle of power; |
print the circle of power; |
||
end the story.</ |
end the story.</syntaxhighlight> |
||
=={{header|J}}== |
=={{header|J}}== |
||
< |
<syntaxhighlight lang="j">coclass 'Point' |
||
create=: monad define |
create=: monad define |
||
'X Y'=:2{.y |
'X Y'=:2{.y |
||
Line 2,095: | Line 2,095: | ||
smoutput 'Point ',":X,Y |
smoutput 'Point ',":X,Y |
||
) |
) |
||
destroy=: codestroy</ |
destroy=: codestroy</syntaxhighlight> |
||
< |
<syntaxhighlight lang="j">coclass 'Circle' |
||
coinsert 'Point' |
coinsert 'Point' |
||
create=: monad define |
create=: monad define |
||
Line 2,106: | Line 2,106: | ||
print=: monad define |
print=: monad define |
||
smoutput 'Circle ',":X,Y,R |
smoutput 'Circle ',":X,Y,R |
||
)</ |
)</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
< |
<syntaxhighlight lang="java">class Point { |
||
protected int x, y; |
protected int x, y; |
||
public Point() { this(0); } |
public Point() { this(0); } |
||
Line 2,144: | Line 2,144: | ||
c.print(); |
c.print(); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
< |
<syntaxhighlight lang="javascript">/* create new Point in one of these ways: |
||
* var p = new Point(x,y); |
* var p = new Point(x,y); |
||
* var p = new Point(a_point); |
* var p = new Point(a_point); |
||
Line 2,209: | Line 2,209: | ||
var out = "Circle(" + this.x + "," + this.y + "," + this.r + ")"; |
var out = "Circle(" + this.x + "," + this.y + "," + this.r + ")"; |
||
print(out); |
print(out); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|jq}}== |
=={{header|jq}}== |
||
<syntaxhighlight lang="jq"> |
|||
<lang jq> |
|||
def Point(x;y): {"type": "Point", "x": x, "y": y}; |
def Point(x;y): {"type": "Point", "x": x, "y": y}; |
||
def Point(x): Point(x;0); |
def Point(x): Point(x;0); |
||
Line 2,228: | Line 2,228: | ||
else empty |
else empty |
||
end; |
end; |
||
</syntaxhighlight> |
|||
</lang> |
|||
In practice, it's unlikely one would want to write accessors, as .x will retrieve "x", etc; similar remarks apply to setters (.x = VALUE). `.` will copy, and `empty` could serve as a kind of destructor, in that `Point(0;0) | empty` produces the empty stream. |
In practice, it's unlikely one would want to write accessors, as .x will retrieve "x", etc; similar remarks apply to setters (.x = VALUE). `.` will copy, and `empty` could serve as a kind of destructor, in that `Point(0;0) | empty` produces the empty stream. |
||
Line 2,234: | Line 2,234: | ||
For the sake of illustration, one could define a polymorphic "setter" as follows: |
For the sake of illustration, one could define a polymorphic "setter" as follows: |
||
<syntaxhighlight lang="jq"> |
|||
<lang jq> |
|||
# keyname should be (or evaluate to) a string |
# keyname should be (or evaluate to) a string |
||
def set(keyname; value): |
def set(keyname; value): |
||
Line 2,240: | Line 2,240: | ||
else error("set: invalid type: \(.)") |
else error("set: invalid type: \(.)") |
||
end; |
end; |
||
</syntaxhighlight> |
|||
</lang> |
|||
Example: |
Example: |
||
< |
<syntaxhighlight lang="julia"> |
||
Circle(0;1;2) | .x = 1 | print |
Circle(0;1;2) | .x = 1 | print |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
Line 2,252: | Line 2,252: | ||
{{works with|Julia|0.6}} |
{{works with|Julia|0.6}} |
||
< |
<syntaxhighlight lang="julia">mutable struct Point |
||
x::Float64 |
x::Float64 |
||
y::Float64 |
y::Float64 |
||
Line 2,279: | Line 2,279: | ||
setr(c::Circle, r) = (c.r = r) |
setr(c::Circle, r) = (c.r = r) |
||
Base.show(io::IO, c::Circle) = print(io, "Circle($(c.x), $(c.y), $(c.r))")</ |
Base.show(io::IO, c::Circle) = print(io, "Circle($(c.x), $(c.y), $(c.r))")</syntaxhighlight> |
||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
Line 2,289: | Line 2,289: | ||
In the JVM version of Kotlin, it is possible to declare a destructor in the guise of a 'finalize' method though there is no guarantee that this will actually be called by the garbage collector (or, if it is called, when this will be) and consequently many programmers feel it is more trouble than its worth. |
In the JVM version of Kotlin, it is possible to declare a destructor in the guise of a 'finalize' method though there is no guarantee that this will actually be called by the garbage collector (or, if it is called, when this will be) and consequently many programmers feel it is more trouble than its worth. |
||
< |
<syntaxhighlight lang="scala">// version 1.1.2 |
||
open class Point(var x: Int, var y: Int) { |
open class Point(var x: Int, var y: Int) { |
||
Line 2,344: | Line 2,344: | ||
c.print() // change radius |
c.print() // change radius |
||
/* note that finalizers for p and c are not called */ |
/* note that finalizers for p and c are not called */ |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,378: | Line 2,378: | ||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
Lua does not have a standard definition of objects or classes, so a basic and typical protoctype-based OOP model will be used. In Lua all objects are tables, and through the use of metatables, polymorphism can be achieved in many ways, this is only one of them. |
Lua does not have a standard definition of objects or classes, so a basic and typical protoctype-based OOP model will be used. In Lua all objects are tables, and through the use of metatables, polymorphism can be achieved in many ways, this is only one of them. |
||
< |
<syntaxhighlight lang="lua">-- Point |
||
local Point = {x = 0, y = 0} |
local Point = {x = 0, y = 0} |
||
Line 2,406: | Line 2,406: | ||
function Circle:copy() |
function Circle:copy() |
||
return Circle:new{x = self.x, y = self.y, r = self.r} |
return Circle:new{x = self.x, y = self.y, r = self.r} |
||
end</ |
end</syntaxhighlight> |
||
=={{header|M2000 Interpreter}}== |
=={{header|M2000 Interpreter}}== |
||
Line 2,425: | Line 2,425: | ||
In following examples there is a block for temporary objects. We make a MM as a group, and at the exit of the block, group erased, so next time we make a new one. |
In following examples there is a block for temporary objects. We make a MM as a group, and at the exit of the block, group erased, so next time we make a new one. |
||
Syntax: |
Syntax: |
||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
\\ block For This {}, or For object [, object2] { }, where object is a group, or a pointer to group, or an item from an array contains a group |
\\ block For This {}, or For object [, object2] { }, where object is a group, or a pointer to group, or an item from an array contains a group |
||
\\ This is "this context". |
\\ This is "this context". |
||
Line 2,432: | Line 2,432: | ||
\\ can be nested, but if we use object then we can use dots to access members of it. If we use a second one then we have to use double dots (..x for second object, for access to x member) |
\\ can be nested, but if we use object then we can use dots to access members of it. If we use a second one then we have to use double dots (..x for second object, for access to x member) |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
Class PointA { |
Class PointA { |
||
Property x=0~ |
Property x=0~ |
||
Line 2,514: | Line 2,514: | ||
rA.Print |
rA.Print |
||
</syntaxhighlight> |
|||
</lang> |
|||
Changes for PointA, we use variables, for Circle R has a limit of 1000. We use Stack object, and Inventory for copies of named groups, they changed to float groups. |
Changes for PointA, we use variables, for Circle R has a limit of 1000. We use Stack object, and Inventory for copies of named groups, they changed to float groups. |
||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
Class PointA { |
Class PointA { |
||
X=0~, Y=0~ |
X=0~, Y=0~ |
||
Line 2,586: | Line 2,586: | ||
NN(3).Print |
NN(3).Print |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|NetRexx}}== |
=={{header|NetRexx}}== |
||
'''Note:''' Based on default values in method prototypes, NetRexx will automatically generate intermediate constructors and methods, thus ensuring that none are omitted. |
'''Note:''' Based on default values in method prototypes, NetRexx will automatically generate intermediate constructors and methods, thus ensuring that none are omitted. |
||
< |
<syntaxhighlight lang="netrexx">/* NetRexx */ |
||
options replace format comments java crossref savelog symbols binary |
options replace format comments java crossref savelog symbols binary |
||
Line 2,694: | Line 2,694: | ||
Rexx(getR()).format(null, 3)')' |
Rexx(getR()).format(null, 3)')' |
||
return str |
return str |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,712: | Line 2,712: | ||
Similar to the Python solution: |
Similar to the Python solution: |
||
< |
<syntaxhighlight lang="nim">type |
||
Point = object |
Point = object |
||
x, y: float |
x, y: float |
||
Line 2,746: | Line 2,746: | ||
c1.center.x = 12 |
c1.center.x = 12 |
||
c1.radius = 5.2</ |
c1.radius = 5.2</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>p1: (x: 0.0, y: 0.0) |
<pre>p1: (x: 0.0, y: 0.0) |
||
Line 2,752: | Line 2,752: | ||
=={{header|Objeck}}== |
=={{header|Objeck}}== |
||
< |
<syntaxhighlight lang="objeck"> |
||
bundle Default { |
bundle Default { |
||
class Point { |
class Point { |
||
Line 2,835: | Line 2,835: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Objective-C}}== |
=={{header|Objective-C}}== |
||
< |
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h> |
||
@interface RCPoint : NSObject { |
@interface RCPoint : NSObject { |
||
Line 2,910: | Line 2,910: | ||
} |
} |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
< |
<syntaxhighlight lang="ocaml">class point ?(x=0.0) ?(y=0.0) () = (* extra () used to erase the optional parameters *) |
||
object (self) |
object (self) |
||
val mutable x = x |
val mutable x = x |
||
Line 2,945: | Line 2,945: | ||
c#set_x 10.0; |
c#set_x 10.0; |
||
print c; |
print c; |
||
print (new point ~y:2.1 ())</ |
print (new point ~y:2.1 ())</syntaxhighlight> |
||
=={{header|Oforth}}== |
=={{header|Oforth}}== |
||
Line 2,963: | Line 2,963: | ||
< |
<syntaxhighlight lang="oforth">Object Class new: Point(x, y) |
||
Point method: initialize(x, y) x := x y := y ; |
Point method: initialize(x, y) x := x y := y ; |
||
Point method: _x @x ; |
Point method: _x @x ; |
||
Line 2,976: | Line 2,976: | ||
Circle method: << "(" << @x << ", " << @y << ", " << @r << ")" << ; |
Circle method: << "(" << @x << ", " << @y << ", " << @r << ")" << ; |
||
Circle classMethod: newFromPoint(aPoint, r) self new(aPoint _x, aPoint _y, r) ;</ |
Circle classMethod: newFromPoint(aPoint, r) self new(aPoint _x, aPoint _y, r) ;</syntaxhighlight> |
||
Usage : |
Usage : |
||
< |
<syntaxhighlight lang="oforth">: testPoly |
||
| p c | |
| p c | |
||
Point new(3, 4) ->p |
Point new(3, 4) ->p |
||
Line 2,987: | Line 2,987: | ||
c println |
c println |
||
System.Out "Attributes of this circle are : " << c _x << ", " << c _y << " and " << c _r << cr |
System.Out "Attributes of this circle are : " << c _x << ", " << c _y << " and " << c _r << cr |
||
Circle newFromPoint(p, 2) println ;</ |
Circle newFromPoint(p, 2) println ;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,001: | Line 3,001: | ||
ooRexx supports traditional class-based polymorphism. The polymorphic methods can be part of the main class sequence or brought in using mixins for multiple inheritance situations. Here is a simple example using point and circle classes in a hierarchy. |
ooRexx supports traditional class-based polymorphism. The polymorphic methods can be part of the main class sequence or brought in using mixins for multiple inheritance situations. Here is a simple example using point and circle classes in a hierarchy. |
||
<syntaxhighlight lang="oorexx"> |
|||
<lang ooRexx> |
|||
p = .point~new(3,2) |
p = .point~new(3,2) |
||
c = .circle~new(,2,6) |
c = .circle~new(,2,6) |
||
Line 3,032: | Line 3,032: | ||
say "A circle of radius" radius "centered at location ("||self~x","self~y")" |
say "A circle of radius" radius "centered at location ("||self~x","self~y")" |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,042: | Line 3,042: | ||
Method binding in ooRexx is late and dynamic. In many situations, polymorphism can be achieved merely by providing an expected method. It is not necessary for an object to be of a particular class hierarchy. In the example below, both point and circle implement a print method, but there is no class relationship between these classes other than what they inherit from the object class. |
Method binding in ooRexx is late and dynamic. In many situations, polymorphism can be achieved merely by providing an expected method. It is not necessary for an object to be of a particular class hierarchy. In the example below, both point and circle implement a print method, but there is no class relationship between these classes other than what they inherit from the object class. |
||
<syntaxhighlight lang="oorexx"> |
|||
<lang ooRexx> |
|||
p = .point~new(3,2) |
p = .point~new(3,2) |
||
c = .circle~new(,2,6) |
c = .circle~new(,2,6) |
||
Line 3,074: | Line 3,074: | ||
say "A circle of radius" radius "centered at location ("||x","y")" |
say "A circle of radius" radius "centered at location ("||x","y")" |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,087: | Line 3,087: | ||
A compact format for the methods is used to improve layout. |
A compact format for the methods is used to improve layout. |
||
< |
<syntaxhighlight lang="oxygenbasic"> |
||
type tpoint float xx,yy |
type tpoint float xx,yy |
||
type tcircle float xx,yy,rr |
type tcircle float xx,yy,rr |
||
Line 3,144: | Line 3,144: | ||
del ca : del cb : del cc |
del ca : del cb : del cc |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
Line 3,150: | Line 3,150: | ||
No accessors because we use immutable public attributes ("features"). |
No accessors because we use immutable public attributes ("features"). |
||
< |
<syntaxhighlight lang="oz">class Point |
||
feat |
feat |
||
x |
x |
||
Line 3,187: | Line 3,187: | ||
")"} |
")"} |
||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
Line 3,194: | Line 3,194: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
What polymorphic function means in the context of Perl is as clear as mud. subs already can take anything as parameter by default. Destructors are automatic, so I dropped them. |
What polymorphic function means in the context of Perl is as clear as mud. subs already can take anything as parameter by default. Destructors are automatic, so I dropped them. |
||
< |
<syntaxhighlight lang="perl">{ |
||
package Point; |
package Point; |
||
use Class::Spiffy -base; |
use Class::Spiffy -base; |
||
Line 3,279: | Line 3,279: | ||
my $c = Circle->new(r => 4); |
my $c = Circle->new(r => 4); |
||
print $c->r, "\n"; # accessor autogenerated |
print $c->r, "\n"; # accessor autogenerated |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Line 3,289: | Line 3,289: | ||
There are no private members here; for that I would write something that returns integer ids to the outside world. |
There are no private members here; for that I would write something that returns integer ids to the outside world. |
||
<!--< |
<!--<syntaxhighlight lang="phix">--> |
||
<span style="color: #008080;">type</span> <span style="color: #000000;">point</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">o</span><span style="color: #0000FF;">)</span> |
<span style="color: #008080;">type</span> <span style="color: #000000;">point</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">o</span><span style="color: #0000FF;">)</span> |
||
<span style="color: #008080;">return</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">2</span> <span style="color: #008080;">and</span> <span style="color: #004080;">atom</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">and</span> <span style="color: #004080;">atom</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])</span> |
<span style="color: #008080;">return</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">2</span> <span style="color: #008080;">and</span> <span style="color: #004080;">atom</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">and</span> <span style="color: #004080;">atom</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])</span> |
||
Line 3,316: | Line 3,316: | ||
<span style="color: #0000FF;">?</span><span style="color: #000000;">c1</span> |
<span style="color: #0000FF;">?</span><span style="color: #000000;">c1</span> |
||
<span style="color: #0000FF;">?</span><span style="color: #000000;">c2</span> |
<span style="color: #0000FF;">?</span><span style="color: #000000;">c2</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
Line 3,330: | Line 3,330: | ||
{{libheader|Phix/Class}} |
{{libheader|Phix/Class}} |
||
<!--< |
<!--<syntaxhighlight lang="phix">--> |
||
<span style="color: #008080;">class</span> <span style="color: #000000;">Point</span> |
<span style="color: #008080;">class</span> <span style="color: #000000;">Point</span> |
||
<span style="color: #004080;">atom</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span> |
<span style="color: #004080;">atom</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span> |
||
Line 3,390: | Line 3,390: | ||
<span style="color: #000000;">c2</span><span style="color: #0000FF;">.</span><span style="color: #000000;">show</span><span style="color: #0000FF;">()</span> |
<span style="color: #000000;">c2</span><span style="color: #0000FF;">.</span><span style="color: #000000;">show</span><span style="color: #0000FF;">()</span> |
||
<span style="color: #000000;">c3</span><span style="color: #0000FF;">.</span><span style="color: #000000;">show</span><span style="color: #0000FF;">()</span> |
<span style="color: #000000;">c3</span><span style="color: #0000FF;">.</span><span style="color: #000000;">show</span><span style="color: #0000FF;">()</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
Line 3,406: | Line 3,406: | ||
Point class definition. |
Point class definition. |
||
<syntaxhighlight lang="php"> |
|||
<lang PHP> |
|||
class Point |
class Point |
||
{ |
{ |
||
Line 3,478: | Line 3,478: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Circle class definition. |
Circle class definition. |
||
<syntaxhighlight lang="php"> |
|||
<lang PHP> |
|||
class Circle extends Point |
class Circle extends Point |
||
{ |
{ |
||
Line 3,546: | Line 3,546: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Usage: |
Usage: |
||
<syntaxhighlight lang="php"> |
|||
<lang PHP> |
|||
$point = new Point( 1, 5 ); |
$point = new Point( 1, 5 ); |
||
$circle = new Circle( 1, 5, 6 ); |
$circle = new Circle( 1, 5, 6 ); |
||
Line 3,563: | Line 3,563: | ||
// or |
// or |
||
echo $circle; |
echo $circle; |
||
</syntaxhighlight> |
|||
</lang> |
|||
Will result in: |
Will result in: |
||
Line 3,571: | Line 3,571: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang="picolisp">(class +Point) |
||
# x y |
# x y |
||
Line 3,589: | Line 3,589: | ||
(dm print> () |
(dm print> () |
||
(prinl "Circle " (: x) "," (: y) "," (: r)) )</ |
(prinl "Circle " (: x) "," (: y) "," (: r)) )</syntaxhighlight> |
||
< |
<syntaxhighlight lang="picolisp">(setq |
||
P (new '(+Point) 3 4) |
P (new '(+Point) 3 4) |
||
C (new '(+Circle) 10 10 5) ) |
C (new '(+Circle) 10 10 5) ) |
||
(print> P) |
(print> P) |
||
(print> C)</ |
(print> C)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Point 3,4 |
<pre>Point 3,4 |
||
Line 3,604: | Line 3,604: | ||
So it is enough to define classes and the print method. |
So it is enough to define classes and the print method. |
||
< |
<syntaxhighlight lang="pop11">uses objectclass; |
||
define :class Point; |
define :class Point; |
||
slot x = 0; |
slot x = 0; |
||
Line 3,622: | Line 3,622: | ||
define :method print(p : Circle); |
define :method print(p : Circle); |
||
printf('Circle(' >< x(p) >< ', ' >< y(p) >< ', ' >< r(p) >< ')\n'); |
printf('Circle(' >< x(p) >< ', ' >< y(p) >< ', ' >< r(p) >< ')\n'); |
||
enddefine;</ |
enddefine;</syntaxhighlight> |
||
To test we can use the following code: |
To test we can use the following code: |
||
< |
<syntaxhighlight lang="pop11">;;; Initialize variables using default constructors |
||
lvars instance1 = newPoint(); |
lvars instance1 = newPoint(); |
||
lvars instance2 = newCircle(); |
lvars instance2 = newCircle(); |
||
;;; Use print method |
;;; Use print method |
||
print(instance1); |
print(instance1); |
||
print(instance2);</ |
print(instance2);</syntaxhighlight> |
||
=={{header|Prolog}}== |
=={{header|Prolog}}== |
||
Line 3,639: | Line 3,639: | ||
The Copy constructor, assignment and destructor operations are not needed as terms can be copied and assigned using unification as part of the language. |
The Copy constructor, assignment and destructor operations are not needed as terms can be copied and assigned using unification as part of the language. |
||
< |
<syntaxhighlight lang="prolog">% Point |
||
point_construct(X, Y, point(X1,Y1)) :- |
point_construct(X, Y, point(X1,Y1)) :- |
||
default(X, X1), |
default(X, X1), |
||
Line 3,681: | Line 3,681: | ||
Y1 is Y * 2, |
Y1 is Y * 2, |
||
shape_x_y_set(T, X1, Y1, T1), |
shape_x_y_set(T, X1, Y1, T1), |
||
print_shape(T1).</ |
print_shape(T1).</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,694: | Line 3,694: | ||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
Using the open-source precompiler [http://www.development-lounge.de/viewtopic.php?t=5915 SimlpeOOP]. |
Using the open-source precompiler [http://www.development-lounge.de/viewtopic.php?t=5915 SimlpeOOP]. |
||
< |
<syntaxhighlight lang="purebasic">Class MyPoint |
||
BeginProtect |
BeginProtect |
||
Line 3,752: | Line 3,752: | ||
EndMethod |
EndMethod |
||
EndClass</ |
EndClass</syntaxhighlight> |
||
Testcode |
Testcode |
||
< |
<syntaxhighlight lang="purebasic">*point.MyPoint = NewObject.MyPoint |
||
*circle.Circle = NewObject.Circle |
*circle.Circle = NewObject.Circle |
||
Line 3,762: | Line 3,762: | ||
*circle\Print() |
*circle\Print() |
||
CloseConsole() |
CloseConsole() |
||
EndIf</ |
EndIf</syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
Line 3,770: | Line 3,770: | ||
For the print function, use the standard __repr__ methods, used when printing an object. Destructors are not needed of course. |
For the print function, use the standard __repr__ methods, used when printing an object. Destructors are not needed of course. |
||
< |
<syntaxhighlight lang="python">class Point(object): |
||
def __init__(self, x=0.0, y=0.0): |
def __init__(self, x=0.0, y=0.0): |
||
self.x = x |
self.x = x |
||
Line 3,783: | Line 3,783: | ||
def __repr__(self): |
def __repr__(self): |
||
return '<Circle 0x%x x: %f y: %f radius: %f>' % ( |
return '<Circle 0x%x x: %f y: %f radius: %f>' % ( |
||
id(self), self.center.x, self.center.y, self.radius)</ |
id(self), self.center.x, self.center.y, self.radius)</syntaxhighlight> |
||
Usage example: |
Usage example: |
||
Line 3,822: | Line 3,822: | ||
Or, using inheritance like some of the other solutions: |
Or, using inheritance like some of the other solutions: |
||
< |
<syntaxhighlight lang="python">class Point(object): |
||
def __init__(self, x=0.0, y=0.0): |
def __init__(self, x=0.0, y=0.0): |
||
self.x = x |
self.x = x |
||
Line 3,835: | Line 3,835: | ||
def __repr__(self): |
def __repr__(self): |
||
return '<Circle 0x%x x: %f y: %f radius: %f>' % ( |
return '<Circle 0x%x x: %f y: %f radius: %f>' % ( |
||
id(self), self.x, self.y, self.radius)</ |
id(self), self.x, self.y, self.radius)</syntaxhighlight> |
||
Usage example: |
Usage example: |
||
Line 3,876: | Line 3,876: | ||
The task calls for the creation of mutable types i.e. that you are allowed to change the values of x, y, or r of a Point or Circle after they have been created. |
The task calls for the creation of mutable types i.e. that you are allowed to change the values of x, y, or r of a Point or Circle after they have been created. |
||
If this is not needed, then the Python namedtuple is a good way to create immutable classes with named fields such as these. |
If this is not needed, then the Python namedtuple is a good way to create immutable classes with named fields such as these. |
||
< |
<syntaxhighlight lang="python">>>> from collections import namedtuple |
||
>>> class Point(namedtuple('Point', 'x y')): |
>>> class Point(namedtuple('Point', 'x y')): |
||
def __new__( _cls, x=0, y=0 ): |
def __new__( _cls, x=0, y=0 ): |
||
Line 3,899: | Line 3,899: | ||
p.x = 10.81 |
p.x = 10.81 |
||
AttributeError: can't set attribute |
AttributeError: can't set attribute |
||
>>> </ |
>>> </syntaxhighlight> |
||
And if you don't need default arguments, this becomes: |
And if you don't need default arguments, this becomes: |
||
< |
<syntaxhighlight lang="python">>>> Point = namedtuple('Point', 'x y') |
||
>>> Circle = namedtuple('Circle', 'x y r') |
>>> Circle = namedtuple('Circle', 'x y r') |
||
>>> Point(3, 4) |
>>> Point(3, 4) |
||
Line 3,908: | Line 3,908: | ||
>>> Circle(x=1, y=2, r=3) |
>>> Circle(x=1, y=2, r=3) |
||
Circle(x=1, y=2, r=3) |
Circle(x=1, y=2, r=3) |
||
>>> </ |
>>> </syntaxhighlight> |
||
=={{header|R}}== |
=={{header|R}}== |
||
Line 3,914: | Line 3,914: | ||
Copy constructors are not needed, since objects are copied by value. |
Copy constructors are not needed, since objects are copied by value. |
||
Neither are destructors needed (just use the rm function). |
Neither are destructors needed (just use the rm function). |
||
< |
<syntaxhighlight lang="r">setClass("point", |
||
representation( |
representation( |
||
x="numeric", |
x="numeric", |
||
Line 3,952: | Line 3,952: | ||
cat("This is a circle, with radius", x@r, "and centre (", x@centre@x, ",", x@centre@y, ").\n") |
cat("This is a circle, with radius", x@r, "and centre (", x@centre@x, ",", x@centre@y, ").\n") |
||
}) |
}) |
||
print(circS4)</ |
print(circS4)</syntaxhighlight> |
||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
Line 3,958: | Line 3,958: | ||
"Fields" come with accessors and mutators for free. |
"Fields" come with accessors and mutators for free. |
||
<syntaxhighlight lang="racket"> |
|||
<lang Racket> |
|||
#lang racket |
#lang racket |
||
(define point% |
(define point% |
||
Line 3,973: | Line 3,973: | ||
(define/override (custom-write out) (write (show) out)) |
(define/override (custom-write out) (write (show) out)) |
||
(define/override (custom-display out) (display (show) out)))) |
(define/override (custom-display out) (display (show) out)))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,998: | Line 3,998: | ||
To create only readonly accessors for better encapsulation, leave out all the "is rw" traits. |
To create only readonly accessors for better encapsulation, leave out all the "is rw" traits. |
||
Here we demonstrate that accessors can behave like variables and may be assigned. |
Here we demonstrate that accessors can behave like variables and may be assigned. |
||
<lang |
<syntaxhighlight lang="raku" line>class Point { |
||
has Real $.x is rw = 0; |
has Real $.x is rw = 0; |
||
has Real $.y is rw = 0; |
has Real $.y is rw = 0; |
||
Line 4,015: | Line 4,015: | ||
$c.p.y = (-10..10).pick; |
$c.p.y = (-10..10).pick; |
||
$c.r = (0..10).pick; |
$c.r = (0..10).pick; |
||
say $c;</ |
say $c;</syntaxhighlight> |
||
In this case we define the Str coercion method polymorphically, which is used by say or print to format the contents of the object. |
In this case we define the Str coercion method polymorphically, which is used by say or print to format the contents of the object. |
||
We could also have defined print methods directly. |
We could also have defined print methods directly. |
||
We could have factored this method out to a common role and composed it into each class. |
We could have factored this method out to a common role and composed it into each class. |
||
We could also have defined multi subs outside of the class, like this: |
We could also have defined multi subs outside of the class, like this: |
||
<lang |
<syntaxhighlight lang="raku" line>multi print (Point $p) { $p.perl.print } |
||
multi print (Circle $c) { $c.perl.print }</ |
multi print (Circle $c) { $c.perl.print }</syntaxhighlight> |
||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
Line 4,028: | Line 4,028: | ||
The <tt>Kernel#dup</tt> method can be used as a copy constructor. |
The <tt>Kernel#dup</tt> method can be used as a copy constructor. |
||
< |
<syntaxhighlight lang="ruby">class Point |
||
attr_accessor :x,:y |
attr_accessor :x,:y |
||
def initialize(x=0, y=0) |
def initialize(x=0, y=0) |
||
Line 4,050: | Line 4,050: | ||
"Circle at #{x},#{y} with radius #{r}" |
"Circle at #{x},#{y} with radius #{r}" |
||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
Example: |
Example: |
||
< |
<syntaxhighlight lang="ruby"># create a point |
||
puts Point.new # => Point at 0,0 |
puts Point.new # => Point at 0,0 |
||
p = Point.new(1, 2) |
p = Point.new(1, 2) |
||
Line 4,066: | Line 4,066: | ||
d.r = 7.5 |
d.r = 7.5 |
||
puts c # => Circle at 4,5 with radius 6 |
puts c # => Circle at 4,5 with radius 6 |
||
puts d # => Circle at 4,5 with radius 7.5</ |
puts d # => Circle at 4,5 with radius 7.5</syntaxhighlight> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/altUDTl/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/ohfeM4nvTZyeOTYYWHaNgQ Scastie (remote JVM)]. |
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/altUDTl/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/ohfeM4nvTZyeOTYYWHaNgQ Scastie (remote JVM)]. |
||
< |
<syntaxhighlight lang="scala">object PointCircle extends App { |
||
class Point(x: Int = 0, y: Int = 0) { |
class Point(x: Int = 0, y: Int = 0) { |
||
Line 4,105: | Line 4,105: | ||
println(e, " changed radius") |
println(e, " changed radius") |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Seed7}}== |
=={{header|Seed7}}== |
||
Line 4,114: | Line 4,114: | ||
Note that a Seed7 constructor does not need to have the name of the type (a new Point could be created with a function called abc). |
Note that a Seed7 constructor does not need to have the name of the type (a new Point could be created with a function called abc). |
||
Seed7 defines copy constructor, assignment and destructor automatically. |
Seed7 defines copy constructor, assignment and destructor automatically. |
||
< |
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i"; |
||
const type: GraphicObj is new interface; |
const type: GraphicObj is new interface; |
||
Line 4,173: | Line 4,173: | ||
graph := circ; |
graph := circ; |
||
print(graph); |
print(graph); |
||
end func;</ |
end func;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 4,181: | Line 4,181: | ||
We create four named objects, two of which we put in the traits namespace and two in a general prototype namespace. This would normally be done in the UI. |
We create four named objects, two of which we put in the traits namespace and two in a general prototype namespace. This would normally be done in the UI. |
||
< |
<syntaxhighlight lang="self">traits point = (| |
||
parent* = traits clonable. |
parent* = traits clonable. |
||
printString = ('Point(', x asString, ':', y asString, ')'). |
printString = ('Point(', x asString, ':', y asString, ')'). |
||
Line 4,201: | Line 4,201: | ||
center <- point copy. |
center <- point copy. |
||
r <- 0 |
r <- 0 |
||
|)</ |
|)</syntaxhighlight> |
||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
< |
<syntaxhighlight lang="ruby">class Point(x=0, y=0) { |
||
} |
} |
||
Line 4,218: | Line 4,218: | ||
func pp(Circle obj) { |
func pp(Circle obj) { |
||
say "Circle at #{obj.x},#{obj.y} with radius #{obj.r}"; |
say "Circle at #{obj.x},#{obj.y} with radius #{obj.r}"; |
||
}</ |
}</syntaxhighlight> |
||
Example: |
Example: |
||
< |
<syntaxhighlight lang="ruby">pp(Point.new); # => Point at 0,0 |
||
var p = Point(1, 2); # create a point |
var p = Point(1, 2); # create a point |
||
pp(p); # => Point at 1,2 |
pp(p); # => Point at 1,2 |
||
Line 4,232: | Line 4,232: | ||
d.r = 7.5; # and change the radius to 7.5 |
d.r = 7.5; # and change the radius to 7.5 |
||
pp(c); # => Circle at 4,5 with radius 6 |
pp(c); # => Circle at 4,5 with radius 6 |
||
pp(d); # => Circle at 4,5 with radius 7.5</ |
pp(d); # => Circle at 4,5 with radius 7.5</syntaxhighlight> |
||
=={{header|SIMPOL}}== |
=={{header|SIMPOL}}== |
||
Line 4,242: | Line 4,242: | ||
The <code>embed</code> keyword in the type definition states that the type itself can be embedded in another type (any type can be placed as a reference in another type). |
The <code>embed</code> keyword in the type definition states that the type itself can be embedded in another type (any type can be placed as a reference in another type). |
||
< |
<syntaxhighlight lang="simpol">type mypoint(mypoint) embed export |
||
embed |
embed |
||
integer x |
integer x |
||
Line 4,314: | Line 4,314: | ||
result = p.print() + "{d}{a}" + c.print() + "{d}{a}" |
result = p.print() + "{d}{a}" + c.print() + "{d}{a}" |
||
end function result</ |
end function result</syntaxhighlight> |
||
[[SIMPOL]] does not currently have access to stdin, stdout, and stderr, |
[[SIMPOL]] does not currently have access to stdin, stdout, and stderr, |
||
Line 4,322: | Line 4,322: | ||
=={{header|Smalltalk}}== |
=={{header|Smalltalk}}== |
||
Like Python and Ruby, these objects do not need to be related in order to have polymorphic methods. |
Like Python and Ruby, these objects do not need to be related in order to have polymorphic methods. |
||
< |
<syntaxhighlight lang="smalltalk">!Object subclass: #Point |
||
instanceVariableNames: 'x y' |
instanceVariableNames: 'x y' |
||
classVariableNames: '' |
classVariableNames: '' |
||
Line 4,396: | Line 4,396: | ||
!Circle methodsFor: 'polymorphism test'! |
!Circle methodsFor: 'polymorphism test'! |
||
print |
print |
||
Transcript show: center; space; show: radius ! !</ |
Transcript show: center; space; show: radius ! !</syntaxhighlight> |
||
''TODO: more idiomatic mechanism for presenting objects as strings.'' |
''TODO: more idiomatic mechanism for presenting objects as strings.'' |
||
Line 4,402: | Line 4,402: | ||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
< |
<syntaxhighlight lang="swift">class RCPoint : Printable { |
||
var x: Int |
var x: Int |
||
var y: Int |
var y: Int |
||
Line 4,447: | Line 4,447: | ||
println(p.x) // 1 |
println(p.x) // 1 |
||
p.x = 8 |
p.x = 8 |
||
println(p.x) // 8</ |
println(p.x) // 8</syntaxhighlight> |
||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
Line 4,455: | Line 4,455: | ||
We only do so here for convenience. |
We only do so here for convenience. |
||
In addition, Tcl's arguments to commands, procedures and methods are all fully polymorphic by default. |
In addition, Tcl's arguments to commands, procedures and methods are all fully polymorphic by default. |
||
< |
<syntaxhighlight lang="tcl">package require TclOO |
||
oo::class create Point { |
oo::class create Point { |
||
variable X Y |
variable X Y |
||
Line 4,507: | Line 4,507: | ||
foreach o $objects { |
foreach o $objects { |
||
$o print |
$o print |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Wollok}}== |
=={{header|Wollok}}== |
||
< |
<syntaxhighlight lang="wollok"> |
||
class Point { |
class Point { |
||
var x |
var x |
||
Line 4,554: | Line 4,554: | ||
c.print() |
c.print() |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
Line 4,562: | Line 4,562: | ||
The following program uses the same examples as the Kotlin entry. |
The following program uses the same examples as the Kotlin entry. |
||
< |
<syntaxhighlight lang="ecmascript">class Point { |
||
construct new(x, y) { |
construct new(x, y) { |
||
_x = x |
_x = x |
||
Line 4,602: | Line 4,602: | ||
Circle.new(4, 5, 6), Circle.fromCircle(Circle.new(7, 8, 9)) |
Circle.new(4, 5, 6), Circle.fromCircle(Circle.new(7, 8, 9)) |
||
] |
] |
||
for (circle in circles) circle.print()</ |
for (circle in circles) circle.print()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 4,619: | Line 4,619: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
Written for brevity |
Written for brevity |
||
< |
<syntaxhighlight lang="zkl">class Point{var x,y; |
||
fcn init(xyOrPoint=0,_=0){ |
fcn init(xyOrPoint=0,_=0){ |
||
if(Point.isInstanceOf(xyOrPoint)) set(xyOrPoint); |
if(Point.isInstanceOf(xyOrPoint)) set(xyOrPoint); |
||
Line 4,645: | Line 4,645: | ||
c:=Circle(1,2,3); |
c:=Circle(1,2,3); |
||
c.println(); c.center.println(); |
c.println(); c.center.println(); |
||
c.copy().println();</ |
c.copy().println();</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |