Method Declarations

Overriding methods

When a method in a class overrides a method of a super class, the overridden method in the super class is no longer accessible. Dynamic dispatch is performed, using the exact type of the object (known at runtime) to select the method according to this exact type.

However, the interface of the accessible attributes and callable methods remains restricted to the static interface (i.e. the one of the static type of the object).

let
  class Shape
  {
    /* Position.  */
    var row := 0
    var col := 0

    method print_row() = (print("row = "); print_int(self.row))
    method print_col() = (print("col = "); print_int(self.col))

    method print() =
      (
        print("Shape = { ");
        self.print_row();
        print(", ");
        self.print_col();
        print(" }")
      )
  }

  class Circle extends Shape
  {
    var radius := 1

    method print_radius() = (print("radius = "); print_int(self.radius))

    /* Overridden method.  */
    method print() =
      (
        print("Circle = { ");
        self.print_row();
        print(", ");
        self.print_col();
        print(", ");
        self.print_radius();
        print(" }")
      )
  }

  /* C has static type Shape, and dynamic (exact) type Circle.  */
  var c : Shape := new Circle
in
  /* Dynamic dispatch to Circle's print method.  */
  c.print();

  /* Allowed.  */
  c.print_row()

  /* Forbidden: `print_radius' is not a member of Shape (nor of its
     super class(es)).  */
  /* c.print_radius() */
end
Method invariance

Methods are invariant in Tiger: each redefinition of a method in a subclass shall have the exact same signature as the original overridden method. This invariance applies to:

  1. the number of arguments.

  2. the types of the arguments.

  3. the type of the return value [1].

let
  class Food {}
  class Grass extends Food {}

  class Animal
  {
    method eat(f : Food) = ()
  }

  class Cow extends Animal
  {
    /* Invalid: methods shall be invariant.  */
    method eat(g : Grass) = ()
  }
in
end