diff6-10.chapter3.txtこのページは最後に更新されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。 last mod. 2008-08-28 (木) 09:51:18
4c4 < (Chapter written by Jérôme Vouillon and Didier Rémy) --- > (Chapter written by Jérôme Vouillon, Didier Rémy and Jacques Garrigue) 9c9,12 < Caml. --- > Caml. Note that the relation between object, class and type in Objective Caml > is very different from that in main stream object-oriented languages like Java > or C++, so that you should not assume that similar keywords mean the same > thing. 12,26c15,31 < 3.2 Reference to self < 3.3 Initializers < 3.4 Virtual methods < 3.5 Private methods < 3.6 Class interfaces < 3.7 Inheritance < 3.8 Multiple inheritance < 3.9 Parameterized classes < 3.10 Polymorphic methods < 3.11 Using coercions < 3.12 Functional objects < 3.13 Cloning objects < 3.14 Recursive classes < 3.15 Binary methods < 3.16 Friends --- > 3.2 Immediate objects > 3.3 Reference to self > 3.4 Initializers > 3.5 Virtual methods > 3.6 Private methods > 3.7 Class interfaces > 3.8 Inheritance > 3.9 Multiple inheritance > 3.10 Parameterized classes > 3.11 Polymorphic methods > 3.12 Using coercions > 3.13 Functional objects > 3.14 Cloning objects > 3.15 Recursive classes > 3.16 Binary methods > 3.17 Friends > 174c179 < initializers, as decribed below in section 3.3. --- > initializers, as decribed below in section 3.4. 177c182,222 < 3.2 Reference to self --- > 3.2 Immediate objects > *=*=*=*=*=*=*=*=*=*=*= > > > There is another, more direct way to create an object: create it without > going through a class. > The syntax is exactly the same as for class expressions, but the result is a > single object rather than a class. All the constructs described in the rest of > this section also apply to immediate objects. > <<#let p = > # object > # val mutable x = 0 > # method get_x = x > # method move d = x <- x + d > # end;; > val p : < get_x : int; move : int -> unit > = <obj> > > #p#get_x;; > - : int = 0 > > #p#move 3;; > - : unit = () > > #p#get_x;; > - : int = 3 > >> > > Unlike classes, which cannot be defined inside an expression, immediate > objects can appear anywhere, using variables from their environment. > <<#let minmax x y = > # if x < y then object method min = x method max = y end > # else object method min = y method max = x end;; > val minmax : 'a -> 'a -> < max : 'a; min : 'a > = <fun> > >> > > Immediate objects have two weaknesses compared to classes: their types are > not abbreviated, and you cannot inherit from them. But these two weaknesses can > be advantages in some situations, as we will see in sections 3.3 and 3.10. > > > 3.3 Reference to self 208a254,280 > A common problem with self is that, as its type may be extended in > subclasses, you cannot fix it in advance. Here is a simple example. > <<#let ints = ref [];; > val ints : '_a list ref = {contents = []} > > #class my_int = > # object (self) > # method n = 1 > # method register = ints := self :: !ints > # end;; > This expression has type < n : int; register : 'a; .. > > but is here used with type 'b > Self type cannot escape its class > >> > You can ignore the first two lines of the error message. What matters is the > last one: putting self into an external reference would make it impossible to > extend it afterwards. We will see in section 3.12 a workaround to this problem. > Note however that, since immediate objects are not extensible, the problem does > not occur with them. > <<#let my_int = > # object (self) > # method n = 1 > # method register = ints := self :: !ints > # end;; > val my_int : < n : int; register : unit > = <obj> > >> > 211c283 < 3.3 Initializers --- > 3.4 Initializers 247c319 < 3.4 Virtual methods --- > 3.5 Virtual methods 258d329 < # val mutable x = x_init 266d336 < val mutable x : int 274a345 > # val mutable x = x_init 287a359,383 > Instance variables can also be declared as virtual, with the same effect as > with methods. > <<#class virtual abstract_point2 = > # object > # val mutable virtual x : int > # method move d = x <- x + d > # end;; > class virtual abstract_point2 : > object val mutable virtual x : int method move : int -> unit end > > #class point2 x_init = > # object > # inherit abstract_point2 > # val mutable x = x_init > # method get_offset = x - x_init > # end;; > class point2 : > int -> > object > val mutable x : int > method get_offset : int > method move : int -> unit > end > >> > 290c386 < 3.5 Private methods --- > 3.6 Private methods 321a418,423 > Note that this is not the same thing as private and protected methods in > Java or C++, which can be called from other objects of the same class. This is > a direct consequence of the independence between types and classes in Objective > Caml: two unrelated classes may produce objects of the same type, and there is > no way at the type level to ensure that an object comes from a specific class. > However a possible encoding of friend methods is given in section 3.17. 381c483 < 3.6 Class interfaces --- > 3.7 Class interfaces 400,402c502,504 < constrain the type of a class. Both instance variables and concrete private < methods can be hidden by a class type constraint. Public and virtual methods, < however, cannot. --- > constrain the type of a class. Both concrete instance variables and concrete > private methods can be hidden by a class type constraint. Public methods and > virtual members, however, cannot. 434c536 < 3.7 Inheritance --- > 3.8 Inheritance 486c588 < 3.8 Multiple inheritance --- > 3.9 Multiple inheritance 533,534c635,636 < 3.9 Parameterized classes < *=*=*=*=*=*=*=*=*=*=*=*=*= --- > 3.10 Parameterized classes > *=*=*=*=*=*=*=*=*=*=*=*=*=* 565,568c667,680 < A class for polymorphic references must explicitly list the type parameters < in its declaration. Class type parameters are always listed between [ and ]. < The type parameters must also be bound somewhere in the class body by a type < constraint. --- > Note that since immediate objects do not define a class type, the have no > such restriction. > <<#let new_ref x_init = > # object > # val mutable x = x_init > # method get = x > # method set y = x <- y > # end;; > val new_ref : 'a -> < get : 'a; set : 'a -> unit > = <fun> > >> > On the other hand, a class for polymorphic references must explicitly list > the type parameters in its declaration. Class type parameters are always listed > between [ and ]. The type parameters must also be bound somewhere in the class > body by a type constraint. 669c781 < 3.10 Polymorphic methods --- > 3.11 Polymorphic methods 730c842,848 < after the method name), they can be left implicit in class descriptions. --- > after the method name), quantified type variables can be left implicit in class > descriptions. Why require types to be explicit? The problem is that (int -> int > -> int) -> int -> int would also be a valid type for fold, and it happens to be > incompatible with the polymorphic type we gave (automatic instantiation only > works for toplevel types variables, not for inner quantifiers, where it becomes > an undecidable problem.) So the compiler cannot choose between those two types, > and must be helped. 761,764c879,881 < This expression has type < intlist = < empty : bool; fold : 'a. ('a -> int -> 'a) -> 'a -> 'a > < but is here used with type < < empty : bool; fold : (int -> int -> int) -> int -> 'b > --- > This expression has type intlist but is here used with type > < fold : (int -> int -> int) -> int -> 'a; .. > > Types for method fold are incompatible 778c895 < subtyping in method arguments. We have already seen in section 3.7 how some --- > subtyping in method arguments. We have already seen in section 3.8 how some 826c943 < 3.11 Using coercions --- > 3.12 Using coercions 854,856c971,974 < Indeed, narrowing coercions would be unsafe, and could only be combined with < a type case, possibly raising a runtime error. However, there is no such < operation available in the language. --- > Indeed, narrowing coercions without runtime checks would be unsafe. Runtime > type checks might raise exceptions, and they would require the presence of type > information at runtime, which is not the case in the Objective Caml system. For > these reasons, there is no such operation available in the language. 862,863c980 < The domain of a coercion can usually be omitted. For instance, one can < define: --- > The domain of a coercion can often be omitted. For instance, one can define: 874c991 < The object type c is an abbreviation for <m : 'a; n : int> as 'a. Consider --- > The object type c0 is an abbreviation for <m : 'a; n : int> as 'a. Consider 887,891c1004,1009 < c0 = < m : c0; n : int > as 'a < but is here used with type 'a < Type c0 = 'a is not compatible with type 'a < Type c0 = 'a is not compatible with type c1 = < m : c1 > < Only the first object type has a method n. --- > c0 = < m : c0; n : int > > but is here used with type < m : #c1 as 'a; .. > > Type c0 = < m : c0; n : int > is not compatible with type 'a = < m : c1; .. > > > Type c0 = < m : c0; n : int > is not compatible with type c1 = < m : c1 > > The second object type has no method n. 923c1041 < instances of #c are not subtypes of c, as explained in section 3.15. Yet, for --- > instances of #c are not subtypes of c, as explained in section 3.16. Yet, for 947,948c1065,1066 < < as_c : 'a; m : int; n : int; .. > < but is here used with type c = < m : int > --- > < as_c : c; m : int; n : int; .. > > but is here used with type c 994c1112 < class d : object method as_c : c' method m : int method n : int end --- > and d : object method as_c : c' method m : int method n : int end 1017c1135 < 3.12 Functional objects --- > 3.13 Functional objects 1022,1024c1140,1141 < instance variables. The construct {< ... >} returns a copy of ``self'' (that < is, the current object), possibly changing the value of some instance < variables. --- > instance variables. The construct {< ... >} returns a copy of "self" (that is, > the current object), possibly changing the value of some instance variables. 1055c1172 < # method move d = new functional_point (x+d) --- > # method move d = new bad_functional_point (x+d) 1062c1179 < method move : int -> functional_point --- > method move : int -> bad_functional_point 1064,1075d1180 < < #let p = new functional_point 7;; < val p : functional_point = <obj> < < #p#get_x;; < - : int = 7 < < #(p#move 3)#get_x;; < - : int = 10 < < #p#get_x;; < - : int = 7 1085c1190 < 3.13 Cloning objects --- > 3.14 Cloning objects 1110c1215 < val q : < get_offset : int; get_x : int; move : int -> unit > = <obj> --- > val q : point = <obj> 1121c1226 < val q : < get_offset : int; get_x : int; move : int -> unit > = <obj> --- > val q : point = <obj> 1222c1327 < 3.14 Recursive classes --- > 3.15 Recursive classes 1243,1244c1348 < class widget : < window -> object val window : window method window : window end --- > and widget : window -> object val window : window method window : window end 1250c1354 < 3.15 Binary methods --- > 3.16 Binary methods 1354c1458 < 3.16 Friends --- > 3.17 Friends |