2015-05-28 3 views
0

У меня есть некоторый узел с объектами и классами. Я пытаюсь вызвать метод из класса kid в классе, чтобы добавить ребенка в семью в любое время, когда захочу, но я получаю сообщение об ошибке, которое я не понимаю.Ocaml как вызвать метод в одном классе из другого класса

class virtual person name lastName sex = 
    object 
     val name = (name:string) 
     val mutable lastName = (lastName:string) 
     val sex = (sex:char) 
    end;; 

class man name lastName= 
    object 
     inherit person name lastName 'm' 
     method printNameAndLastName = (name^" "^lastName) 
     method changeLastName newLastName = lastName <- newLastName 
     method printLastName = lastName 
end;; 

class woman name lastName = 
    object 
     inherit person name lastName 'w' 
     method printNameAndLastName = (name^" "^lastName) 
     method changeLastName newLastName = lastName <- newLastName 
     method printLastName = lastName 
end;; 

class child name sex= 
    object 
     inherit person name "" 'm' 
     method printNameAndLastName = (name^" "^lastName) 
     method changeLastName newLastName = lastName <- newLastName 
     method printLastName = lastName 
end;; 

class family familyName man woman= 
    object 
     val man = man 
     val woman = woman 
     val mutable kids = ([] :string list) 
     initializer woman#changeLastName (man#printLastName) 
     method addKid kid = kids <- (kid#printLastName)::kids 
     method printFamily = (man#printNameAndLastNAme^", "^woman#printNameAndLastName) 
end;; 



Error: Some type variables are unbound in this type: 
     class family : 
      'a -> 
      (< printLastName : 'c; printNameAndLastNAme : string; .. > as 'b) -> 
      (< changeLastName : 'c -> unit; printNameAndLastName : string; 
       .. > 
      as 'd) -> 
      object 
      val mutable kids : string list 
      val man : 'b 
      val woman : 'd 
      method addKid : < printLastName : string; .. > -> unit 
      method printFamily : string 
      end 
     The method addKid has type 
     (< printLastName : string; .. > as 'e) -> unit 
     where 'e is unbound 

Ошибка при добавлении метода addKid. также последний метод printFamily, я хотел бы добавить к нему список имен детей после того, как имя мужчины и женщины, что делает его выглядеть следующим образом:

  • (строка * строка) * строка списка = ((«мужчина», «женщина»), [«kid1»; «kid2»]).

Я экспериментировал, но я не мог объединить строки со списком, получив ожидаемую ошибку (строка * строка) * string.

Спасибо за Вас время :)

ответ

1

Типы всех значений в классе должны быть связаны с его определением. Например:

# class ident x = object 
    method x = x 
    end;; 
    Characters 6-11: 
    class ident x = object 
     ^^^^^ 
Error: Some type variables are unbound in this type: 
     class ident : 'a -> object method x : 'a end 
     The method x has type 'a where 'a is unbound 

Это означает, что вам нужно или обвил его к конкретному типу:

class ident x = object 
    method x : int = x 
    end;; 
class ident : int -> object method x : int end 

Или сделать свой класс полиморфного и связанное значение вновь введенным переменным типа:

# class ['a] ident x = object 
    method x : 'a = x 
    end;; 
class ['a] ident : 'a -> object method x : 'a end 

В вашем случае man, woman и kid несвязаны. Так, каждый раз, когда вы определяете класс создается одинаково с именем типа, вы можете связали их к man, woman и child (а также исправить опечатку в методе)

class family familyName man woman = 
    object 
     val man : man = man 
     val woman : woman = woman 
     val mutable kids = ([] :string list) 
     initializer woman#changeLastName (man#printLastName) 
     method addKid (kid : child) = kids <- (kid#printLastName)::kids 
     method printFamily = (man#printNameAndLastName^", "^woman#printNameAndLastName) 
end;; 
+0

Я обновил ответ. – ivg

+0

это работает, спасибо. Как насчет последней части, когда я печатаю семью, как я могу напечатать 2 конкатенированные строки + список детей после этого, не делая этого дважды? – minus

+0

Прежде всего, вы не печатаете, а конвертируете в строку. Это другое. Чтобы преобразовать строковый список в строку, вы можете использовать 'String.concat', который также принимает разделитель. Кроме того, использование 'sprintf' (или любой другой функции printf-family) очень полезно. – ivg

Смежные вопросы