*vim9class.txt*	For Vim バージョン 9.1.  Last change: 2025 Nov 11


		  VIM リファレンスマニュアル	by Bram Moolenaar


Vim9 のクラス、オブジェクト、インターフェイス、型定義と列挙型。	*vim9-class*

1.  概要			|Vim9-class-overview|
2.  単純なクラス		|Vim9-simple-class|
3.  クラス変数とメソッド	|Vim9-class-member|
4.  抽象クラスを使う		|Vim9-abstract-class|
5.  インターフェイスを使う	|Vim9-using-interface|
6.  さらなるクラスの詳細	|Vim9-class|
7.  型定義			|Vim9-type|
8.  列挙型			|Vim9-enum|

9.  論理的根拠
10. 後でやる

==============================================================================

1. 概要						*Vim9-class-overview*

聞こえのいい呼び名は「オブジェクト指向プログラミング」である。このテーマに関す
る教材はたくさんある。ここでは、あなたが基本をすでに理解していることを前提とし
て、|Vim9| script が提供するものを文書化する。この機能を効果的に使用する方法に
関する役立つヒントも加えている。Vim9 のクラスとオブジェクトは、旧来の Vim
script や従来の関数では使用できない。

基本アイテムはオブジェクト:
- オブジェクトは状態を保存する。これには、それぞれ値を持つことができる 1 つ以
  上の変数が含まれる。
- オブジェクトは、その状態を使用したり操作したりする関数を提供する。これらの関
  数は「オブジェクト上で」呼び出され、これが従来のデータとデータを操作するコー
  ドの分離とは異なる点である。
- オブジェクトには、型付きのメンバー変数とメソッドを備えた明確に定義されたイン
  ターフェイスを持つ。
- オブジェクトはクラスから生成され、すべてのオブジェクトは同じインターフェイス
  を持つ。これは実行時に変更されることはなく、動的なものではない。

オブジェクトはクラスによってのみ生成さる。クラスは以下を提供する:
- コンストラクタとしての new() メソッド、これはクラスのオブジェクトを返す。
  このメソッドはクラス名で呼び出される: MyClass.new()。
- クラスのすべてのオブジェクトで状態を共有する: クラス変数(クラスメンバ)。
- スーパークラスとサブクラス、継承によるクラスの階層。

インターフェイスはオブジェクトのプロパティを指定するために使用される:
- オブジェクトはいくつかのインターフェイスを実装する宣言ができる。
- 同じインターフェイスを実装した異なるオブジェクトを同じように扱うことができ
  る。

クラス階層は単一の継承になる。それ以外の場合は、必要に応じてインターフェイスを
使用すること。

クラスのモデリング ~

好きな方法でクラスをモデル化できる。何を構築しているのかを念頭に置き、現実世界
をモデル化しようとしないこと。これは、特に教師が現実世界のオブジェクトを使用し
てクラス関係を説明するので、モデルが現実世界を反映している必要があると考えるか
もしれず、混乱を招く可能性がある。そうではない！ モデルは目的に合ったものでな
ければならない。

多くの場合、合成(オブジェクトに他のオブジェクトが含まれる)の方が継承(オブジェ
クトが別のオブジェクトを拡張する)よりも優れていることを念頭に置くこと。最適な
クラスモデルを見つけるために時間を無駄にする必要はない。あるいは、正方形が長方
形なのか、それとも長方形が正方形なのかを議論するのは時間の無駄である。それは問
題ではない。


==============================================================================

2.  単純なクラス				*Vim9-simple-class*

簡単な例から始めよう: テキストの位置を保存するクラスだ (これをより効率的に行う
方法は後述する): >

	class TextPosition
	   var lnum: number
	   var col: number

	   def new(lnum: number, col: number)
	      this.lnum = lnum
	      this.col = col
	   enddef

	   def SetLnum(lnum: number)
	      this.lnum = lnum
	   enddef

	   def SetCol(col: number)
	      this.col = col
	   enddef

	   def SetPosition(lnum: number, col: number)
	      this.lnum = lnum
	      this.col = col
	   enddef
	 endclass
<							*object* *Object*
new() メソッドを使用して、このクラスからオブジェクトを作成できる: >

	var pos = TextPosition.new(1, 1)
<
オブジェクト変数 "lnum" と "col" には直接アクセスできる: >

	echo $'The text position is ({pos.lnum}, {pos.col})'
<						    *E1317* *E1327* *:this*
他のオブジェクト指向言語を使用したことがある場合は、Vim ではクラス定義内で宣言
されたオブジェクトのメンバが一貫してプリフィックス "this." で参照されることに
気づくだろう。これは、Java や TypeScript などの言語とは異なる。この命名規則に
より、オブジェクトのメンバを簡単に見つけることができる。また、変数にプリフィッ
クス "this." がない場合、それがオブジェクト変数ではないことが分かる。
								*E1411*
クラス定義の外からオブジェクトのメソッドや変数にアクセスするには、オブジェクト
名の後にドットを付け、その後にメンバを続ける: >

	pos.lnum
	pos.SetCol(10)
<
							*E1405* *E1406*
クラス名を式として使用することはできない。クラス名は、代入の左辺では使用できな
い。

オブジェクト変数の書き込みアクセス ~
						    *read-only-variable*
では、オブジェクト変数を直接変更してみよう: >

	pos.lnum = 9
<							*E1335*
これはエラーになる! デフォルトでは、オブジェクト変数は読み取ることはできても、
設定することはできないからである。TextPosition クラスがそのためのメソッドを提
供しているのはそのためだ: >

	pos.SetLnum(9)

オブジェクト変数の読み取りは許可するが設定は許可しないのが、最も一般的で安全な
方法である。ほとんどの場合、値を使用しても問題はないが、値を設定すると注意が必
要な副作用が発生する可能性がある。この場合、SetLnum() メソッドは行番号が有効か
どうかをチェックし、エラーを返すか、最も近い有効な値を使用する。
					*:public* *public-variable* *E1331*
副作用を気にせず、オブジェクト変数をいつでも変更できるようにしたい場合は、オブ
ジェクト変数をパブリックにすることができる: >

	public var lnum: number
	public var col: number

これで、SetLnum(), SetCol() および SetPosition() メソッドは必要なくなり、
"pos.lnum" を直接設定してもエラーが発生しなくなる。
							*E1326*
存在しないオブジェクト変数を設定しようとすると、エラーが発生する: >
	pos.other = 9
<	E1326: Member not found on object "TextPosition": other ~

							*E1376*
クラス名を使用してオブジェクト変数にアクセスすることはできない。

Protected 変数 ~
					*protected-variable* *E1332* *E1333*
一方、オブジェクト変数をクラスまたはそのサブクラスの外部から直接読み取られたく
ない場合は、オブジェクト変数を保護することができる。これは、名前の前にアンダー
スコアを付けることによって行われる: >

	var _lnum: number
	var _col: number

次に、protected 変数の値を取得するメソッドを提供する必要がある。これらは一般に
ゲッターと呼ばれる。"Get" で始まる名前を使用することをお勧めする: >

	def GetLnum(): number
	   return this._lnum
	enddef

	def GetCol(): number
	   return this._col
	enddef

この例はあまり役に立たない。変数はパブリックでもよいだろう。値を確認するときに
便利である。例えば、行番号を総行数に制限する: >

	def GetLnum(): number
	   if this._lnum > this._lineCount
	      return this._lineCount
	   endif
	   return this._lnum
	enddef
<
Protected メソッド ~
						*protected-method* *E1366*
オブジェクトメソッドを同じクラスの他のメソッドからのみアクセス可能にし、クラス
の外部からは使用しないようにしたい場合は、オブジェクトメソッドを protected に
できる。これを行うには、メソッド名の前にアンダースコアを付ける: >

    class SomeClass
	def _Foo(): number
	  return 10
	enddef
	def Bar(): number
	  return this._Foo()
	enddef
    endclass
<
クラス外の protected メソッドにアクセスすると、エラーが発生する (上記のクラス
を使用した場合): >

    var a = SomeClass.new()
    a._Foo()
<
new() メソッドの単純化 ~
						*new()* *constructor*
|default-constructor| および |multiple-constructors| も参照。

多くのコンストラクタはオブジェクト変数の値を受け取る。したがって、次のようなパ
ターンがよく見られる: >

	 class SomeClass
	   var lnum: number
	   var col: number

	   def new(lnum: number, col: number)
	      this.lnum = lnum
	      this.col = col
	   enddef
	 endclass
<
							*E1390*
このテキストを記述する必要があるだけでなく、各変数の型も 2 回記述されている。
これは非常に一般的なので、new() を記述する短い方法が提供されている: >

	   def new(this.lnum, this.col)
	   enddef

セマンティクスは理解しやすい。"this." を含むオブジェクト変数名を new() の引数
として指定すると、new() 呼び出しで指定された値がそのオブジェクト変数に割り当て
られることを意味する。このメカニズムは Dart 言語から来ている。

new() を使用して変数をパブリックにするこの方法をまとめると、最初のクラス定義よ
りもはるかに短いクラス定義になる: >

	class TextPosition
	   public var lnum: number
	   public var col: number

	   def new(this.lnum, this.col)
	   enddef

	   def SetPosition(lnum: number, col: number)
	      this.lnum = lnum
	      this.col = col
	   enddef
	 endclass

新しいオブジェクトを構築するシーケンスは次のとおり:
1. メモリが割り当てられ、クリアされる。すべての値はゼロ/偽/空でである。
2. 初期化子を持つ宣言されたオブジェクト変数ごとに、式が評価され、変数に割り当
   てられる。これは、変数がクラスで宣言された順序で発生する。
3. "this.name" 形式の new() メソッドの引数が割り当てられる。
4. new() メソッドの本体が実行される。

クラスが親クラスを拡張する場合も、同じことが起こる。2 番目のステップでは、最初
に親クラスのオブジェクト変数が初期化される。親が "super()" または "new()" を呼
び出す必要はない。

							*E1365*
new() メソッドを定義するときは、戻り値の型を指定しないこと。常にクラスのオブ
ジェクトを返す。

new() メソッドは、"_new()" を使用して protected メソッドにすることができる。こ
れは、シングルトン設計パターンをサポートするために使用できる。

							*E1386*
オブジェクトメソッドを呼び出すときは、メソッド名の前にオブジェクト変数名を付け
る必要がある。クラス名を使用してオブジェクトメソッドを呼び出すことはできない。

==============================================================================

3.  クラス変数とメソッド			*Vim9-class-member*

				    *:static* *E1329* *E1337* *E1338* *E1368*
クラスメンバは "static" で宣言される。これらは、定義されているクラス内でプリ
フィックスなしの名前によって使用される: >

	class OtherThing
	   var size: number
	   static var totalSize: number

	   def new(this.size)
	      totalSize += this.size
	   enddef
	endclass
<							*E1340* *E1341*
名前はそのまま使用されるため、メソッドの引数名やローカル変数名による名前のシャ
ドウイングは許可されていない。

					    *E1374* *E1375* *E1384* *E1385*
クラスメンバが定義されているクラスの外にあるクラスメンバにアクセスするには、ク
ラス名のプリフィックスを使用する必要がある。オブジェクトを使用してクラスメンバ
にアクセスすることはできない。

オブジェクトメンバと同様に、名前の最初の文字としてアンダースコアを使用すること
でアクセスを保護することができ、プリフィックス "public" を付けることでアクセス
を公開することができる: >

    class OtherThing
	static var total: number	  # 誰でも読み取り可、クラスのみ書き込
					  # み可
	static var _sum: number	          # クラスのみ読み書き可
	public static var result: number  # 誰でも読み書き可
    endclass
<
							*class-method*
クラスメソッドも "static" で宣言される。クラス変数は使用できるが、オブジェクト
変数にはアクセスできず、"this" キーワードは使用できない。
>
	class OtherThing
	   var size: number
	   static var totalSize: number

	   # 合計サイズをクリアし、以前の値を返す。
	   static def ClearTotalSize(): number
	      var prev = totalSize
	      totalSize = 0
	      return prev
	   enddef
	endclass

クラス内では、クラスメソッドを名前で直接呼び出すことができるが、クラスの外で
は、クラス名がプリフィックスされている必要がある:
`OtherThing.ClearTotalSize()`。また、クラス変数初期化子、ラムダ式、入れ子になっ
た関数といった特殊なコンテキストでは、パブリッククラスメソッドに名前プリフィッ
クスを使用しなければならない:
>
    class OtherThing
	static var name: string = OtherThing.GiveName()

	static def GiveName(): string
	    def DoGiveName(): string
		return OtherThing.NameAny()
	    enddef

	    return DoGiveName()
	enddef

	static def NameAny(): string
	    return "any"
	enddef
    endclass
<

オブジェクトメソッドと同様に、メソッド名の最初の文字としてアンダースコアを使用
することで、アクセスを protected にすることができる: >

    class OtherThing
	static def _Foo()
	    echo "Foo"
	enddef
	def Bar()
	    _Foo()
	enddef
    endclass
<
							*E1370*
Note コンストラクタは "static" として宣言できないことに注意。これらは staticの
ように呼び出されるが、オブジェクトメソッドとして実行される。これらは "this"に
アクセスできる。

拡張クラス内のスーパークラスのクラスメソッドとクラス変数にアクセスするには、定
義クラスの外部からの場合と同様に、クラス名のプリフィックスを使用する必要がある:
>

    vim9script
    class Vehicle
	static var nextID: number = 1000
	static def GetID(): number
	    nextID += 1
	    return nextID
	enddef
    endclass
    class Car extends Vehicle
	var myID: number
	def new()
	    this.myID = Vehicle.GetID()
	enddef
    endclass
<
クラス変数とメソッドは子クラスに継承されない。子クラスは、スーパークラスと同じ
名前の静的変数またはメソッドを宣言できる。メンバが使用されるクラスに応じて、対
応するクラスのメンバが使用される。子クラスのクラスメンバの型は、スーパークラス
のクラスメンバの型とは異なる場合がある。

クラスメソッドまたはオブジェクトメソッド名の 2 重アンダースコア (__) プリフィッ
クスは、将来の使用のために予約されている。

					*object-final-variable* *E1409*
|:final| キーワードを使用すると、クラス変数またはオブジェクト変数を定数にする
ことができる。例: >

    class A
	final v1 = [1, 2]		# final オブジェクト変数
	public final v2 = {x: 1}	# final オブジェクト変数
	static final v3 = 'abc'		# final クラス変数
	public static final v4 = 0z10	# final クラス変数
    endclass
<
final 変数はコンストラクタ関数からのみ変更できる。例: >

    class A
	final v1: list<number>
	def new()
	    this.v1 = [1, 2]
	enddef
    endclass
    var a = A.new()
    echo a.v1
<
Note final 変数の値は変更できることに注意。例: >

    class A
	public final v1 = [1, 2]
    endclass
    var a = A.new()
    a.v1[0] = 6			# OK
    a.v1->add(3)		# OK
    a.v1 = [3, 4]		# Error
<
							*E1408*
final 変数はインターフェイスではサポートされていない。クラスまたはオブジェクト
のメソッドを final にすることはできない。

					*object-const-variable*
|:const| キーワードを使用すると、クラス変数またはオブジェクト変数を作成し、そ
の値を定数にすることができる。例: >

    class A
	const v1 = [1, 2]		# const オブジェクト変数
	public const v2 = {x: 1}	# const オブジェクト変数
	static const v3 = 'abc'		# const クラス変数
	public static const v4 = 0z10	# const クラス変数
    endclass
<
const 変数はコンストラクタ関数からのみ変更できる。例: >

    class A
	const v1: list<number>
	def new()
	    this.v1 = [1, 2]
	enddef
    endclass
    var a = A.new()
    echo a.v1
<
const 変数およびその値は変更できない。例: >

    class A
	public const v1 = [1, 2]
    endclass
    var a = A.new()
    a.v1[0] = 6			# Error
    a.v1->add(3)		# Error
    a.v1 = [3, 4]		# Error
<
							 *E1410*
const 変数はインターフェイスではサポートされていない。クラスまたはオブジェクト
のメソッドを const にすることはできない。

==============================================================================

4.  抽象クラスを使う				*Vim9-abstract-class*

抽象クラスは、少なくとも 1 つのサブクラスのベースを形成する。クラスモデルでは、
いくつかのクラスが共有できる同じプロパティを持っていることがよくあるが、これら
のプロパティを持つクラスにはオブジェクトを作成するための十分な状態がない。サブ
クラスは、オブジェクトの作成に使用する前に、抽象クラスを拡張し、不足している状
態やメソッドを追加する必要がある。

例えば、Shape クラスには色と太さを格納できる。Shape オブジェクトを作成すること
はできない。形状の種類に関する情報が欠落している。Shape クラスは、オブジェクト
を作成できる Square クラスと Triangle クラスのベースとして機能する。例: >

	abstract class Shape
	   var color = Color.Black
	   var thickness = 10
	endclass

	class Square extends Shape
	   var size: number

	   def new(this.size)
	   enddef
	endclass

	class Triangle extends Shape
	   var base: number
	   var height: number

	   def new(this.base, this.height)
	   enddef
	endclass
<
抽象クラスは、new() メソッドがないことを除き、通常のクラスと同じ方法で定義され
る。 *E1359*

					    *abstract-method* *E1371* *E1372*
抽象メソッドは、抽象クラス内でメソッド定義時に "abstract" プリフィックスを使用
することで定義できる: >

	abstract class Shape
	   abstract def Draw()
	endclass
<
抽象クラスの静的メソッドを抽象メソッドにすることはできない。

						*E1404*
インターフェイスメソッドは抽象メソッドにすることはできない。

						*E1373*
抽象クラスを拡張する非抽象クラスは、すべての抽象メソッドを実装する必要がある。
シグネチャ (引数、引数の型、戻り値の型) はまったく同じである必要がある。メソッ
ドの戻り値の型がクラスの場合、そのクラスまたはそのサブクラスの 1 つを拡張メソッ
ドで使用できる。

						*E1431*
抽象スーパークラス内の抽象メソッドは呼び出すことができない。

==============================================================================

5.  インターフェイスを使う			*Vim9-using-interface*

Shape, Square および Triangle を使用した上記の例は、オブジェクトの表面積を計算
するメソッドを追加するとさらに便利になる。そのために、数値を返す 1 つのメソッ
ド Surface() を指定する HasSurface というインターフェイスを作成する。この例は
上記の例を拡張したものである: >

	abstract class Shape
	   var color = Color.Black
	   var thickness = 10
	endclass

	interface HasSurface
	   def Surface(): number
	endinterface

	class Square extends Shape implements HasSurface
	   var size: number

	   def new(this.size)
	   enddef

	   def Surface(): number
	      return this.size * this.size
	   enddef
	endclass

	class Triangle extends Shape implements HasSurface
	   var base: number
	   var height: number

	   def new(this.base, this.height)
	   enddef

	   def Surface(): number
	      return this.base * this.height / 2
	   enddef
	endclass
<
					*E1348* *E1349* *E1367* *E1382* *E1383*
クラスがインターフェイスの実装を宣言した場合、インターフェイスで指定されたすべ
ての項目が同じ型でクラス内に出現する必要がある。

インターフェイス名は型として使用できる: >

	var shapes: list<HasSurface> = [
				Square.new(12),
				Triangle.new(8, 15),
				]
	for shape in shapes
	   echo $'the surface is {shape.Surface()}'
	endfor
<
					*E1378* *E1379* *E1380* *E1387*
インターフェイスには、オブジェクトメソッドと読み取り専用のオブジェクト変数のみ
を含めることができる。インターフェイスには、読み書き可能または protected オブ
ジェクト変数、protected オブジェクトメソッド、クラス変数、およびクラスメソッド
を含めることはできまない。

インターフェイスは、"extends" を使用して別のインターフェイスを拡張できる。サブ
インターフェイスは、スーパーインターフェイスからすべてのインスタンス変数とメ
ソッドを継承する。

関数内でインターフェイスを定義することはできない。	*E1436*

==============================================================================

6.  さらなるクラスの詳細			*Vim9-class* *Class* *class*

クラスの定義 ~
					*:class* *:endclass* *:abstract*
クラスは `:class` と `:endclass` の間で定義される。クラス全体は 1 つのスクリプ
トファイルで定義される。後からクラスに追加することはできない。

クラスは |Vim9| script ファイル内でのみ定義できる。  *E1316*
関数内でクラスを定義することはできない。  *E1429*

スクリプトファイル内に複数のクラスを定義することは可能である。しかし、通常はメ
インクラスを 1 つだけエクスポートする方が良い。型、列挙型、ヘルパークラスを定
義すると便利である。

`:abstract` キーワードをプリフィックスとして付けたり、`:export` を使用したりで
きる。これにより、次のようなバリエーションが得られる: >

	class ClassName
	endclass

	export class ClassName
	endclass

	abstract class ClassName
	endclass

	export abstract class ClassName
	endclass
<
							*E1314*
クラス名は CamelCased にする必要がある。そして、大文字で始める必要がある。これ
により、組み込み型との衝突が回避される。
							*E1315*
クラス名の後に、これらのオプションの項目を使用できる。それぞれ 1 回のみ出現で
きる。これらは任意の順序で出現できるが、この順序が推奨される: >
	extends ClassName
	implements InterfaceName, OtherInterface
	specifies SomeInterface
<
"specifies" 機能は現在実装されていない。

							*E1355* *E1369*
各変数とメソッドの名前は 1 回だけ使用できる。同じ名前で異なる型の引数を持つメ
ソッドを定義することはできない。パブリックと protected のメンバー変数を同じ名
前で使用することはできない。スーパークラスで使用したオブジェクト変数名を子クラ
スで再利用することはできない。

オブジェクト変数の初期化 ~

							*E1430*
変数の型がクラスで明示的に指定されていない場合、クラス定義時に "any" に設定さ
れる。オブジェクトがクラスからインスタンス化されると、変数の型が設定される。

次の予約キーワード名は、オブジェクトまたはクラス変数名として使用できない:
"super", "this", "true", "false", "null", "null_blob", "null_channel",
"null_class", "null_dict", "null_function", "null_job", "null_list",
"null_object", "null_partial" および "null_string"。

クラスを拡張する ~
							*extends*
クラスは他のクラスを拡張できる。 *E1352* *E1353* *E1354*
基本的な考え方は、既存のクラスの上に構築し、それにプロパティを追加することだ。

拡張されたクラスは "base class" (基底クラス) または "super class" (スーパーク
ラス) と呼ばれる。新しいクラスは "child class" (子クラス) と呼ばれる。

基底クラスのオブジェクト変数はすべて子クラスに引き継がれる。(他の言語とは異な
り) それらをオーバーライドすることはできない。

						*E1356* *E1357* *E1358*
基底クラスのオブジェクトメソッドは無効にすることができる。署名 (引数、引数の
型、戻り値の型) はまったく同じである必要がある。メソッドの戻り値の型がクラスの
場合、そのクラスまたはそのサブクラスの 1 つを拡張メソッドで使用できる。基底ク
ラスのメソッドは、先頭に "super." を付けることで呼び出すことができる。

						*E1377*
子クラスのメソッド (パブリックまたは protected) のアクセスレベルは、スーパーク
ラスと同じである必要がある。

基底クラスの他のオブジェクトメソッドは、子クラスによって引き継がれる。

"new" で始まるメソッドを含むクラスメソッドは、オブジェクトメソッドと同様に無効
にすることができる。基底クラスのメソッドは、クラス名 (クラスメソッドの場合) ま
たは "super." のプリフィックスを付けることで呼び出すことができる。

他の言語とは異なり、基底クラスのコンストラクタを呼び出す必要はない。実際に呼び
出すことはできない。基底クラスからの初期化を子クラスでも行う必要がある場合は、
それをオブジェクトメソッドに入れて、すべての constructor() からそのメソッドを
呼び出す。

基底クラスで new() メソッドが指定されていない場合は、自動的に new() メソッドが
作成される。このメソッドは子クラスには引き継がれない。子クラスは独自の new()
メソッドを定義できるが、メソッドがなければ、new() メソッドが自動的に追加され
る。


インターフェイスを実装するクラス ~
					*implements* *E1346* *E1347* *E1389*
クラスは 1 つ以上のインターフェイスを実装できる。"implements" キーワードは 1 回
のみ使用できる *E1350* 。複数のインターフェイスをコンマで区切って指定できる。
各インターフェイス名は 1 回だけ出現できる。 *E1351*

インターフェイスを定義するクラス ~
							*specifies*
クラスは、名前付きインターフェイスを使用して、そのインターフェイス、オブジェク
ト変数およびメソッドを宣言できる。これにより、多くの言語、特に Java で頻繁に行
われる、インターフェイスを個別に指定する必要がなくなった。
TODO: 現時点では実装されていない。

クラス内の項目 ~
						*E1318* *E1325* *E1388*
クラス内では、`:class` と `:endclass` の間に、次の項目を含めることができる:
- オブジェクト変数宣言: >
	var _protectedVariableName: memberType
	var readonlyVariableName: memberType
	public var readwriteVariableName: memberType
- クラス変数宣言: >
	static var _protectedClassVariableName: memberType
	static var readonlyClassVariableName: memberType
	public static var readwriteClassVariableName: memberType
- コンストラクタメソッド: >
	def new(arguments)
	def newName(arguments)
- クラスメソッド: >
	static def SomeMethod(arguments)
	static def _ProtectedMethod(arguments)
- オブジェクトメソッド: >
	def SomeMethod(arguments)
	def _ProtectedMethod(arguments)

オブジェクト変数の場合は、型を指定する必要がある。最善の方法は、": {type}" を
使用してこれを明示的に行うことである。単純な型の場合、"= 123" などの初期化子を
使用することもでき、Vim はその型が数値であると認識する。より複雑な型や、型が不
完全になる場合には、これを行わないこと。
例: >
	var nameList = []
これはリストを指定するが、項目タイプは不明である。より良い使い方: >
	var nameList: list<string>
初期化は必要ない。デフォルトではリストは空である。
							*E1330*
"void", "null" および "v:none" 等、一部の型は使用できない。

組み込みオブジェクトメソッド ~
                                                       *builtin-object-methods*
|empty()|、|len()| および |string()| などの一部の組み込み関数はオブジェクトで
使用できる。オブジェクトは、これらの組み込み関数と同じ名前のメソッドを実装し
て、オブジェクト固有の値を返すことができる。

							*E1412*
以下の組み込みメソッドがサポートされている:
							*object-empty()*
    empty()  |empty()| 関数によって呼び出され、オブジェクトが空かどうかを確認
	     する。このメソッドが存在しない場合は、true が返される。このメソッ
	     ドは引数を受け入れず、真偽値を返す必要がある。
							*object-len()*
    len()    |len()| 関数によって呼び出され、オブジェクトの長さを返す。このメ
	     ソッドがクラスにない場合はエラーが発生し、ゼロが返される。このメ
	     ソッドは引数を受け入れず、数値を返す必要がある。
							*object-string()*
    string() |string()| 関数によって呼び出され、オブジェクトのテキスト表現を取
	     得する。オブジェクトに対する |:echo| コマンドでも使用される。この
	     メソッドがクラスにない場合は、組み込みのデフォルトのテキスト表現
	     が使用される。このメソッドは引数を受け入れず、文字列を返す必要が
	     ある。

							*E1413*
クラスメソッドを組み込みメソッドとして使用することはできない。

インターフェイスの定義 ~
					*Interface* *:interface* *:endinterface*
インターフェイスは `:interface` と `:endinterface` の間で定義される。プリフィッ
クスとして `:export` を付けることができる: >

	interface InterfaceName
	endinterface

	export interface InterfaceName
	endinterface
<							*E1344*
インターフェイスは、クラスと同じようにオブジェクト変数を宣言できるが、初期化子
は必要ない。
							*E1345*
インターフェイスは、引数と戻り値の型を含む `:def` を使用してメソッドを宣言でき
るが、本体や `:enddef` は使用しない。例: >

	interface HasSurface
	   var size: number
	   def Surface(): number
	endinterface

インターフェイス名は大文字で始めなければならない。 *E1343*
"Has" プリフィックスを使うことで、インターフェイス名であることが推測しやすくな
り、それが何を提供するものであるかのヒントを与えることができる。
インターフェイスは |Vim9| script ファイルでのみ定義できる。 *E1342*
インターフェイスは他のインターフェイスを "implement" することはできないが、他
のインターフェイスを "extend" することはできる。 *E1381*

null オブジェクト ~

変数がオブジェクトの型を持つように宣言されているが初期化されていない場合、値は
null になる。この null オブジェクトを使用しようとすると、Vim はどのクラスを使
用することになっていたのかが分からないことがよくある。この場合、Vim は変数名が
正しいかどうかをチェックできず、変数名が無効な場合でも "Using a null object"
エラーが発生する。 *E1360* *E1362*

デフォルトコンストラクタ ~
							*default-constructor*
new() メソッドを使用せずにクラスを定義した場合は、自動的に new() メソッドが定
義される。このデフォルトコンストラクタには、指定された順序ですべてのオブジェク
ト変数の引数が含まれる。したがって、クラスが次のような場合: >

	class AutoNew
	   var name: string
	   var age: number
	   var gender: Gender
	endclass

デフォルトコンストラクタは次のようになる: >

	def new(this.name = v:none, this.age = v:none, this.gender = v:none)
	enddef

"= v:none" のデフォルト値では、引数はオプションとなる。したがって、引数なしで
`new()` を呼び出すこともできる。割り当ては行われず、オブジェクト変数のデフォル
ト値が使用される。これは、デフォルト値を使用した、より便利な例である: >

	class TextPosition
	   var lnum: number = 1
	   var col: number = 1
	endclass

コンストラクタに必須の引数を持たせたい場合は、それを自分で記述する必要がああ
る。例えば、上記の AutoNew クラスで名前を取得する必要がある場合は、次のように
コンストラクタを定義できる: >

	def new(this.name, this.age = v:none, this.gender = v:none)
	enddef
<
デフォルトの new() メソッドを使用する場合、クラス内のオブジェクト変数の順序を
後で変更すると、デフォルトの new() メソッドの呼び出し元もすべて変更する必要が
ある。これを回避するために、new() メソッドを引数なしで明示的に定義することがで
きる。

							*E1328*
Note ここでは "v:none" 以外のデフォルト値を使用できないことに注意。オブジェク
ト変数を初期化したい場合は、それらが宣言されている場所で実行すること。この方法
では、デフォルト値を 1 箇所で確認するだけで済む。

すべてのオブジェクト変数は、アクセス保護されたものを含め、デフォルトのコンスト
ラクタで使用されます。

クラスが別のクラスを拡張する場合、そのクラスのオブジェクト変数が最初に来る。


複数のコンストラクタ ~
						*multiple-constructors*
通常、クラスには new() コンストラクタが 1 つだけある。コンストラクタが同じ引数
を使用して呼び出されることが多い場合は、それらの引数を 2 番目のコンストラクタ
メソッドに入れることでコードを簡素化できる。例えば、黒という色をよく使う場合
は、次のようにする: >

	def new(this.garment, this.color, this.size)
	enddef
	...
	var pants = new(Garment.pants, Color.black, "XL")
	var shirt = new(Garment.shirt, Color.black, "XL")
	var shoes = new(Garment.shoes, Color.black, "45")

毎回色を繰り返す代わりに、それを含むコンストラクタを追加できる: >

	def newBlack(this.garment, this.size)
	   this.color = Color.black
	enddef
	...
	var pants = newBlack(Garment.pants, "XL")
	var shirt = newBlack(Garment.shirt, "XL")
	var shoes = newBlack(Garment.shoes, "9.5")

Note メソッド名は "new" で始まる必要があることに注意。"new()" というメソッドが
ない場合は、他のコンストラクタメソッドがあっても、デフォルトコンストラクタが追
加される。

オブジェクトに変数型 "any" を使用する ~
							*obj-var-type-any*
オブジェクトを保持するために、"any" 型で宣言された変数を使用できる。例:
>
    vim9script
    class A
	var n = 10
	def Get(): number
	    return this.n
	enddef
    endclass

    def Fn(o: any)
	echo o.n
	echo o.Get()
    enddef

    var a = A.new()
    Fn(a)
<
この例では、Vim はコンパイル時に関数 Fn() のパラメータ "o" の型を判別できない。
|Dict| または |Object| 値のいずれかになる。したがって、実行時に型がわかってい
る場合は、オブジェクトメンバー変数とメソッドが検索される。この処理過程は効率的
ではないため、効率を高めるために可能な限りより具体的な型を使用することをお勧め
する。

クラス内のメソッドをコンパイルする ~
							*class-compile*
|:defcompile| コマンドを使用すると、クラスで定義されているすべてのクラスメソッ
ドおよびオブジェクトメソッドをコンパイルできる: >

	defcompile MyClass	# クラス "MyClass" をコンパイルする
	defcompile		# 現在のスクリプト内のクラス群をコンパイルする
<
==============================================================================

7.  型定義					*typealias* *Vim9-type* *:type*

					*E1393* *E1395* *E1396* *E1397* *E1398*
型定義は、型指定に名前をつけることである。これは "型エイリアス" とも呼ばれる。
型エイリアスは、組み込み型が使える場所であればどこでも使うことができる。例: >

    type ListOfStrings = list<string>
    var s: ListOfStrings = ['a', 'b']

    def ProcessStr(str: ListOfStrings): ListOfStrings
	return str
    enddef
    echo ProcessStr(s)
<
							*E1394*
型エイリアスは大文字で始める必要がある。既存の型のみエイリアスできる。

							*E1399*
型エイリアスはスクリプトレベルでのみ作成でき、関数内では作成できない。型エイリ
アスはエクスポートし、スクリプト間で使用できる。

					*E1400* *E1401* *E1402* *E1403* *E1407*
型エイリアスを式として使用することはできない。型エイリアスは代入の左辺では使用
できない。

型エイリアスの名前について、|typename()| 関数はエイリアスされた型を返す: >

    type ListOfStudents = list<dict<any>>
    echo typename(ListOfStudents)
    typealias<list<dict<any>>>
<
==============================================================================

8.  列挙型					*Vim9-enum* *:enum* *:endenum*

						*enum* *E1418* *E1419* *E1420*
列挙型は、値のリストの 1 つを持つことができる型である。例: >

    enum Color
	White,
	Red,
	Green, Blue, Black
    endenum
<
						*enumvalue* *E1422* *E1428*
列挙値はコンマで区切られる。複数の列挙値を 1 行にリストできる。最後の列挙値の
後にコンマを付けてはならない。重複した列挙値は許可されない。

列挙値には、列挙名に続いて値の名前を使用してアクセスする: >

    var a: Color = Color.Blue
<
列挙型はクラスとして扱われ、各列挙値は本質的にそのクラスのインスタンスである。
|new()| メソッドを使用した一般的なオブジェクトのインスタンス化とは異なり、この
方法では列挙型インスタンスを作成できない。

列挙型は |Vim9| script ファイルでのみ定義できる。	*E1414*
列挙型は関数内で定義できない。				*E1435*

							*E1415*
列挙名は大文字で始めなければならない。列挙型内の列挙値の名前は、大文字または小
文字で始めることができる。

							*E1416*
列挙型はインターフェイスを実装できるが、クラスを拡張することはできない: >

    enum MyEnum implements MyIntf
	Value1,
	Value2

	def SomeMethod()
	enddef
    endenum
<
							*enum-constructor*
列挙型内の列挙値オブジェクトは、|new()| メソッドを使用する他のオブジェクトと同
じように構築される。関数を呼び出すのと同じように、引数を列挙値名の後に指定する
ことで、列挙型コンストラクタに引数を渡すことができる。デフォルトのコンストラク
タには引数がない。

							*E1417*
列挙型には、クラス変数、クラスメソッド、オブジェクト変数、およびオブジェクトメ
ソッドを含めることができる。列挙型内のメソッドを |:abstract| メソッドにするこ
とはできない。

次の例は、オブジェクト変数とオブジェクトメソッドを含む列挙型を示している: >

    vim9script
    enum Planet
	Earth(1, false),
	Jupiter(95, true),
	Saturn(146, true)

	var moons: number
	var has_rings: bool
	def GetMoons(): number
	    return this.moons
	enddef
    endenum
    echo Planet.Jupiter.GetMoons()
    echo Planet.Earth.has_rings
<
						*E1421* *E1423* *E1424* *E1425*
列挙型とその値は不変である。数値型または文字列型として使用することはできない。
列挙値は変更可能なインスタンス変数を宣言できる。

						*enum-name* *E1427*
各列挙値オブジェクトには、列挙値の名前を含む "name" インスタンス変数がある。こ
れは読み取り専用の変数である。

						*enum-ordinal* *E1426*
各列挙値には、0 から始まる序数が関連付けられている。列挙値の序数には、インスタ
ンス変数 "ordinal" を使用してアクセスできる。これは読み取り専用の変数である。
Note 列挙型内の列挙値の順序が変更されると、その序数の値も変更されることに注意。

						*enum-values*
列挙型内のすべての値には、列挙型オブジェクトのリストである "values" クラス変数
を使用してアクセスできる。これは読み取り専用の変数である。

例: >
    enum Planet
	Mercury,
	Venus,
	Earth
    endenum

    echo Planet.Mercury
    echo Planet.Venus.name
    echo Planet.Venus.ordinal
    for p in Planet.values
	# ...
    endfor
<
列挙型は、列挙値オブジェクトのクラス変数と、列挙値の名前と列挙値の序数のオブ
ジェクト変数を持つクラスである: >

    enum Planet
	Mercury,
	Venus
    endenum
<
上記の列挙型定義は、以下のクラス定義と同等である: >

    class Planet
      public static final Mercury: Planet = Planet.new('Mercury', 0)
      public static final Venus: Planet = Planet.new('Venus', 1)

      public static const values: list<Planet> = [Planet.Mercury, Planet.Venus]

      public const name: string
      public const ordinal: number
    endclass
<
enum には、通常のクラスと同様にオブジェクト変数とメソッドを含めることができる:
>
    enum Color
	Cyan([0, 255, 255]),
	Magenta([255, 0, 255]),
	Gray([128, 128, 128])

	var rgb_values: list<number>

	def Get_RGB(): list<number>
	    return this.rgb_values
	enddef
    endenum
    echo Color.Magenta.Get_RGB()
<
==============================================================================

9.  論理的根拠

|Vim9| クラスのほとんどの選択肢は、Java, TypeScript, Dart 等の人気のある最近開
発された言語から来ている。構文は、クラス全体を波括弧で囲む代わりに `endclass`
を使用する等、Vim script の動作に合わせて作成されている。

オブジェクト指向言語の一般的な構造の一部は、この種のプログラミングがまだ新し
かったかなり昔に選択されたもので、後に最適ではないことが判明した。この時点まで
に、これらの構造は広く使用されており、それらを変更するという選択肢はなかった。
Vim では、クラスがまったく新しいものであるため、さまざまな選択をする自由があ
る。「古い」言語が使用するものよりも、構文をより単純かつ一貫性のあるものにする
ことができる。あまり流用することなく、既存の言語から知っているものとほとんど同
じになるはずだ。

最近開発された言語の中には、Vim には必要のないあらゆる種類の派手な機能を追加し
ているものもある。しかし、中には私たちが活用したいと思うような素晴らしいアイデ
アもある。
したがって、我々は一般的な言語をベースにし、悪いアイデアに見えるものを削除し、
理解しやすいいくつかの優れた機能を追加することになる。

我々が決断を下す際に用いる主なルール:
- シンプルに。
- 奇をてらわず、他の言語がやっていることをほとんどやる。
- 過去の過ちを避ける。
- ほとんどのことを明白にし、スクリプト作成者が、物事がどのように機能するかを理
  解するためにヘルプを参照する必要をなくす。
- 一貫性を保つ。
- 大規模なプロジェクトではなく、平均的な規模のプラグインを目指すこと。


コンストラクタに new() を使用する ~

多くの言語では、コンストラクタメソッドのクラス名が使用される。欠点は、多くの場
合、名前が長いことだ。また、クラス名を変更する場合は、すべてのコンストラクタメ
ソッドの名前を変更する必要がある。大したことではないが、それでもデメリットはあ
る。

TypeScript などの他の言語では、"constructor()" 等の特定の名前が使用される。そ
の方が良さそうである。しかしながら、"new" または "new()" を使用して新しいオブ
ジェクトを作成することと、"constructor()" との明らかな関係はない。

|Vim9| script の場合 すべてのコンストラクタに同じメソッド名を使用するスクリプ
トは正しい選択であるように思えた。これを new() と呼び出すことで、呼び出し元と
呼び出されるメソッドの関係が明確になる。

コンストラクタのオーバーロードを行わない ~

Vim script では、旧来と |Vim9| の両スクリプトとも、メソッドのオーバーロードは
ない。つまり、異なる種類の引数で同じメソッド名を使用することはできない。した
がって、new() コンストラクタも 1 つだけ存在する。

|Vim9| script では引数が型付けされているため、オーバーロードをサポートできる。
ただし、これはすぐに複雑になる。new() 呼び出しを見て、いくつかの new() メソッ
ドのどれが実際に呼び出されているのかを知るためには、引数の型を調べなければなら
ない。そして、そのためにはかなりの量のコードを検査する必要がある。例えば、引数
の 1 つがメソッドの戻り値である場合、そのメソッドを見つけて、そのメソッドがど
のような型を返しているかを確認する必要がある。

代わりに、すべてのコンストラクタには、"new" で始まる異なる名前を付ける必要があ
る。こうすることで、異なる引数を持つ複数のコンストラクタが可能になり、同時にど
のコンストラクタが使用されているかを確認するのが非常に簡単になる。引数の型も適
切に確認できる。

メソッドのオーバーロードを行わない ~

コンストラクタの場合と同じ理由である。多くの場合、引数の型が明らかではないた
め、実際にどのメソッドが呼び出されているかを把握することが困難になる。メソッド
に別の名前を付けるだけで、型チェックによって意図したとおりに動作することが確認
される。これにより、実際には必要のないポリモーフィズムが排除される。

単一の継承とインターフェイス ~

一部の言語は多重継承をサポートしている。これは場合によっては便利だが、クラスの
動作規則が非常に複雑になる。
代わりに、インターフェイスを使用してサポートされる内容を宣言する方がはるかに簡
単である。非常に人気のある Java 言語はこの方法で実行しており、Vim にはこれで十
分だ。ここでは「シンプルに」ルールが適用される。

クラスがインターフェイスをサポートしていることを明示的に宣言すると、クラスの目
的が簡単に分かる。また、適切な型チェックを行うことも可能になる。インターフェイ
スが変更されると、その変更も変更されたかどうかがチェックされる。メソッドがたま
たま一致したからといって、クラスがインターフェイスを実装しているとみなすメカニ
ズムは脆弱で、分かりにくい問題を引き起こすため、やめておこう。

あらゆる場所で "this.variable" を使用する ~

さまざまなプログラミング言語のオブジェクト変数には、多くの場合、場所に応じてさ
まざまな方法でアクセスできる。曖昧さを避けるために "this." を前置しなければな
らないこともある。通常は "this." なしで宣言される。 これは非常に矛盾しており、
時に混乱を招く。

非常に一般的な問題は、コンストラクタで引数がオブジェクト変数と同じ名前を使用し
ていることである。その場合、これらの変数では "this." を本体に前置する必要があ
るが、他の変数ではその必要はなく、しばしば省略される。
このため、"this." を含む変数と含まない変数が混在することになり、一貫性が失われ
る。

|Vim9| のクラスでは、宣言されたメソッドと変数には常にプリフィックス "this." が
使用される。シンプルで一貫性がある。クラス内部のコードを見る時にも、どの変数参
照がオブジェクト変数で、どれがそうでないかが直接明らかになる。

クラス変数の使用 ~

"static variable" を使ってクラス変数を宣言するのはよくあることで、特に目新しい
ことはない。|Vim9| script では、クラス変数は名前によって直接アクセスできる。
スクリプトローカル変数をメソッド内で使用する方法とよく似ている。オブジェクト変
数には常に "this." を先頭につけてアクセスするので、それがどんな変数なのかもす
ぐに分かる。

TypeScript は、クラス内でもクラス変数名の前にクラス名を付ける。これには 2 つの
問題がある: クラス名はかなり長くなり、かなりのスペースが必要になることと、クラ
ス名が変更されたときに、これらの場所もすべて変更する必要があることだ。

オブジェクト変数とクラス変数の宣言 ~

主な選択肢は、変数宣言のように "var" を使うかどうかである。TypeScript では使用
していない: >
	class Point {
	  x: number;
	  y = 0;
	}

Vim のオブジェクト変数は以下のように宣言できる: >
	class Point
	  this.x: number
	  this.y = 0
	endclass

一部のユーザーは、これは宣言というよりも代入のように見えると指摘した。"var" を
追加し、"this." を省略すると、次のように変更される: >
	class Point
	  var x: number
	  var y = 0
	endclass

また、"static" キーワードを使ってクラス変数を宣言できるようにする必要もある。
ここでは "var" を省略することもできる: >
	class Point
	  var x: number
	  static count = 0
	endclass

または、"static" の前にそれを使う: >
	class Point
	  var x: number
	  var static count = 0
	endclass

あるいは、"static" の後: >
	class Point
	  var x: number
	  static var count = 0
	endclass

この方が "static def Func()" に近い。

"var" を使うか使わないかの明確な好みはない。省略する主な理由は2つある:
1. TypeScript およびその他の一般的な言語では使用されていない。
2. ごちゃごちゃしない。

しかしながら、クラスやオブジェクトの変数やメソッドには、一般的な変数や関数の宣
言構文を再利用するのが一般的である。Vim9 でもメソッドには一般的な関数宣言構文
を再利用している。そのため、一貫性を保つために、これらの宣言では "var" を必要
とする。

"ClassName.new()" を使用してオブジェクトを構築する ~

多くの言語では、オブジェクトの作成に "new" 演算子を使用するが、コンストラクタ
はコマンドではなく引数を持つメソッドとして定義されているため、実際には少し奇妙
である。TypeScript にも "new" キーワードはあるが、メソッドは "constructor()"
と呼ばれており、両者の関係が分かりにくい。

|Vim9| script では、コンストラクタメソッドは new() と呼ばれ、new() として呼び
出される。シンプルで簡単だ。他の言語では "new ClassName()" が使用されるが、
ClassName() メソッドはなく、ClassName というクラス内の別名のメソッドである。か
なり混乱する。


Vim9class のアクセスモード ~
						    *vim9-access-modes*
Vim9class でサポートされる変数アクセスモードとその意味は、
	|public-variable|	どこからでも読み書きできる
	|read-only-variable|	どこからでも読み取れ、クラスおよびサブクラス内
				から書き込みできる
	|protected-variable|	クラスおよびサブクラス内から読み書きできる

メソッドのアクセスモードは似ているが、読み取り専用モードがない。


オブジェクト変数へのデフォルトの読み取りアクセス ~

ユーザーの中には、オブジェクト変数のアクセスルールが非対称であると指摘する人も
いる。まあ、それは意図的だ。値の変更は、値の読み取りとは大きく異なるアクション
である。読み取り操作には副作用はなく、オブジェクトに影響を与えることなく何度で
も実行できる。値を変更すると、多くの副作用が発生する可能性があり、他のオブジェ
クトに影響を与える波及効果も生じる可能性がある。

オブジェクト変数を追加する時、通常はこれについてあまり考えず、ただ型を正しくす
るだけである。通常、値は new() メソッドで設定される。したがって、ほとんどの場
合、デフォルトで読み取りアクセスのみが「機能」する。また、直接書き込むとエラー
が発生するため、本当にそれを許可する必要があるのか疑問に感じる。これは、間違い
の少ないコードを作成するのに役立つ。


アンダースコアを使用してオブジェクト変数を protected にする ~

オブジェクト変数がプライベートの場合、クラス内 (およびサブクラス内) でのみ読み
取りおよび変更でき、クラス外では使用できない。

オブジェクト変数が保護されている場合、その変数はクラス内 (およびサブクラス内)
でのみ読み取りおよび変更でき、クラス外では使用できない。アンダースコアを先頭に
付けることは、それを可視化する簡単な方法である。さまざまなプログラミング言語が
これを推奨している。

もし気が変わって、クラス外からオブジェクト変数にアクセスできるようにしたい場合
は、すべてのアンダースコアを削除する必要がある。
名前はクラス (およびサブクラス) の中にしか現れないため、見つけて変更するのは簡
単である。

逆の方法ははるかに困難である: クラス内のオブジェクト変数の先頭にアンダースコア
を追加して protected にすることは簡単にできるが、他の場所で使用されている場合
は追跡して変更する必要がある。"set" メソッド呼び出しにする必要がある場合があ
る。これは、アクセスを奪うには、そのアクセスが存在するすべての場所に対して作業
を行う必要があるという現実の問題を反映している。

別の方法としては、"public" がアクセスを別の方向に変更するのと同様に、
"protected" キーワードを使用することもできる。まぁ、これはキーワードの数を減ら
すためなのだが。

オブジェクト変数に private はない ~

一部の言語では、オブジェクト変数へのアクセスを制御するいくつかの方法が提供され
ている。
最もよく知られているのは "protected" だが、その意味は言語によって異なる。他に
は "shared", "private", "package" さらには "friend" もある。

これらのルールは人生をより困難にする。多くの人が同じ複雑なコードに取り組むプロ
ジェクトでは、ミスを犯しやすいので、これは当然のことだ。特に、クラスモデルに対
するリファクタリングやその他の変更の場合。

Vim script は、1 人または小規模なチームが作業するプラグインで使用されることが
想定されている。複雑なルールは事態をさらに複雑にするだけであり、ルールによって
提供される追加の安全性は実際には必要ない。アクセスの詳細は指定せず、単純なまま
にしておく。


==============================================================================

10. 後でやる

newSomething() コンストラクタは別のコンストラクタを呼び出すことができるか? 可
能な場合、制限は何?

考えていること:
- クラスのジェネリクス: `class <Tkey, Tentry>`
- 関数のジェネリクス: `def <Tkey> GetLast(key: Tkey)`
- ミックスイン: 役立つかどうかは分からない。簡単にするために省略する。

追加として良さそうなものをいくつか:
- テスト用: モック機構

提供すべき重要なクラスは "Promise" だ。Vim はシングルスレッドであるため、非同
期操作を接続することは、ユーザーをブロックすることなくプラグインが作業を実行で
きるようにする自然な方法である。これは、コールバックを呼び出し、タイムアウトや
エラーを処理するための統一された方法である。


 vim:tw=78:ts=8:noet:ft=help:norl:
