Програзм's Journal
 
[Most Recent Entries] [Calendar View] [Friends View]

Monday, November 7th, 2005

    Time Event
    10:59p
    Про объекты в 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
    написать нельзя. Будет
    ошибка типизации.

    Вот вкратце все.

    Как это реализуется (а вызов метода делается за константное время),
    будет в следующем номере.

    << Previous Day 2005/11/07
    [Calendar]
    Next Day >>

About LJ.Rossia.org