Про объекты в O'Caml: Объектность там забавная и в каком-то смысле очень оригинальная
Во-первых - типизация там, как и везде статическая.
Во-вторых - при этом там не наследования в обычном смысле
этого слова.
То есть: "объектный тип" (АКА class type - типы, которые приписываются
значениям объектам) - это сигнатура. То есть - список методов,
которые должны быть у объекта + их типы. Ну например -
type p2d = < x : int; y : int >
тип, которому соотвествует любой объект, у которого есть методы x и y,
возвращающие int. Соотвественно - естественным путем возникает
отношение тип-подтип между объектными типами. Оно и заменяет наследование.
Важно не то, как объекты образоывывались, а что они умеют.
Более интересный пример (кажется не выразимый ни в одном из статически
типизированных языкоа):
type eq = < eq : 'a -> bool > as 'a
Тут это тип объекта, у которого есть метод eq, ожидающий получить параметром
объект в точности того же самого типа. Понятно, что трехмерная точка
будет одноврменно и двумерной, но сравнение на = разнородных точек вряд ли уместно.
Наследование, конечно, есть, но это конструкция скорее синтаксическая -
вместо использования inherit, можно просто повторить все тоже самое
руками. Результат, за исключением тонких нюансов, отличаться не будет:
class p2d (x:int) (y:int) = object (self:'self)
method x = x
method y = y
method eq (a: 'self) = self#x = a#x && self#y = a#y
end
class p3d (x:int) (y:int) (z:int) = object (self:'self)
inherit p2d x y as super
method z = z
method eq (a: 'self) = super#eq (a :> 'self) && self#z = a#z
end
class p3d' (x:int) (y:int) (z:int) = object (self:'self)
method x = x
method y = y
method z = z
method eq (a: 'self) = self#x = a#x && self#y = a#y && self#z = a#z
end
let p2 = new p2d 1 2
let p3_1 = new p3d 1 2 3
let p3_2 = new p3d 1 2 3
let _ = Printf.printf "%b\n" (p3_1#eq p3_2)
Разницы между p3d и p3d' с точки зрения типов нет никакой. Типы
у них идентичны.
Обращу внимание,что
p2#eq p3_1
написать нельзя. Будет
ошибка типизации.
Вот вкратце все.
Как это реализуется (а вызов метода делается за константное время),
будет в следующем номере.