Classes

From Rosetta Code
Task
Classes
You are encouraged to solve this task according to the task description, using any language you may know.

In object-oriented programming class is a set (a transitive closure) of types bound by the relation of inheritance. It is said that all types derived from some base type T and the type T itself form a class T. The first type T from the class T sometimes is called the root type of the class.

A class of types itself, as a type, has the values and operations of its own. The operations of are usually called methods of the root type. Both operations and values are called polymorphic.

A polymorphic operation (method) selects an implementation depending on the actual specific type of the polymorphic argument. The action of choice the type-specific implementation of a polymorphic operation is called dispatch. Correspondingly, polymorphic operations are often called dispatching or virtual. Operations with multiple arguments and/or the results of the class are called multi-methods. A further generalization of is the operation with arguments and/or results from different classes.

  • single-dispatch languages are those that allow only one argument or result to control the dispatch. Usually it is the first parameter, often hidden, so that a prefix notation x.f() is used instead of mathematical f(x).
  • multiple-dispatch languages allow many arguments and/or results to control the dispatch.

A polymorphic value has a type tag indicating its specific type from the class and the corresponding specific value of that type. This type is sometimes called the most specific type of a [polymorphic] value. The type tag of the value is used in order to resolve the dispatch. The set of polymorphic values of a class is a transitive closure of the sets of values of all types from that class.

In many OO languages the type of the class of T and T itself are considered equivalent. In some languages they are distinct (like in Ada). When class T and T are equivalent, there is no way to distinguish polymorphic and specific values.

The purpose of this task is to create a basic class with a method, a constructor, an instance variable and how to instantiate it.

ActionScript

<lang actionscript>package {

   public class MyClass {

       private var myVariable:int;  // Note: instance variables are usually "private"

       /**
        * The constructor
        */
       public function MyClass() {
           // creates a new instance
       }

       /**
        * A method
        */
       public function someMethod():void {
           this.myVariable = 1; // Note: "this." is optional
           // myVariable = 1; works also
       }
   }

}</lang>

Ada

Class is used in many languages to provide both encapsulation, or grouping of data and actions, and type definition. Ada packages provide encapsulation or grouping while type definitions are done using the type reserved word. Types participating in inheritance are named tagged record types.

A package specification has the following form: <lang ada>package My_Package is

  type My_Type is tagged private;
  procedure Some_Procedure(Item : out My_Type);
   function Set(Value : in Integer) return My_Type;

private

  type My_Type is tagged record
     Variable : Integer := -12;
  end record;

end My_Package;</lang> The type declaration at the top of the package gives public visibility to the private tagged type My_Type. Since My_Type is declared to be private, the public has no visibility of its structure. The type must be treated as a black box. The private section of the package specification includes the actual tagged record definition. Note that the data member Variable is initialized to -12. This corresponds to a default constructor for the type.

The package body must contain the implementation of the procedures and functions declared in the package specification. <lang ada> package body My_Package is

   procedure Some_Procedure(Item : out My_Type) is
   begin
      Item := 2 * Item;
   end Some_Procedure;

   function Set(Value : Integer) return My_Type is
      Temp : My_Type;
   begin
      Temp.Variable := Value;
      return Temp;
   end Set;

end My_Package;</lang> The Set function acts as a conversion constructor for My_Type.

An instance is typically created outside the package: <lang ada>with My_Package; use My_Package;

procedure Main is

  Foo : My_Type; -- Foo is created and initialized to -12

begin

  Some_Procedure(Foo); -- Foo is doubled
  Foo := Set(2007); -- Foo.Variable is set to 2007

end Main;</lang>

Aikido

Aikido provides classes with single inheritance and multiple interface implementation. A class takes a set of constructor arguments and provides a set of public functions, operators, classes, monitors and threads. <lang aikido>class Circle (radius, x, y) extends Shape (x, y) implements Drawable {

   var myvec = new Vector (x, y)
   public function draw() {
       // draw the circle
   }

}</lang>

ALGOL 68

Translation of: python
Works with: ALGOL 68 version Revision 1 - no extensions to language used
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny

The following code is experimental. Basically ALGOL 68 is not object oriented, so the task to create (and use of) objects is tedious due to the lack of certain constructs, especially the lack of OO syntactic sugar.

For further details:

Other examples of this experimental approach are located at pages: Life in two dimensions, Playing Cards and Stack.

<lang algol68>MODE MYDATA = STRUCT(

   INT name1 

); STRUCT(

   INT name2,
   PROC (REF MYDATA)REF MYDATA new,
   PROC (REF MYDATA)VOID init,
   PROC (REF MYDATA)VOID some method

) class my data; class my data := (

 # name2 := # 2, # Class attribute #

 # PROC new := # (REF MYDATA new)REF MYDATA:(
       (init OF class my data)(new);
       new
  ),
 # PROC init := # (REF MYDATA self)VOID:(
       """ Constructor  (Technically an initializer rather than a true 'constructor') """;
       name1 OF self := 0 # Instance attribute #
   ),

 # PROC some method := # (REF MYDATA self)VOID:(
       """ Method """;
       name1 OF self := 1;
       name2 OF class my data := 3
   )

);

  1. class name, invoked as a function is the constructor syntax #

REF MYDATA my data = (new OF class my data)(LOC MYDATA);

MODE GENDEROPT = UNION(STRING, VOID); MODE AGEOPT = UNION(INT, VOID);

MODE MYOTHERDATA = STRUCT(

   STRING name,
   GENDEROPT gender,
   AGEOPT age

); STRUCT (

   INT count,
   PROC (REF MYOTHERDATA, STRING, GENDEROPT, AGEOPT)REF MYOTHERDATA new,
   PROC (REF MYOTHERDATA, STRING, GENDEROPT, AGEOPT)VOID init,
   PROC (REF MYOTHERDATA)VOID del

) class my other data; class my other data := (

 # count := # 0,  # Population of "(init OF class my other data)" objects #
  1. PROC new := # (REF MYOTHERDATA new, STRING name, GENDEROPT gender, AGEOPT age)REF MYOTHERDATA:(
         (init OF class my other data)(new, name, gender, age);
         new
     ),
 # PROC init := # (REF MYOTHERDATA self, STRING name, GENDEROPT gender, AGEOPT age)VOID:(
       """ One initializer required, others are optional (with different defaults) """;
       count OF class my other data +:= 1;
       name OF self := name;
       gender OF self := gender;
       CASE gender OF self IN
           (VOID):gender OF self := "Male"
       ESAC;
       age OF self := age
   ),
 # PROC del := # (REF MYOTHERDATA self)VOID:(
       count OF class my other data -:= 1
   )

);

PROC attribute error := STRING: error char; # mend the error with the "error char" #

  1. Allocate the instance from HEAP #

REF MYOTHERDATA person1 = (new OF class my other data)(HEAP MYOTHERDATA, "John", EMPTY, EMPTY); print (((name OF person1), ": ",

       (gender OF person1|(STRING gender):gender|attribute error), " "));  # "John Male" #

print (((age OF person1|(INT age):age|attribute error), new line)); # Raises AttributeError exception! #

  1. Allocate the instance from LOC (stack) #

REF MYOTHERDATA person2 = (new OF class my other data)(LOC MYOTHERDATA, "Jane", "Female", 23); print (((name OF person2), ": ",

       (gender OF person2|(STRING gender):gender|attribute error), " "));

print (((age OF person2|(INT age):age|attribute error), new line)) # "Jane Female 23" #</lang> Output:

John: Male *
Jane: Female         +23

AmigaE

<lang amigae>OBJECT a_class

 varA, varP

ENDOBJECT

-> this could be used like a constructor PROC init() OF a_class

 self.varP := 10
 self.varA := 2

ENDPROC

-> the special proc end() is for destructor PROC end() OF a_class -> nothing to do here... ENDPROC

-> a not so useful getter PROC getP() OF a_class IS self.varP

PROC main()

 DEF obj : PTR TO a_class
 NEW obj.init()
 WriteF('\d\n', obj.varA)   -> this can be done, while
                            -> varP can't be accessed directly
 WriteF('\d\n', obj.varP)   -> or
 WriteF('\d\n', obj.getP())
 END obj

ENDPROC</lang>

AutoHotkey

Works with: AutoHotkey_L

AutoHotkey_L is prototype-based. However, for convenience, class-syntax may be used to create a base object. <lang AutoHotkey>obj := new MyClass obj.WhenCreated()

class MyClass {

Instance Variable #1
  time := A_Hour ":" A_Min ":" A_Sec
  
Constructor
  __New() {
     MsgBox, % "Constructing new object of type: " this.__Class
     FormatTime, date, , MM/dd/yyyy
  ; Instance Variable #2
     this.date := date
  }
Method
  WhenCreated() {
     MsgBox, % "Object created at " this.time " on " this.date
  }

}</lang>

BASIC

Works with: QuickBasic version 4.5

<lang basic> DECLARE SUB MyClassDelete (pthis AS MyClass)

 DECLARE SUB MyClassSomeMethod (pthis AS MyClass)
 DECLARE SUB MyClassInit (pthis AS MyClass)
 TYPE MyClass
   Variable AS INTEGER
 END TYPE
 DIM obj AS MyClass
 MyClassInit obj
 MyClassSomeMethod obj
 SUB MyClassInit (pthis AS MyClass)
   pthis.Variable = 0
 END SUB
 SUB MyClassSomeMethod (pthis AS MyClass)
   pthis.Variable = 1
 END SUB</lang>

BBC BASIC

<lang bbcbasic> INSTALL @lib$+"CLASSLIB"

     REM Declare the class:
     DIM MyClass{variable, @constructor, _method}
     DEF MyClass.@constructor MyClass.variable = PI : ENDPROC
     DEF MyClass._method = MyClass.variable ^ 2
     
     REM Register the class:
     PROC_class(MyClass{})
     
     REM Instantiate the class:
     PROC_new(myclass{}, MyClass{})
     
     REM Call the method:
     PRINT FN(myclass._method)
     
     REM Discard the instance:
     PROC_discard(myclass{})</lang>

C

Works with: gcc version 4.0.2

<lang c>typedef struct sMyClass {

 int variable;

} *MyClass;

MyClass MyClass_new() {

 MyClass pthis = malloc( sizeof(struct sMyClass) );
 //memset(pthis, 0, sizeof(struct sMyClass) );
 pthis->variable = 0;
 return pthis;

}

void MyClass_delete(MyClass* pthis) {

 if(pthis && *pthis)
 {
   free(*pthis);
   *pthis = NULL;
 }

}

void MyClass_someMethod(MyClass pthis) {

 pthis->variable = 1;

}

MyClass obj = MyClass_new(); MyClass_someMethod(obj); MyClass_delete(&obj);</lang>

C++

Works with: g++ version 4.0.2

<lang cpp>class MyClass { public:

 void someMethod(); // member function = method
 MyClass(); // constructor

private:

 int variable; // member variable = instance variable

};

// implementation of constructor MyClass::MyClass():

 variable(0)

{

 // here could be more code

}

// implementation of member function void MyClass::someMethod() {

 variable = 1; // alternatively: this->variable = 1

}

// Create an instance as variable MyClass instance;

// Create an instance on free store MyClass* pInstance = new MyClass; // Instances allocated with new must be explicitly destroyed when not needed any more: delete pInstance;</lang>

Note: MyClass instance(); would not define an instance, but declare a function returning an instance. Accidentally declaring functions when object definitions are wanted is a rather common bug in C++.

Functions can also be defined inline:

<lang cpp>class MyClass { public:

 MyClass(): variable(0) {}
 void someMethod() { variable = 1; }

private:

 int variable;

};</lang>

Note that member functions in C++ by default are not polymorphic; if you want a polymorphic member function, you have to mark it as virtual. In that case, you should also add a virtual destructor, even if that is empty. Example:

<lang cpp>class MyClass { public:

 virtual void someMethod(); // this is polymorphic
 virtual ~MyClass(); // destructor

};</lang>

C#

<lang csharp>public class MyClass {

   public MyClass()
   {
   }
   public void SomeMethod()
   {
   }
   private int _variable;
   public int Variable
   {
       get { return _variable; }
       set { _variable = value; }
   }
   public static void Main()
   {
       // instantiate it
       MyClass instance = new MyClass();
       // invoke the method
       instance.SomeMethod();
       // set the variable
       instance.Variable = 99;
       // get the variable
       System.Console.WriteLine( "Variable=" + instance.Variable.ToString() );
   }

}</lang>

COBOL

<lang cobol> IDENTIFICATION DIVISION.

      CLASS-ID. my-class INHERITS base.
      
      *> The 'INHERITS base' and the following ENVIRONMENT DIVISION
      *> are optional (in Visual COBOL).
      ENVIRONMENT DIVISION.
      CONFIGURATION SECTION.
      REPOSITORY.
          CLASS base.
    
          *> There is no way (as far as I can tell) of creating a
          *> constructor. However, you could wrap it with another
          *> method to achieve the desired effect.
          *>...
    
          OBJECT.
              *> Instance data
              DATA DIVISION.
              WORKING-STORAGE SECTION.
              01  instance-variable PIC 9(8).
      
              *> Properties can have getters and setters automatically
              *> generated.
              01  a-property        PIC 9(8) PROPERTY.
              
              PROCEDURE DIVISION.
      
              METHOD-ID. some-method.
              PROCEDURE DIVISION.
                  *> ...
              END METHOD some-method.
          END OBJECT.
      END CLASS my-class.
      
      IDENTIFICATION DIVISION.
      PROGRAM-ID. example-class-use.
      
      ENVIRONMENT DIVISION.
      CONFIGURATION SECTION.
      REPOSITORY.
          *> These declarations brings the class and property into
          *> scope.
          CLASS my-class
          PROPERTY a-property. 
                 
      DATA DIVISION.
      WORKING-STORAGE SECTION.
      *> Declaring a my-class reference variable.
      01  instance USAGE OBJECT REFERENCE my-class.
      
      PROCEDURE DIVISION.
      
          *> Invoking a static method or (in this case) a constructor.
          INVOKE my-class "new" RETURNING instance
          
          *> Invoking an instance method.
          INVOKE instance "some-method"
          *> Using the setter and getter of a-property.
          MOVE 5 TO a-property OF instance
          DISPLAY a-property OF instance
      
          GOBACK
          .
          
      END PROGRAM example-class-use.</lang>

CoffeeScript

<lang coffeescript># Create a basic class class Rectangle

 # Constructor that accepts one argument
 constructor: (@width) ->
 
 # An instance variable
 length: 10
 
 # A method
 area: () ->
   @width * @length
  1. Instantiate the class using the new operator

rect = new Rectangle 2</lang>

Common Lisp

<lang lisp>(defclass circle ()

 ((radius :initarg :radius
          :initform 1.0
          :type number
          :reader radius)))

(defmethod area ((shape circle))

 (* pi (expt (radius shape) 2)))

> (defvar *c* (make-instance 'circle :radius 2)) > (area *c*) 12.566370614359172d0</lang>

Component Pascal

BlackBox Component Builder <lang oberon2> MODULE Graphics; IMPORT StdLog; TYPE (* class *) Point* = POINTER TO LIMITED RECORD x-,y-: INTEGER; (* Instance variables *) END;

(* method *) PROCEDURE (p: Point) Abs*(): INTEGER,NEW; BEGIN RETURN p.x END Abs;

(* method *) PROCEDURE (p: Point) Ord*(): INTEGER,NEW; BEGIN RETURN p.y END Ord;

(* method *) PROCEDURE (p: Point) Show*,NEW; BEGIN StdLog.String("Point(");StdLog.Int(p.x);StdLog.String(","); StdLog.Int(p.y);StdLog.String(");");StdLog.Ln END Show;

(* constructor *) PROCEDURE NewPoint*(x,y: INTEGER): Point; VAR p: Point; BEGIN NEW(p);p.x := x;p.y := y; RETURN p END NewPoint;

PROCEDURE TestPoint*; VAR p: Point; BEGIN p := NewPoint(10,20); p.Show(); StdLog.String("Abs:> ");StdLog.Int(p.Abs());StdLog.Ln; StdLog.String("Ord:> ");StdLog.Int(p.Ord());StdLog.Ln END TestPoint; END Graphics. </lang> Execute: ^Q Graphics.TestPoint
Output:

Point( 10, 20);
Abs:>  10
Ord:>  20

D

<lang d>import std.stdio;

class MyClass {

   //constructor (not necessary if empty)
   this() {}
   void someMethod() {
       variable = 1;
   }
   // getter method
   @property int variable() const {
       return variable_;
   }
   // setter method
   @property int variable(int newVariable) {
       return variable_ = newVariable;
   }
   private int variable_;

}

void main() {

   // On default class instances are allocated on the heap
   // The GC will manage their lifetime
   auto obj = new MyClass();
   // prints 'variable = 0', ints are initialized to 0 by default
   writeln("variable = ", obj.variable);
   // invoke the method
   obj.someMethod();
   // prints 'variable = 1'
   writeln("variable = ", obj.variable);
   // set the variable using setter method
   obj.variable = 99;
   // prints 'variable = 99'
   writeln("variable = ", obj.variable);

}</lang>

Delphi

<lang Delphi>program SampleClass;

{$APPTYPE CONSOLE}

type

 TMyClass = class
 private
   FSomeField: Integer; // by convention, fields are usually private and exposed as properties
 public
   constructor Create;
   destructor Destroy; override;
   procedure SomeMethod;
   property SomeField: Integer read FSomeField write FSomeField;
 end;

constructor TMyClass.Create; begin

 FSomeField := -1

end;

destructor TMyClass.Destroy; begin

 // free resources, etc
 inherited Destroy;

end;

procedure TMyClass.SomeMethod; begin

 // do something

end;


var

 lMyClass: TMyClass;

begin

 lMyClass := TMyClass.Create;
 try
   lMyClass.SomeField := 99;
   lMyClass.SomeMethod();
 finally
   lMyClass.Free;
 end;

end.</lang>

DWScript

Methods can be implemented inline or out-of-line, this sample illustrates both. <lang Delphi>type

 TMyClass = class
 private
   FSomeField: Integer; // by convention, fields are usually private and exposed as properties
 public
   constructor Create;
   begin
      FSomeField := -1;
   end;
   procedure SomeMethod;
   property SomeField: Integer read FSomeField write FSomeField;
 end;

procedure TMyClass.SomeMethod; begin

 // do something

end;


var lMyClass: TMyClass;

lMyClass := new TMyClass; // can also use TMyClass.Create

lMyClass.SomeField := 99; lMyClass.SomeMethod;</lang>

E

In E, classes, constructors, and instance variables are not built into the language. This is an example of the basic convention; different cases may call for objects built in different ways.

<lang e>def makeColor(name :String) {

   def color {
       to colorize(thing :String) {
         return `$name $thing`
       }
   }
   return color

}</lang>

Example interactive session creating and using it:

<lang e>? def red := makeColor("red")

  1. value: <color>

? red.colorize("apple")

  1. value: "red apple"</lang>

Falcon

Falcon classes are a mix of data and code that can be used to instantiate objects. Classes are defined below. Note: inh1...inhN can also be passed the param_list. <lang falcon>class class_name[ ( param_list ) ] [ from inh1[, inh2, ..., inhN] ]

   [ static block ]
   [ properties declaration ]
   [init block]
   [method list]

end</lang> Example of a class: <lang falcon>class mailbox( max_msg )

  capacity = max_msg * 10 
  name = nil
  messages = [] 
 
   init
     printl( "Box now ready for ", self.capacity, " messages." )
   end
 
   function slot_left()
     return  self.capacity - len( self.messages )
   end
 

end</lang>

Instantiation: <lang falcon>m = mailbox( 10 ) // Ouputs: Box now ready for 100 messages.</lang>

Factor

<lang factor>TUPLE: my-class foo bar baz ; M: my-class quux foo>> 20 + ; C: <my-class> my-class 10 20 30 <my-class> quux ! result: 30 TUPLE: my-child-class < my-class quxx ; C: <my-child-class> my-child-class M: my-child-class foobar 20 >>quux ; 20 20 30 <my-child-class> foobar quux ! result: 30</lang>

Fancy

<lang fancy>class MyClass {

 read_slot: 'instance_var # creates getter method for @instance_var
 @@class_var = []
 def initialize {
   # 'initialize' is the constructor method invoked during 'MyClass.new' by convention
   @instance_var = 0
 }
 def some_method {
   @instance_var = 1
   @another_instance_var = "foo"
 }
 # define class methods: define a singleton method on the class object
 def self class_method {
   # ...
 }
 # you can also name the class object itself
 def MyClass class_method {
   # ...
 }

}

myclass = MyClass new</lang>

Fantom

<lang Fantom>class MyClass {

 // an instance variable
 Int x
 
 // a constructor, providing default value for instance variable
 new make (Int x := 1)
 {
   this.x = x
 }
 // a method, return double the number x
 public Int double ()
 {
   return 2 * x
 }

}

class Main {

 public static Void main ()
 {
   a := MyClass (2)  // instantiates the class, with x = 2
   b := MyClass()    // instantiates the class, x defaults to 1
   c := MyClass { x = 3 }  // instantiates the class, sets x to 3
 }

}</lang>

Forth

Works with: Win32Forth

ANSI Forth has no object oriented features, but as Forth is a very easy language to extend, many object oriented programming systems have been implemented for it over the years. WinForth has one such system, which is described here.

Declare a class

<lang forth>:class MyClass <super Object

 int memvar
 :m ClassInit: ( -- )
      ClassInit: super
      1 to memvar ;m
 :m ~: ( -- )  ." Final " show: [ Self ] ;m
 :m set: ( n -- )  to memvar ;m
 :m show: ( -- ) ." Memvar = " memvar . ;m
class</lang>

Allocate a static object <lang forth>MyClass newInstance</lang>

Allocate a dynamic object, saving its pointer in a global variable. <lang forth>New> MyClass value newInstance</lang>

Call member functions <lang forth>10 set: newInstance show: newInstance</lang>

Free a dynamically allocated object

<lang forth>newInstance dispose 0 to newInstance \ no dangling pointers!</lang>

Example of dynamic allocation and local variable use"

<lang forth>: test { \ obj -- }

   New> MyClass to obj
     show: obj
     1000 set: obj
   obj dispose ;</lang>

F#

A minimal example as required by the task description: <lang fsharp>type MyClass(init) = // constructor with one argument: init

 let mutable var = init  // a private instance variable
 member x.Method() =     // a simple method
   var <- var + 1
   printfn "%d" var

// create an instance and use it let myObject = new MyClass(42) myObject.Method()</lang>

A somewhat more meaningful example, inspired by the Haskell version: <lang fsharp>open System

type Shape =

 abstract Perimeter: unit -> float
 abstract Area: unit -> float

type Circle(radius) =

 interface Shape with
   member x.Perimeter() = 2.0 * radius * Math.PI
   member x.Area() = Math.PI * radius**2.0

type Rectangle(width, height) =

 interface Shape with
   member x.Perimeter() = 2.0 * width + 2.0 * height
   member x.Area() = width * height</lang>

Go

The task describes several concepts concerning class methods before giving some task requirements. The following code satisfies the task requirements. The concepts described however, are more involved. A discussion of these concepts follows. <lang go>package main

import "fmt"

// a basic "class." // In quotes because Go does not use that term or have that exact concept. // Go simply has types that can have methods. type picnicBasket struct {

   nServings int // "instance variables"
   corkscrew bool

}

// a method (yes, Go uses the word method!) func (b *picnicBasket) happy() bool {

   return b.nServings > 1 && b.corkscrew

}

// a "constructor." // Also in quotes as Go does not have that exact mechanism as part of the // language. A common idiom however, is a function with the name new<Type>, // that returns a new object of the type, fully initialized as needed and // ready to use. It makes sense to use this kind of constructor function when // non-trivial initialization is needed. In cases where the concise syntax // shown is sufficient however, it is not idiomatic to define the function. // Rather, code that needs a new object would simply contain &picnicBasket{... func newPicnicBasket(nPeople int) *picnicBasket {

   // arbitrary code to interpret arguments, check resources, etc.
   // ...
   // return data new object.
   // this is the concise syntax.  there are other ways of doing it.
   return &picnicBasket{nPeople, nPeople > 0}

}

// how to instantiate it. func main() {

   var pb picnicBasket          // create on stack (probably)
   pbl := picnicBasket{}        // equivalent to above
   pbp := &picnicBasket{}       // create on heap.  pbp is pointer to object.
   pbn := new(picnicBasket)     // equivalent to above
   forTwo := newPicnicBasket(2) // using constructor
   // equivalent to above.  field names, called keys, are optional.
   forToo := &picnicBasket{nServings: 2, corkscrew: true}
   fmt.Println(pb.nServings, pb.corkscrew)
   fmt.Println(pbl.nServings, pbl.corkscrew)
   fmt.Println(pbp)
   fmt.Println(pbn)
   fmt.Println(forTwo)
   fmt.Println(forToo)

}</lang> Output

0 false
0 false
&{0 false}
&{0 false}
&{2 true}
&{2 true}

Transitive closure based on inheritance

Method polymorphism exists in Go with a type called interface. A Go interface is a method set. A type is said to satisfy an interface if it has defined on it all methods of the interface. If interface A is a subset of interface B then A satisfies B, so a transitive closure exists on this concept of satisfying an interface.

Inheritance is not involved however. A type satisfies an interface automatically when all methods of the interface are defined on the type. Inheritance is not involved because the interface being satisfied is not mentioned in any way, either in the type satisfying the interface or in its methods. The writer of a type and methods need not even be aware that the interface being satisfied exists.

Root type

The empty interface, with an empty method set and written as interface{}, is the “root type” in this context of transitive closure of interface satisfaction. All types satisfy the empty interface, since it makes no requirements that any methods be defined at all. interface{} is often used in go as a type that can hold a data value of any type. For example, note how fmt.Println, used above, accepts arguments of any type. It's (variadic) argument is of type interface{}.

Polymorphic dispatch

This happens when a method is called through an interface. Consider this code in addition to the example above. <lang go>import reflect

type happinessTester interface {

   happy() bool

}

type bottleOfWine struct {

   USD   float64
   empty bool

}

func (b *bottleOfWine) happy() bool {

   return b.USD > 10 && !b.empty

}

func main() {

   partySupplies := []happinessTester{
       &picnicBasket{2, true},
       &bottleOfWine{USD: 6},
   }
   for _, ps := range partySupplies {
       fmt.Printf("%s: happy? %t\n",
           reflect.Indirect(reflect.ValueOf(ps)).Type().Name(),
           ps.happy())
   }

}</lang> On the last line, in the call to ps.happy(), ps is of the interface type happinessTester. The method actually called is based on the underlying concrete type. For the method call, this is called the receiver type and the variable b (in both happy methods) is called the receiver. Dispatch is based on this single receiver so Go is a single dispatch kind of language.

Type tag

Go maintains something equivalent in its internal representation of interfaces. In place of direct access to internal data, Go's reflect package provides a number of functions for inspecting types and returning useful information. Shown above for example, is code recovering the name of the concrete type underlying the dynamic type of the interface.

Output for second example:

picnicBasket: happy? true
bottleOfWine: happy? false

Distinction of types and classes

To the extent that an interface represents a class, it is distinct from a type that satisfies it. Interface is one kind of type, but an object of any type can satisfy an interface. The two types—the interface type and the type satisfying the interface—are distinct.

Groovy

A class: <lang groovy>/** Ye olde classe declaration */ class Stuff {

   /** Heare bee anne instance variable declared */
   def guts
   
   /** This constuctor converts bits into Stuff */
   Stuff(injectedGuts) {
       guts = injectedGuts
   }
   
   /** Brethren and sistren, let us flangulate with this fine flangulating method */
   def flangulate() {
       println "This stuff is flangulating its guts: ${guts}"
   }

}</lang>

A demonstration: <lang groovy>def stuff = new Stuff( I have made mistakes in the past. I have made mistakes in the future.

   -- Vice President Dan Quayle

)

stuff.flangulate()

stuff.guts = Our enemies are innovative and resourceful, and so are we. They never stop thinking about new ways to harm our country and our people, and neither do we.

   -- President George W. Bush

stuff.flangulate()</lang>

Output:

This stuff is flangulating its guts: 
I have made mistakes in the past.
I have made mistakes in the future.
    -- Vice President Dan Quayle

This stuff is flangulating its guts: 
Our enemies are innovative and resourceful, and so are we.
They never stop thinking about new ways to harm our country and our people,
and neither do we.
    -- President George W. Bush

Haskell

Haskell is entirely statically typed; that is, the type of every expression is completely determined at compile-time. Hence, the usual approach to object-oriented programming, in which the actual method invoked by a method call isn't determined until runtime (think of C++'s virtual functions), is impossible in Haskell 98. Haskell's type classes allow for polymorphic functions, but all the polymorphism happens at compile-time (think of C++ templates) without the use of language extensions (existential types). <lang haskell>class Shape a where

   perimeter :: a -> Double
   area      :: a -> Double

{- A type class Shape. Types belonging to Shape must support two methods, perimeter and area. -}

data Rectangle = Rectangle Double Double {- A new type with a single constructor. In the case of data types which have only one constructor, we conventionally give the constructor the same name as the type, though this isn't mandatory. -}

data Circle = Circle Double

instance Shape Rectangle where

   perimeter (Rectangle width height) = 2 * width + 2 * height
   area      (Rectangle width height) = width * height

{- We made Rectangle an instance of the Shape class by implementing perimeter, area :: Rectangle -> Int. -}

instance Shape Circle where

   perimeter (Circle radius) = 2 * pi * radius
   area      (Circle radius) = pi * radius^2

apRatio :: Shape a => a -> Double {- A simple polymorphic function. -} apRatio shape = area shape / perimeter shape

main = do

   print $ apRatio $ Circle 5
   print $ apRatio $ Rectangle 5 5

{- The correct version of apRatio (and hence the correct implementations of perimeter and area) is chosen based on the type of the argument. -}</lang>

The primary way to simulate run-time polymorphism in Haskell is to use a single algebraic data type with multiple constructors, rather than several types belonging to a single class.

<lang haskell>data Shape = Rectangle Double Double | Circle Double {- This Shape is a type rather than a type class. Rectangle and Circle are its constructors. -}

perimeter :: Shape -> Double {- An ordinary function, not a method. -} perimeter (Rectangle width height) = 2 * width + 2 * height perimeter (Circle radius) = 2 * pi * radius

area :: Shape -> Double area (Rectangle width height) = width * height area (Circle radius) = pi * radius^2

apRatio :: Shape -> Double {- Technically, this version of apRatio is monomorphic. -} apRatio shape = area shape / perimeter shape

main = do

   print $ apRatio $ Circle 5
   print $ apRatio $ Rectangle 5 5

{- The value returned by apRatio is determined by the return values of area and perimeter, which just happen to be defined differently for Rectangles and Circles. -}</lang>

Icon and Unicon

Unicon supports classes. <lang Unicon>class Example (x) # 'x' is a field in class

 # method definition
 method double ()
   return 2 * x
 end
 # 'initially' block is called on instance construction
 initially (x) 
   if /x # if x is null (not given), then set field to 0
     then self.x := 0 
     else self.x := x

end

procedure main ()

 x1 := Example ()  # new instance with default value of x
 x2 := Example (2) # new instance with given value of x
 write (x1.x)
 write (x2.x)
 write (x2.double ()) # call a method

end</lang>

J

Class definition: <lang j>coclass 'exampleClass'

exampleMethod=: monad define

1+exampleInstanceVariable

)

create=: monad define

'this is the constructor'

)

exampleInstanceVariable=: 0</lang>

Instantiation: <lang j> exampleObject=: conew 'exampleClass'</lang>

Java

<lang java>public class MyClass {

 // instance variable
 private int variable;  // Note: instance variables are usually "private"
 /**
 * The constructor
 */
 public MyClass() {
   // creates a new instance
 }
 /**
 * A method
 */
 public void someMethod() {
  this.variable = 1;
 }

}</lang> Note: "this." in someMethod is optional. "variable = 1;" works also. If a parameter also named "variable" came into someMethod, using "this" specifies using the instance variable rather than the local method variable.

JavaScript

JavaScript is prototype-based, so it doesn't have classes per se. Thinking in classes when coding JavaScript will only hinder you in the long run, but here's an example of JavaScript OO:

<lang javascript>//Constructor function. function Car(brand, weight) {

 this.brand = brand;
 this.weight = weight || 1000; // Resort to default value (with 'or' notation).

} Car.prototype.getPrice = function() { // Method of Car.

 return this.price;

}

function Truck(brand, size) {

 this.car = Car;
 this.car(brand, 2000); // Call another function, modifying the "this" object (e.g. "superconstructor".)
 this.size = size; // Custom property for just this object.

} Truck.prototype = Car.prototype; // Also "import" the prototype from Car.

var cars = [ // Some example car objects.

 new Car("Mazda"),
 new Truck("Volvo", 2)

]; for (var i=0; i<cars.length; i++) {

 alert(cars[i].brand + " " + cars[i].weight + " " + cars[i].size + ", " +
     (cars[i] instanceof Car) + " " + (cars[i] instanceof Truck));

}</lang> The alerts shows us:

Mazda 1000 undefined, true true
Volvo 2000 2, true true

The reason Car shows as instanceof Truck is because we've overwritten Truck.prototype with Car.prototype. It's probably not the best way to do it, but it suffices for most cases.

LFE

<lang lisp> (defmodule simple-object

 (export all))

(defun fish-class (species)

 "
 This is the constructor used internally, once the children and fish id are
 known.
 "
 (let ((habitat '"water"))
   (lambda (method-name)
     (case method-name
       ('habitat
         (lambda (self) habitat))
       ('species
         (lambda (self) species))))))

(defun get-method (object method-name)

 "
 This is a generic function, used to call into the given object (class
 instance).
 "
 (funcall object method-name))
define object methods

(defun get-habitat (object)

 "Get a variable set in the class."
 (funcall (get-method object 'habitat) object))

(defun get-species (object)

 "Get a variable passed when constructing the object."
 (funcall (get-method object 'species) object))

</lang>

Usage from the LFE REPL: <lang lisp> > (slurp '"simple-object.lfe")

  1. (ok simple-object)

> (set my-fish (fish-class '"Carp"))

  1. Fun<lfe_eval.10.91765564>

> (get-habitat my-fish) "water" > (get-species my-fish) "Carp" </lang>

Lisaac

<lang Lisaac>Section Header

+ name := SAMPLE;

Section Inherit

- parent : OBJECT := OBJECT;

Section Private

+ variable : INTEGER <- 0;

Section Public

- some_method <- (

 variable := 1;

);

- main <- (

 + sample : SAMPLE;
 sample := SAMPLE.clone;
 sample.some_method;

);</lang>

Logtalk

The definition of classes in Logtalk require the use of meta-classes. In order to avoid infinite regression, we use here the usual trick of making a class an instance of itself. The class meta-class holds the constructor method, allowing the class to accept a message for creating a new instance. The class itself defines the methods and variables of its instances. <lang logtalk>:- object(metaclass,

   instantiates(metaclass)).
   :- public(new/2).
   new(Instance, Value) :-
       self(Class),
       create_object(Instance, [instantiates(Class)], [], [state(Value)]).
- end_object.
- object(class,
   instantiates(metaclass)).
   :- public(method/1).
   method(Value) :-
       ::state(Value).
   :- private(state/1).
- end_object.</lang>

A simple usage example after compiling and loading the above code: <lang logtalk>| ?- class::new(Instance, 1). Instance = o1 yes

| ?- o1::method(Value). Value = 1 yes</lang>

Lua

Classes in Lua are implemented with metatables. This doesn't implement a full system, but it gets the basic idea: <lang lua>myclass = setmetatable({ __index = function(z,i) return myclass[i] end, --this makes class variables a possibility setvar = function(z, n) z.var = n end }, { __call = function(z,n) return setmetatable({var = n}, myclass) end })

instance = myclass(3)

print(instance.var) -->3

instance:setvar(6)

print(instance.var) -->6</lang>

MATLAB

There are two ways to declare classes in MATLAB: with a classdef or without it. First you must create a folder named after the class type that you are defining with an "@" appended to the front, e.g. "@LinkedList", in your MATLAB root directory. In this folder you put all of the class methods and, if you have it, the classdef. Any MATLAB buitlin methods can be overloaded for any class you define. For example, if you want to overload the "+" operator, create an .m file in the class folder named "plus.m". Furthermore, all class variables have to be generated in the class constructor if a classdef is not going to be used.

Below are two examples of classes declared in MATLAB. GenericClass is defined without a classdef. GenericClass2 is defined with a classdef. The classes both do the exact same thing, the only difference between them is how they are defined.

@GenericClass

GenericClass.m: Class Constructor <lang MATLAB>function GenericClassInstance = GenericClass(varargin)

       if isempty(varargin) %No input arguments             
           GenericClassInstance.classVariable = 0; %Generates a struct
       else
           GenericClassInstance.classVariable = varargin{1}; %Generates a struct
       end
       
       %Converts the struct to a class of type GenericClass
       GenericClassInstance = class(GenericClassInstance,'GenericClass');
       

end</lang> getValue.m: <lang MATLAB>%Get function function value = getValue(GenericClassInstance)

   value = GenericClassInstance.classVariable;

end</lang> setValue.m: <lang MATLAB>%Set function function GenericClassInstance = setValue(GenericClassInstance,newValue)

  GenericClassInstance.classVariable = newValue;

end</lang> display.m: This method overloads the "disp()" command <lang MATLAB>function display(GenericClassInstance)

   disp(sprintf('%f',GenericClassInstance.classVariable));

end</lang>

Sample Usage: <lang MATLAB>>> myClass = GenericClass(3) 3.000000 >> myClass = setValue(myClass,pi) 3.141593 >> getValue(myClass)

ans =

  3.141592653589793</lang>

@GenericClass2 GenericClass2.m: This is the classdef, it includes the class constructor as well as class variables and methods. <lang MATLAB>classdef GenericClass2

   properties
       classVariable
   end %properties
   
   methods
        
       %Class constructor
       function objectInstance = GenericClass2(varargin)        
           if isempty(varargin) %No input arguments             
               objectInstance.classVariable = 0;
           else
               objectInstance.classVariable = varargin{1};
           end
       end      
       
       %Set function
       function setValue(GenericClassInstance,newValue)
           GenericClassInstance.classVariable = newValue;
           
           %MATLAB magic that changes the object in the scope that called
           %this set function.
           assignin('caller',inputname(1),GenericClassInstance);  
       end
       
   end %methods

end</lang> getValue.m: <lang MATLAB>%Get function function value = getValue(GenericClassInstance)

   value = GenericClassInstance.classVariable;

end</lang> display.m: This method overloads the "disp()" command <lang MATLAB>function display(GenericClassInstance)

   disp(sprintf('%f',GenericClassInstance.classVariable));

end</lang>

Sample Usage: <lang MATLAB>>> myClass = GenericClass2(3) 3.000000 >> setValue(myClass,pi) >> getValue(myClass)

ans =

  3.141592653589793</lang>

Nemerle

<lang Nemerle>public class MyClass {

   public this() { }  // the constructor in Nemerle is always named 'this'
   
   public MyVariable : int
   {
       get;
       set;
   }
   
   public MyMethod() : void
   {
   }
   

}

def myInstance = MyClass(); // no 'new' keyword needed myInstance.MyVariable = 42; // set MyVariable System.Console.WriteLine($"My variable is $(myInstance.MyVariable)") // get MyVariable</lang>

NetRexx

<lang rexx>class ClassExample

 properties private -- class scope
 foo = int
 
 properties public  -- publicly visible
 bar = boolean
 
 properties indirect -- generates bean patterns
 baz = String()
 
 method main(args=String[]) static -- main method
   clsex = ClassExample()   -- instantiate
   clsex.foo = 42
   clsex.baz = 'forty-two'
   clsex.bar = 0 -- boolean false
   clsex.test(clsex.foo)
   clsex.test(clsex.bar)
   clsex.test(clsex.baz)
 method test(s=int)
   aap = 1 -- local (stack) variable
   say s aap
 method test(s=String)
   noot = 2
   say s noot
 method test(s=boolean)
   mies = 3
   say s mies</lang>

Oberon-2

Works with: OO2C version 2.1.11

<lang oberon2>MODULE M;

  TYPE
     T = POINTER TO TDesc;
     TDesc = RECORD
        x: INTEGER
     END;
  PROCEDURE New*(): T;
     VAR t: T;
  BEGIN
     NEW(t); t.x := 0;
     RETURN t
  END New;


  PROCEDURE (t: T) Increment*;
  BEGIN
     INC(t.x)
  END Increment;

END M.</lang>

Exported procedures are marked with an asterisk (*). There is nothing special about the constructor New, it is just a function that returns a new object of type T. The name of the method receiver can also be chosen freely. INC is a predeclared procedure that increments its argument.

Object Pascal

Works with: Turbo Pascal version 6.0
Note: This is not part of standard Pascal, but Turbo Pascal specific

<lang pascal>type

MyClass = object
           variable: integer;
           constructor init;
           destructor done;
           procedure someMethod;
          end;

constructor MyClass.init;

begin
 variable := 0;
end;

procedure MyClass.someMethod;

begin
 variable := 1;
end;

var

instance: MyClass; { as variable }
pInstance: ^MyClass; { on free store }

begin

{ create instances }
instance.init;
new(pInstance, init); { alternatively: pInstance := new(MyClass, init); }

{ call method }
instance.someMethod;
pInstance^.someMethod;

{ get rid of the objects }
instance.done;
dispose(pInstance, done);

end;</lang>

Objective-C

Works with: GCC
Works with: Cocoa
Works with: GNUstep

Interface: <lang objc>// There are no class variables, so static variables are used. static int myClassVariable = 0;

@interface MyClass : NSObject {

   int variable; // instance variable

}

- (int)variable; // Typical accessor - you should use the same name as the variable

@end</lang>

Implementation:

<lang objc>@implementation MyClass

// Was not declared because init is defined in NSObject - init {

   if (self = [super init])
       variable = 0;
   return self;

}

- (int)variable {

   return variable;

}

@end</lang>

Using the class:

<lang objc>// Creating an instance MyClass *mc = [[MyClass alloc] init];

// Sending a message [mc variable];

// Releasing it. When its reference count goes to zero, it will be deallocated [mc release];</lang>

Objeck

<lang objeck>bundle Default {

 class MyClass {
   @var : Int;
   
   New() {
   }
   
   method : public : SomeMethod() ~ Nil {
   	@var := 1;
   }
   
   method : public : SetVar(var : Int) ~ Nil {
     @var := var;
   }
   
   method : public : GetVar() ~ Int {
     return @var;
   }
 }
 
 class Test {
   function : Main(args : String[]) ~ Nil {
     inst := MyClass->New();
     inst->GetVar()->PrintLine();
     
     inst->SomeMethod();
     inst->GetVar()->PrintLine();
     
     inst->SetVar(15);
     inst->GetVar()->PrintLine();
   }
 }

}</lang>

OCaml

<lang ocaml>class my_class =

 object (self)
   val mutable variable = 0
   method some_method = variable <- 1
 end</lang>

Using the class:

# let instance = new my_class;;
val instance : my_class = <obj>
# instance#some_method;;
- : unit = ()

ooRexx

ooRexx classes are defined using directives. Only methods of the class can directly access instance variables to avoid fragile base class problems, methods can only access variables at the level of the class hierarchy it is defined. ::attribute directives create setter and getter methods that allow instance variables to be accessed in other contexts.

<lang ooRexx> p = .point~new c = .circle~new

p~print c~print

class point
method init
 expose x y
 use strict arg x = 0, y = 0   -- defaults to 0 for any non-specified coordinates
attribute x
attribute y
method print
 expose x y
 say "A point at location ("||x","y")"
class circle subclass point
method init
 expose radius
 use strict arg x = 0, y = 0, radius = 0
 self~init:super(x, y)        -- call superclass constructor
attribute radius
method print
 expose radius
 say "A circle of radius" radius "centered at location ("||self~x","self~y")"

</lang>

OxygenBasic

Example of a dynamic object. (statically defined objects do not require specific constructors and destructors.)

Parameter polymorphism is supported both by method overloading and also by automatic type conversion between integers, floats, strings and other primitives.

<lang oxygenbasic>

class SuperString

indexbase 1

union

 bstring s
 sys     bs
 sys     *y
 int     *i
 byte    *b
 float   *f

end union

method space(sys n)

 s=space n  

end method

method delete()

 freememory bs : bs=0

end method

method clear()

 sys j, le=length
 if le then
   for j=1 to le : b[j]=0 : next
 end if

end method

method length() as sys

 if bs then return i[0]

end method

method resize(sys n)

 sys le=length
 if n<le
   s=left s,n
 elseif n>le
   s+=nuls n-le
 end if

end method

method fill(string f)

 sys j, ls=length, lf=len f
 for j=1 to ls step lf
   mid s,j,f
 next

end method

method constructor() end method

method destructor

 delete

end method

end class


'#recordof SuperString

'===== 'TESTS '=====

new SuperString ss ' ss.space 100 ss.resize 8 ss.fill "abc" ' print ss.s 'result abcabcab print ss.b[3] 'result 99: ascii for 'c' ' del ss </lang>

Oz

Classes are created at runtime and first-class values. <lang oz>declare

 class Something
    feat
       name %% immutable, public attribute (called a "feature")
    attr
       count %% mutable, private attribute
    %% public method which is used as an initializer
    meth init(N)
       self.name = N
       count := 0
    end
    %% public method
    meth increase
       count := @count + 1
    end
 end

in

 %% create an instance
 Object = {New Something init("object")}
 %% call a method
 {Object increase}</lang>

Pascal

See Delphi

Perl

Works with: Perl version 5.8.6

The implementation (there are no declarations) of a class using the standard object system: <lang perl>{

    # a class is a package (i.e. a namespace) with methods in it
   package MyClass;
    # a constructor is a function that returns a blessed reference
   sub new {
       my $class = shift;
       bless {variable => 0}, $class;
        # the instance object is a hashref in disguise.
        # (it can be a ref to anything.)
   }
    # an instance method is a function that takes an object as first argument.
    # the -> invocation syntax takes care of that nicely, see Usage paragraph below.
   sub some_method {
       my $self = shift;
       $self->{variable} = 1;
   }

}</lang>

This is the same using the Moose object system: <lang perl>{

   package MyClass;
   use Moose;
   has 'variable' => (is => 'rw', default => 0);
   # constructor and accessor methods are added automatically
   sub some_method {
       my $self = shift;
       $self->variable(1);
   }

}</lang>

This is the same class using the MooseX::Declare extention: <lang perl>use MooseX::Declare; class MyClass {

   has 'variable' => (is => 'rw', default => 0);
   method some_method {
       $self->variable(1);
   }

}</lang>

All of the above classes can be used the same way: <lang perl>my $instance = MyClass->new; # invoke constructor method

$instance->some_method; # invoke method on object instance

# instance deallocates when the last reference falls out of scope</lang>

Perl 6

<lang perl6>class Camel { has Int $.humps = 1; }

my Camel $a .= new; say $a.humps; # Automatically generated accessor method.

my Camel $b .= new: humps => 2; say $b.humps;</lang>

A more complex example:

<lang perl6>class Butterfly {

   has Int $!age;    # The ! twigil makes it private.
   has Str $.name;
   has Str $.color;
   has Bool $.wings;
   submethod BUILD(:$!name = 'Camelia', :$!age = 2, :$!color = 'pink') {
       # BUILD is called by bless. Its primary use is to to control
       # object initialization.
       $!wings = $!age > 1;
   }
   method flap() {
       say ($.wings
         ?? 'Watch out for that hurricane!'
         !! 'No wings to flap.');
   }

}

my Butterfly $a .= new: age => 5; say "Name: {$a.name}, Color: {$a.color}"; $a.flap;

my Butterfly $b .= new(name => 'Osgood', age => 4); say "Name: {$b.name}, Color: {$b.color}"; $b.flap;</lang>

PHL

<lang phl>module classes;

extern printf;

class @MyClass { field @Integer myField { get:get_myField, set:set_myField };

new [ this.set_myField(2); ]

@Void method [ this.set_myField(this::get_myField + 1); ] };

@Integer main [ var obj = new @MyClass; printf("obj.myField: %i\n", obj::get_myField); obj::method; printf("obj.myField: %i\n", obj::get_myField); return 0; ]</lang>

PHP

<lang php>class MyClass {

   public static $classVar;
   public $instanceVar; // can also initialize it here
   function __construct() {
       $this->instanceVar = 0;
   }
   function someMethod() {
       $this->instanceVar = 1;
       self::$classVar = 3;
   }

} $myObj = new MyClass();</lang>

PicoLisp

<lang PicoLisp>(class +Rectangle)

  1. dx dy

(dm area> () # Define a a method that calculates the rectangle's area

  (* (: dx) (: dy)) )

(println # Create a rectangle, and print its area

  (area> (new '(+Rectangle) 'dx 3 'dy 4)) )</lang>

Pop11

Object system is implemented as a library, so we must first load it. <lang pop11>uses objectclass; define :class MyClass;

   slot value = 1;

enddefine;</lang>

Defining class MyClass automatically defines two constructors, newMyClass and consMyClass and slot (instance variable) accessors, so we can immediately start using our new class:

<lang pop11>;;; Construct instance with default slot values lvars instance1 = newMyClass();

Construct instance with explicitely given slot values

lvars instance2 = consMyClass(15);

Print slot value using dot notation

instance1.value => instance2.value =>

Print slot value using funtional notation

value(instance1) =>

Change slot value

12 -> value(instance1);

Print it

value(instance1) =></lang>

We can add methods at any time (even after creating an instance):

<lang pop11>define :method reset(x : MyClass);

  0 -> value(x);

enddefine; reset(instance1);

Print it

instance1 =></lang>

PureBasic

Generic version

<lang PureBasic>Interface OO_Interface ; Interface for any value of this type

 Get.i()        
 Set(Value.i) 
 ToString.s()
 Destroy()

EndInterface

Structure OO_Structure ; The *VTable structure

 Get.i
 Set.i
 ToString.i
 Destroy.i

EndStructure

Structure OO_Var

 *VirtualTable.OO_Structure
 Value.i 

EndStructure

Procedure OO_Get(*Self.OO_Var)

 ProcedureReturn *Self\Value

EndProcedure

Procedure OO_Set(*Self.OO_Var, n)

 *Self\Value = n

EndProcedure

Procedure.s OO_ToString(*Self.OO_Var)

 ProcedureReturn Str(*Self\Value)

EndProcedure

Procedure Create_OO()

 *p.OO_Var=AllocateMemory(SizeOf(OO_Var))
 If *p
   *p\VirtualTable=?VTable
 EndIf
 ProcedureReturn *p

EndProcedure

Procedure OO_Destroy(*Self.OO_Var)

 FreeMemory(*Self)

EndProcedure

DataSection

 VTable:
 Data.i @OO_Get()
 Data.i @OO_Set()
 Data.i @OO_ToString()
 Data.i @OO_Destroy()

EndDataSection

- Test the code
  • Foo.OO_Interface = Create_OO()
  • Foo\Set(341)

MessageRequester("Info", "Foo = " + *Foo\ToString() )

  • Foo\Destroy()</lang>

Simple OOP Version

Using the open-source precompiler SimpleOOP. <lang PureBasic>Class Foo

 Private Value.i
 
 BeginPublic
   Method Init()
     ; Any needed code goes here  
   EndMethod
   
   Method Release()
     ; Any code befoe freeing the object goes here
   EndMethod
   
   Method Get()
     MethodReturn This\Value  
   EndMethod
   
   Method Set(n)
     This\Value = n
   EndMethod
   
   Method.s ToString()
     MethodReturn Str(This\Value)
   EndMethod
 EndPublic

EndClass

- Test the code
  • Demo.foo = NewObject.foo()
  • Demo\Set(4)

MessageRequester("Info", "Val= " + *Demo\ToString())</lang>

Python

<lang python>class MyClass:

   name2 = 2 # Class attribute
   def __init__(self):
       """
       Constructor  (Technically an initializer rather than a true "constructor")
       """
       self.name1 = 0 # Instance attribute
 
   def someMethod(self):
       """
       Method
       """
       self.name1 = 1
       MyClass.name2 = 3
 
 

myclass = MyClass() # class name, invoked as a function is the constructor syntax.

class MyOtherClass:

   count = 0  # Population of "MyOtherClass" objects
   def __init__(self, name, gender="Male", age=None):
       """
       One initializer required, others are optional (with different defaults)
       """
       MyOtherClass.count += 1
       self.name = name
       self.gender = gender
       if age is not None:
           self.age = age
   def __del__(self):
       MyOtherClass.count -= 1

person1 = MyOtherClass("John") print person1.name, person1.gender # "John Male" print person1.age # Raises AttributeError exception! person2 = MyOtherClass("Jane", "Female", 23) print person2.name, person2.gender, person2.age # "Jane Female 23"</lang>

Python allows for very flexible argument passing including normal named parameters, defaulted/optional named parameters, up to one "varargs" tuple, and any number of keywords arguments (which are all passed in the form of a single dictionary (associative array), and any non-ambiguous combination of these). All types of argument passing for functions can also be used for object instantiation/initialization (passed to the special __init__() method) as shown.

New-style classes inherit from "object" or any descendant of the "object" class:

<lang python>class MyClass(object):

   ...</lang>

These "new-style" classes support some features which were unavailable in "classic classes". New features include a __new__() with lower level control over object instantiation, metaclass support, static methods, class methods, "properties" (managed attributes) and "slots" (attribute restrictions).

R

R has (at least) 5 different object oriented systems. S3 and S4 correspond to different versions of the S language, from which R was derived. See, for example, this presentation by Freidrich Leisch for a more thorough introduction to S3 and S4 classes. Both these class systems are in use, and ship with the standard R distribution. The OOP, R.oo and proto packages provide other systems.

S3

S3 provides a very simple class system designed to be easily used interactively. <lang R>#You define a class simply by setting the class attribute of an object circS3 <- list(radius=5.5, centre=c(3, 4.2)) class(circS3) <- "circle"

  1. plot is a generic function, so we can define a class specific method by naming it plot.classname

plot.circle <- function(x, ...) {

  t <- seq(0, 2*pi, length.out=200)
  plot(x$centre[1] + x$radius*cos(t),
     x$centre[2] + x$radius*sin(t),
     type="l", ...)

} plot(circS3)</lang>

S4

S4 is a more formal class system that provides validity checking and a way to define different methods for different input signatures. <lang R>setClass("circle",

  representation(
     radius="numeric",
     centre="numeric"),
  prototype(
     radius=1,
     centre=c(0,0)))
  1. Instantiate class with some arguments

circS4 <- new("circle", radius=5.5)

  1. Set other data slots (properties)

circS4@centre <- c(3,4.2)

  1. Define a method

setMethod("plot", #signature("circle"),

  signature(x="circle", y="missing"),
  function(x, ...)
  {
     t <- seq(0, 2*pi, length.out=200)
     #Note the use of @ instead of $
     plot(x@centre[1] + x@radius*cos(t),
        x@centre[2] + x@radius*sin(t),
        type="l", ...)
  })

plot(circS4)</lang>

Racket

Racket programs heavily use functions, but classes and objects are available as well:

<lang racket>

  1. lang racket

(define fish%

 (class object%
   (super-new)
   ;; an instance variable & constructor argument
   (init-field size)
   ;; a new method
   (define/public (eat)
     (displayln "gulp!"))))
constructing an instance

(new fish% [size 50]) </lang>

REBOL

<lang REBOL>rebol [

   Title: "Classes"
   Author: oofoe
   Date: 2009-12-11
   URL: http://rosettacode.org/wiki/Classes

]

Objects are derived from the base 'object!' type. REBOL uses a
prototyping object system, so any object can be treated as a class,
from which to derive others.

cowboy: make object! [ name: "Tex"  ; Instance variable. hi: does [  ; Method. print [self/name ": Howdy!"]] ]

I create two instances of the 'cowboy' class.

tex: make cowboy [] roy: make cowboy [ name: "Roy"  ; Override 'name' property. ]

print "Say 'hello', boys:" tex/hi roy/hi print ""

Now I'll subclass 'cowboy'. Subclassing looks a lot like instantiation

legend: make cowboy [ deed: "..." boast: does [ print [self/name ": I once" self/deed "!"]] ]

Instancing the legend

pecos: make legend [name: "Pecos Bill" deed: "lassoed a twister"]

print "Howdy, Pecos!" pecos/hi print "Tell us about yourself?" pecos/boast</lang>

Output:

Say 'hello', boys:
Tex : Howdy!
Roy : Howdy!

Howdy, Pecos!
Pecos Bill : Howdy!
Tell us about yourself?
Pecos Bill : I once lassoed a twister !

Context...

RapidQ

<lang rapidq>TYPE MyClass EXTENDS QObject

   Variable AS INTEGER
   CONSTRUCTOR
       Variable = 0
   END CONSTRUCTOR
   SUB someMethod
       MyClass.Variable = 1
   END SUB

END TYPE

' create an instance DIM instance AS MyClass

' invoke the method instance.someMethod</lang>

Raven

Build classes: <lang raven>class Alpha

   'I am Alpha.' as greeting
   define say_hello
       greeting print

class Beta extend Alpha

   'I am Beta!' as greeting</lang>

Execute classes to create objects: <lang raven>Alpha as alpha Beta as beta</lang>

Call methods: <lang raven>alpha.say_hello beta.say_hello</lang>

Result: <lang raven>I am Alpha. I am Beta!</lang>

Ruby

<lang ruby>class MyClass

 @@class_var = []
 def initialize
   # 'initialize' is the constructor method invoked during 'MyClass.new'
   @instance_var = 0
 end
 def some_method
   @instance_var = 1
   @@class_var << Time.now
 end
 def self.class_method
   # ...
 end
 # another way to define class methods: define an instance method in this class object's singleton class
 class << self
   def another_class_method
     # ...
   end
 end

end

myclass = MyClass.new</lang>

Sather

<lang sather>class CLASSTEST is

 readonly attr x:INT; -- give a public getter, not a setter
 private attr y:INT;  -- no getter, no setter
 attr z:INT;          -- getter and setter
 -- constructor
 create(x, y, z:INT):CLASSTEST is
   res :CLASSTEST := new; -- or res ::= new
   res.x := x; 
   res.y := y;
   res.z := z;
   return res;
 end;
 
 -- a getter for the private y summed to s
 getPrivateY(s:INT):INT is
   -- y is not shadowed so we can write y instead of
   -- self.y
   return y + s;
 end;

end;</lang>

<lang sather>class MAIN is

 main is
   test ::= #CLASSTEST(1, 2, 3);
   -- the previous line is syntactic sugar for
   -- test :CLASSTEST := CLASSTEST::create(1, 2, 3);
   #OUT + test.z + "\n"; -- we can access z
   test.z := 25;         -- we can set z
   #OUT + test.x + "\n"; -- we can get x
   -- test.x := 5;          -- we cannot set x
   #OUT + test.getPrivateY(0) + "\n";
 end;

end;</lang>

Scala

Scala is highly object-oriented and such a task is trivial. In some cases the constructor and instance variables do not have to be explicitly declared; this example shows two ways each to make constructors and instance variables. <lang Scala>/**

* This class implicitly includes a constructor which accepts an int and
* creates "val variable1: Int" with that value.
*/

class MyClass(variable1: Int) {

   var variable2 = "asdf" // Another instance variable; a var this time
   def this() = this(0) // An auxilliary constructor that instantiates with a default value
   def myMethod = variable1 // A getter for variable1

}

/**

* Demonstrate use of our example class.
*/

object Main extends Application {

   val m = new MyClass()
   val n = new MyClass(3)
   println(m.myMethod) // prints 0
   println(n.myMethod) // prints 3

}</lang>

Scheme

From Structure and Interpretation of Computer Programs <lang Scheme> (define (withdraw amount)

   (if (>= balance amount)
       (begin (set! balance (- balance amount))
              balance)
       "Insufficient funds"))
 (define (deposit amount)
   (set! balance (+ balance amount))
   balance)
 (define (dispatch m)
   (cond ((eq? m 'withdraw) withdraw)
         ((eq? m 'deposit) deposit)
         (else (error "Unknown request -- MAKE-ACCOUNT"
                      m))))
 dispatch)</lang>

Slate

Slate objects operate as prototypes with multi-methods: <lang slate>prototypes define: #MyPrototype &parents: {Cloneable} &slots: #(instanceVar). MyPrototype traits addSlot: #classVar.

x@(MyPrototype traits) new [

 x clone `>> [instanceVar: 0. ]

].

x@(MyPrototype traits) someMethod [

 x instanceVar = 1 /\ (x classVar = 3)

].</lang>

Smalltalk

<lang smalltalk>Object subclass: #MyClass

 instanceVariableNames: 'instanceVar'
 classVariableNames: 'classVar'
 poolDictionaries: 
 category: 'Testing' !

!MyClass class methodsFor: 'instance creation'! new

 ^self basicNew  instanceVar := 0 ! !

!MyClass methodsFor: 'testing'! someMethod

 ^self instanceVar = 1; classVar = 3 ! !

MyClass new someMethod!</lang>

SuperCollider

<lang SuperCollider>MyClass {

   classvar someVar, <another, <>thirdVar;    // Class variables.
   var <>something, <>somethingElse;           // Instance variables.
                  // Note: variables are private by default. In the above, "<" enables getting, ">" enables setting
   *new {
       ^super.new.init         // constructor is a class method. typically calls some instance method to set up, here "init"
   }
   init {
         something = thirdVar.squared;
         somethingElse = this.class.name;
   }
   *aClassMethod {
        ^  someVar + thirdVar         // The "^" means to return the result. If not specified, then the object itself will be returned ("^this")
   }
   anInstanceMethod {
       something = something + 1;
   }

}</lang>

Tcl

Works with: Tcl version 8.6

or

Library: TclOO

<lang Tcl>package require TclOO oo::class create summation {

   variable v
   constructor {} {
       set v 0
   }
   method add x {
       incr v $x
   }
   method value {} {
       return $v
   }
   destructor {
       puts "Ended with value $v"
   }

} set sum [summation new] puts "Start with [$sum value]" for {set i 1} {$i <= 10} {incr i} {

   puts "Add $i to get [$sum add $i]"

} $sum destroy</lang>

TIScript

TIScript is prototype-based and yet it has classes. Object that was created as an instance of one class can be transformed to the instance of another class by changing its obj.prototype field.

<lang javascript>class Car {

 //Constructor function.
 function this(brand, weight, price = 0) {
   this.brand = brand;
   this.weight = weight || 1000; // Resort to default value (with 'or' notation).
   this._price = price;
 }
 property price(v) // computable property, special kind of member function
 {
   get { return this._price; } // getter section 
   set { this._price = v; }    // setter section
 }
 function toString() { // member function, method of a Car.
   return String.printf("<%s>",this.brand);
 }

}

class Truck : Car {

 function this(brand, size) {
   super(brand, 2000); // Call of constructor of super class (Car here)
   this.size = size; // Custom property for just this object.
 }

}

var cars = [ // Some example car objects.

 new Car("Mazda"),
 new Truck("Volvo", 2, 30000)

]; for (var (i,car) in cars) // TIScript allows enumerate indexes and values {

 stdout.printf("#%d %s $%d %v %v, %v %v", i, car.brand, car.price, car.weight, car.size,
                car instanceof Car, car instanceof Truck);

}</lang> Console output will show:

#1 Mazda 1000 $0 undefined, true false
#2 Volvo 2000 $30000 2, true true

Vala

<lang vala>public class MyClass {

   // Instance variable
   public int variable;
   
   // Method
   public void some_method() {
       variable = 24;
   }
   
   // Constructor
   public MyClass() {
       variable = 42;
   }   

} void main() {

   // Class instance
   MyClass instance = new MyClass();
   print("%d\n", instance.variable);
   instance.some_method();
   print("%d\n", instance.variable);
   instance.variable = 84;
   print("%d\n", instance.variable);

}</lang>

VBA

Defining a class

In Visual Basic for Applications a class is defined in a separate Class Module. The name of the class module is the name of the class.

For each property you must supply a "Property Let" routine to set the property (or "Property Set" if the property refers to an object), and a "Property Get" function to get the property. Methods are represented by Functions in the class module. A class module can have a constructor - a sub with the special name Class_Initialize - and a destructor with the special name Class_Terminate.

This is the contents of a class module "Foo" (like in the Visual Basic .NET example below):

<lang vb>Private Const m_default = 10 Private m_bar As Integer

Private Sub Class_Initialize()

 'constructor, can be used to set default values
 m_bar = m_default

End Sub

Private Sub Class_Terminate()

 'destructor, can be used to do some cleaning up
 'here we just print a message
 Debug.Print "---object destroyed---"

End Sub Property Let Bar(value As Integer)

 m_bar = value

End Property

Property Get Bar() As Integer

 Bar = m_bar

End Property

Function DoubleBar()

 m_bar = m_bar * 2

End Function

Function MultiplyBar(x As Integer)

 'another method
 MultiplyBar = m_bar * x
 'Note: instead of using the instance variable m_bar we could refer to the Bar property of this object using the special word "Me":
 '  MultiplyBar = Me.Bar * x

End Function</lang>

Using an object

Objects (e.g. of class Foo) are created and used in "normal" modules. <lang vb>Public Sub foodemo() 'declare and create separately Dim f As Foo Dim f0 As Foo

Set f = New Foo

'set property f.Bar = 25 'call method f.DoubleBar 'alternative Call f.DoubleBar Debug.Print "f.Bar is "; f.Bar Debug.Print "Five times f.Bar is "; f.MultiplyBar(5)

'declare and create at the same time Dim f2 As New Foo Debug.Print "f2.Bar is "; f2.Bar 'prints default value

'destroy an object Set f = Nothing

'create an object or not, depending on a random number: If Rnd() < 0.5 Then

 Set f0 = New Foo

End If 'check if object actually exists If f0 Is Nothing Then

 Debug.Print "object f0 does not exist"

Else

 Debug.Print "object f0 was created"

End If 'at the end of execution all remaining objects created in this sub will be released. 'this will trigger one or two "object destroyed" messages 'depending on whether f0 was created... End Sub</lang>

Sample output:

foodemo
f.Bar is  100 
Five times f.Bar is  500 
f2.Bar is  10 
---object destroyed---
object f0 was created
---object destroyed---
---object destroyed---

Visual Basic .NET

Defining a class

<lang vbnet>Class Foo

  Private m_Bar As Integer
  Public Sub New()
  End Sub
  Public Sub New(ByVal bar As Integer)
      m_Bar = bar
  End Sub
  Public Property Bar() As Integer
      Get
          Return m_Bar
      End Get
      Set(ByVal value As Integer)
          m_Bar = value
      End Set
  End Property
  Public Sub DoubleBar()
      m_Bar *= 2
  End Sub
  Public Function MultiplyBar(ByVal x As Integer) As Integer
      Return x * Bar
  End Function

End Class</lang>

Using an object

<lang vbnet>'Declare and create separately Dim foo1 As Foo foo1 = New Foo

'Declare and create at the same time Dim foo2 As New Foo

'... while passing constructor parameters Dim foo3 As New Foo(5)

'... and them immediately set properties Dim foo4 As New Foo With {.Bar = 10}

'Calling a method that returns a value Console.WriteLine(foo4.MultiplyBar(20))

'Calling a method that performs an action foo4.DoubleBar()

'Reading/writing properties Console.WriteLine(foo4.Bar) foo4.Bar = 1000</lang>