3.6 プライベートメソッド

プライベートメソッドとはオブジェクトのインタフェースに現れないメソッドです。プライベートメソッドは同じオブジェクトの他のメソッドからのみ呼び出すことができます。

#class restricted_point x_init =
   object (self)
     val mutable x = x_init
     method get_x = x
     method private move d = x <- x + d
     method bump = self move 1
   end;;
class restricted_point :
  int ->
  object
    val mutable x : int
    method bump : unit
    method get_x : int
    method private move : int -> unit
  end

#let p = new restricted_point 0;;
val p : restricted_point = <obj>

#p#move 10;;
This expression has type restricted_point
It has no method move

#p#bump;;
- : unit = ()
    

これは Java や C++ のプライベートメソッドやプロテクテッドメソッドとは異なることに注意してください。 Java や C++ では同じクラスの別のオブジェクトからも呼ひ出せますが、 Objective Caml では呼び出せません。これは、 Objective Caml では型とクラスが独立していることによるものです。無関係のクラスが同じ型のオブジェクトを生成することができるので、型レベルでオブジェクトが同じクラスから生成されたか確かめることができません。しかし、3.17節で述べるように friend メソッドを実現することはできます。

後で述べるようにシグネチャによって隠蔽しない限り、プライベートメソッドは継承され、子クラスから呼び出すことができます。

プライベートメソッドは、子クラスで公開することもできます。

#class point_again x =
   object (self)
     inherit restricted_point x
     method virtual move : _
   end;;
class point_again :
  int ->
  object
    val mutable x : int
    method bump : unit
    method get_x : int
    method move : int -> unit
  end
    

ここで virtual が用いられているのは、メソッドをその定義をあたえることなく言及するためです。 private キーワードを用いなかったのでメソッドは公開され、その定義は親クラスのものが用いられます。

次のような定義を用いることもできます。

#class point_again x =
   object (self : < move : _; ..> )
     inherit restricted_point x
   end;;
class point_again :
  int ->
  object
    val mutable x : int
    method bump : unit
    method get_x : int
    method move : int -> unit
  end
    

self の型が move メソッドが公開されていることを示しています。これでプライベートメソッドを公開することができます。

プライベートメソッドは子クラスでも公開されるべきでないと考えるかも知れません。しかし、プライベートメソッドは子クラスから呼び出すことはできるので、結局プライベートメソッドを呼び出す公開メソッドはいつでも定義できます。例えば次のようにすることができます。

#class point_again x =
   object
     inherit restricted_point x as super
     method move = super#move 
   end;;
class point_again :
  int ->
  object
    val mutable x : int
    method bump : unit
    method get_x : int
    method move : int -> unit
  end
    

プライベートメソッドは抽象メソッドでもありえます。このとき、キーワードは method private virtual の順で与えられなければなりません。