2 single: オブジェクト指向プログラミング (OOP); はじめに
4 ====================================
6 ====================================
8 Ring でオブジェクト指向プログラミングのパラダイムを扱う方法を学びます。
22 * Self.属性 および Self.メソッド() の用法
23 * This.属性 および This.メソッド() の用法
26 pair: オブジェクト指向プログラミング (OOP); クラスとオブジェクト
32 このシンタックスで新しいクラスを定義できます。
38 Class <クラス名> [From|<|: <親クラス名>]
46 また、このシンタックスでオブジェクトを作成できます。
52 New <オブジェクト名> [ (init メソッドの仮引数) ] |
53 [ { オブジェクトのデータ、およびメソッドへのアクセス } ] ---> オブジェクト
59 New point { x=10 y=20 z=30 print() }
60 Class Point x y z func print see x + nl + y + nl + z + nl
62 .. note:: { } でオブジェクトのデータとメソッドへアクセスできます。
64 .. tip:: クラス名の直後にクラスの属性を宣言できます。
78 New point # point クラスで新しいオブジェクトを作成
79 { # 新しいオブジェクトの属性、およびメソッドへのアクセス
80 x = 10 # 属性 x へ 10 を設定
81 y = 20 # 属性 y へ 20 を設定
82 z = 30 # 属性 z へ 30 を設定
83 print() # print メソッドの呼び出し
87 Class Point # Point クラスの定義
88 x y z # クラスには属性 x, y および z があります。
89 func print # print メソッドの定義
90 see x + nl + # 属性 x の表示
95 また、別の方法で同じプログラムを書くことができます。
104 Class Point x y z func print see x + nl + y + nl + z + nl
106 .. note:: オブジェクト名の直後にドット演算子を用いるとオブジェクトのメンバへアクセスできます。
108 また、別の方法で同じプログラムを書くことができます。
112 new point { print() }
115 func print see x + nl + y + nl + z + nl
117 .. note:: クラスの属性を宣言する時にクラスの属性へデフォルトの値を設定できます。
119 また、別の方法で同じプログラムを書くことができます。
126 func init p1,p2,p3 x=p1 y=p2 z=p3 print()
127 func print see x + nl + y + nl + z + nl
129 .. note:: 新しいオブジェクトを作成するときに () を用いる init メソッドを直接呼び出せます。
131 また、別の方法で同じプログラムを書くことができます。
135 new point( [ :x = 10 , :y = 20 , :z = 30 ] )
137 func init aPara x = aPara[:x] y = aPara[:y] z = aPara[:z] print()
138 func print see x + nl + y + nl + z + nl
140 .. tip:: メソッドの仮引数を渡すためにハッシュを使用する場合は、
141 オプションの仮引数の作成時、およびハッシュへ追加時は仮引数の順序を変更できます。
144 pair: オブジェクト指向プログラミング (OOP); 括弧を用いたオブジェクトへのアクセス
147 ====================================
149 括弧 { } で、いつでもオブジェクトへアクセスできます。
151 括弧内ではオブジェクトの属性とメソッドを直接使えます。
153 これは New キーワードによるオブジェクトの作成、またはこのシンタックスを必要なときに使えます。
157 オブジェクト名 { オブジェクトのデータ、およびメソッドへのアクセス }
163 See "Creating the Object" + nl
165 See "Using the Object" + nl
172 Class Point x y z func print see x + nl + y + nl + z
174 括弧は関数、またはメソッドの呼び出し時にオブジェクトへアクセスするために使えます。
182 print( o1 { x=10 y=20 z=30 } )
191 括弧とドット演算子を併用して同じ式のオブジェクトへアクセスできます。
200 O1 { x=10 y=20 z=30 }.print()
203 func print see x + nl + y + nl + z
206 pair: オブジェクト指向プログラミング (OOP); コンポジション
211 オブジェクトでは、ほかのオブジェクトの属性を所有できます。
213 アクセスしたいオブジェクトを括弧で入れ子にすることで実現できます。
240 see "Name : " + R1.Name + nl +
241 "Color: " + R1.Color + nl +
242 "P1 : (" + R1.P1.X + "," + R1.P1.Y + ")" + nl +
243 "P2 : (" + R1.P2.X + "," + R1.P2.Y + ")"
262 pair: オブジェクト指向プログラミング (OOP); Setter と Getter
267 オブジェクトの属性を設定 (Setter)、または取得 (Getter) 時に用いるメソッドを定義できます。
290 o1.name = "Mahmoud" see o1.name + nl
292 o1 { name = "Ahmed" see name }
296 name family = "Fayed"
299 see "Message from SetName() Function!" + nl
300 name = value + " " + family
303 see "Message from GetName() Function!" + nl
310 Message from SetName() Function!
311 Message from GetName() Function!
313 Message from SetName() Function!
314 Message from GetName() Function!
318 pair: オブジェクト指向プログラミング (OOP); プライベート属性とメソッド
321 ==========================
323 クラスの本体内では private キーワードの後にプライベートな属性とメソッドを定義できます。
343 o1.increasesalary(1000)
353 see "Name : " + name + nl +
357 see "Salary : " + salary + nl
363 func increasesalary x
373 Error (R27) : Using private attribute from outside the class : salary
374 Error (R26) : Calling private method from outside the class : increasesalary
377 pair: オブジェクト指向プログラミング (OOP); 演算子のオーバーロード
380 ======================
382 クラスオブジェクトで演算子を使用可能にするには、クラスへ **operator** メソッドを追加します。
392 Func operator cOperator,Para
396 関数の演算子は二種類の仮引数を扱います。一つ目は演算子を、二つ目は演算子の後にある第二仮引数を意味します。
402 o1 = new point { x = 10 y = 10 print("P1 : ") }
403 o2 = new point { x = 20 y = 40 print("P2 : ") }
410 func operator cOperator,Para
414 result.x = x + Para.x
415 result.y = y + Para.y
417 result.x = x - Para.x
418 result.y = y - Para.y
423 see cPoint + "X : " + x + " Y : " + y + nl
431 P1+P2 : X : 30 Y : 50
434 この用例は stdlib.ring にある List クラスからの引用です。
438 Func operator cOperator,Para
458 “len” 演算子は制御構造 (for in) で使用されます。
460 “[]” 演算子はリスト項目のアクセスをするときに使用されます。
461 この場合、 & 演算子は数値による参照で文字列などの項目の値を返すときに使用します。
462 よって、項目へアクセスするときに項目の更新ができます。
472 a1 = new BigNumber( "123" )
473 a2 = new BigNumber( "456" )
474 a3 = new BigNumber( "789" )
489 ###==================================
490 Func FuncAdd( num1, num2)
491 Sum = 0 + num1 + num2 ### Para.aData isNumber
492 Sum = "" +Sum ### Para.adata isString
493 return Sum ### クラスからの返値
494 ###===================================
503 ? "INIT aPara: " ? aPara
511 func operator cOperator, Para
512 whatType = Type(Para)
513 ? nl+"WhatType-PARA: "+ whatType ? Para
514 ? nl+"Operator: " ? cOperator ? nl+"PARA: " ? Para ? " ______" ? nl
515 if whatType = "STRING"
517 ? "dataInfo String: " ? dataInfo
518 but whatType = "NUMBER"
520 ? "dataInfo Number: " ? dataInfo
521 else whatType = "OBJECT"
522 dataInfo = "" + para.aData
523 ? "dataInfo OBJECT: " ? dataInfo
525 ? "dataInfo USING: " ? dataInfo
526 ### Para.aData は初めて渡されたときには存在しません (メンバのオブジェクト)。
527 ### "self" が代入されたときの結果は isObject です。
531 answer = FuncAdd( aData, dataInfo )
532 ? nl+"AnswerString - FunAdd aData, dataInfo: " ? answer
533 ### result = Self はオブジェクトであるため、 aData メンバへオブジェクトを代入します
534 result.aData = answer
536 ### Result = Self はオブジェクトです
540 ? nl+"ClassPrint aData: " ? aData
543 pair: オブジェクト指向プログラミング (OOP); 継承
548 From キーワードを使用したクラスの定義で別のクラスからクラスを作成できます。
554 Class <クラス名> [From <親クラスの名前>]
556 super オブジェクトで子クラスから親クラスのメソッドを呼び出せます。
584 see "Name : " + name + nl + "Age : " + age + nl
586 Class Employee from Human
590 see "Job : " + job + nl + "Salary : " + salary + nl
602 pair: オブジェクト指向プログラミング (OOP); 動的属性
607 クラス名末尾に命令を記述すると、新しいオブジェクトが作成されたときに実行します。
613 o1 = new dynamicClass
614 see o1.var5 + nl # 5 を出力
618 cStr = "var" + x + " = " + x
622 .. tip:: 前述の用例では var1, var2, ..., var10 は属性として定義されています。
624 .. tip:: 前述の用例における問題は x および cStr が同じ属性として定義されていることです!
626 .. note:: 文字列内にクラスの定義を記述できます。
627 また、 eval() 関数で文字列を実行するとクラスを定義できます。
630 pair: オブジェクト指向プログラミング (OOP); パッケージ
635 このシンタックスでパッケージ (共通の名前によるクラスのグループ) を作成できます。
652 o1 = new System.output.console
653 o1.print("Hello World")
655 Package System.Output
660 .. note:: パッケージ名にドット演算子を使えます。
662 パッケージ.クラス名 (PackageName.ClassName) という長い名前を入力する代わりに import 命令を使えます。
664 パッケージをインポートする場合は、このパッケージを指定のクラスで直接使えます。
674 Package System.Output
680 pair: オブジェクト指向プログラミング (OOP); オブジェクトの表示
685 see 命令はオブジェクトの状態 (属性と値) を表示します。
691 see new point { x=10 y=20 z=30 }
703 pair: オブジェクト指向プログラミング (OOP); Find() とオブジェクトのリスト
706 =============================
708 Find() 関数はオブジェクトのリスト内部を検索します。
714 Find(List,ItemValue,nColumn,cAttribute) ---> 項目のインデックス
720 myList1 = [new Company {position=3 name="Mahmoud" symbol="MHD"},
721 new Company {position=2 name="Bert" symbol="BRT"},
722 new Company {position=1 name="Ring" symbol="RNG"}
725 see find(mylist1,"Bert",1,"name") + nl
726 see find(mylist1,"Ring",1,"name") + nl
727 see find(mylist1,"Mahmoud",1,"name") + nl
728 see find(mylist1,"RNG",1,"symbol") + nl
729 see find(mylist1,"MHD",1,"symbol") + nl
730 see find(mylist1,"BRT",1,"symbol") + nl
731 see find(mylist1,3,1,"position") + nl
732 see find(mylist1,1,1,"position") + nl
734 see find(mylist1,"test",1,"name") + nl
735 see find(mylist1,"test",0,"name") + nl
736 see find(mylist1,"test",5,"name") + nl
738 class company position name symbol
758 pair: オブジェクト指向プログラミング (OOP); Sort() とオブジェクトのリスト
761 =============================
763 Sort() 関数はオブジェクトの属性に基づきオブジェクトのリストを整列します。
769 Sort(List,nColumn,cAttribute) ---> オブジェクトの属性に基づいて整列されたリスト
776 new Company {position=3 name="Mahmoud" symbol="MHD"},
777 new Company {position=2 name="Bert" symbol="BRT"},
778 new Company {position=8 name="Charlie" symbol="CHR"},
779 new Company {position=6 name="Easy" symbol="FEAS"},
780 new Company {position=7 name="Fox" symbol="EFOX"},
781 new Company {position=5 name="Dog" symbol="GDOG"},
782 new Company {position=4 name="George" symbol="DGRG"},
783 new Company {position=1 name="Ring" symbol="RNG"}
786 see sort(mylist1,1,"name")
787 see copy("*",70) + nl
788 see sort(mylist1,1,"symbol")
789 see copy("*",70) + nl
790 see sort(mylist1,1,"position")
792 class company position name symbol
823 **********************************************************************
848 **********************************************************************
875 pair: オブジェクト指向プログラミング (OOP); Self.属性 と Self.メソッド() の用法
877 Self.属性 と Self.メソッド() の用法
878 ==============================================
880 クラスの範囲内 (クラス名末尾、およびメソッドの前) ならびに、クラスのメソッドは Self.属性 と Self.メソッド() を使えます。
889 see self.x + nl + self.y + nl + self.z + nl
891 .. note:: クラスの属性を定義するために、クラスの範囲内で Self.属性 を使うとクラスの属性はグローバル変数との名前衝突から保護されます。
893 .. tip:: Self.属性 でクラスの属性を定義するときに、同名のグローバル変数が存在する場合は属性の定義は行われずにグローバル変数が使用されます。
895 グローバル変数名と属性名の間で起こる名前衝突については「スコープの規則」をご確認ください。
901 * クラスの範囲内ではグローバル変数へアクセスできます。
902 * 変数定義前に Ring は変数の検索を行い、見つかれば使用します。
904 .. note:: グローバル変数を避けるために Main 関数の使用、および名前を $ から始めてください。
906 .. tip:: 大規模プログラムでは Self.属性 でクラスの保護、およびメンバの定義してください。
910 pair: オブジェクト指向プログラミング (OOP); This.属性 と This.メソッド() の用法
912 This.属性 と This.メソッド() の用法
913 =======================================
915 クラス内にあるメソッドはオブジェクトのスコープへ直接的なアクセスできます。
916 属性の読み書き、またはメソッドの呼び出しでは Self.属性 あるいは Self.メソッド() の使用は不要です。
918 また、括弧 { } でメソッドの内側から別のオブジェクトへアクセスできます。
919 この場合は、現在のオブジェクトの有効範囲は括弧内へ変更されます。
921 括弧内のクラスの属性、およびメソッドへのアクセスする方法はありますか?
923 これは This.属性 と This.メソッド() で実現できます。
936 display(this.x,this.y,this.z)
941 see x + nl + y + nl + z + nl
945 pair: オブジェクト指向プログラミング (OOP); クラス範囲で This を Self として使用
947 クラス範囲で This を Self として使用
948 ====================================
950 クラス範囲とはクラス名の後、およびすべてのメソッドの前に出現する範囲のことです。
952 クラス範囲で This を Self として使えます。
968 this.name = "My Application"
974 ? "Version = " + version
982 Name = My Application
987 .. note:: 弓括弧は現在の有効なオブジェクトを変更しますが、This はクラスを指したままにできます。
989 .. tip:: This と Self には違いがあります。 Self が指している現在の有効なオブジェクトは弓括弧で変更できます。
991 ほとんどの場合、クラス範囲で This あるいは Self を使う必要はないことを覚えていてください。
998 class program name version
1002 .. code-block:: ring
1004 class program name="My Application" version="1.0"
1006 .. note:: 同名で定義されたグローバル変数との衝突を回避するために、クラス範囲で This あるいは Self を使用します。
1010 pair: オブジェクト指向プログラミング (OOP); オブジェクト属性のデフォルト値
1013 ==============================
1015 オブジェクト属性のデフォルト値は NULL です。
1017 Ring では、 NULL 値は空文字列または "NULL" を有する文字列です。
1019 isNULL() 関数で NULL 値を確認できます。
1023 .. code-block:: ring
1025 oProgram = new Program
1028 ? isNULL(oProgram.name)
1029 ? isNULL(oProgram.version)
1030 oProgram { name="My Application" version="1.0" }
1031 ? isNULL(oProgram.name)
1032 ? isNULL(oProgram.version)
1041 .. code-block:: none
1049 name: My Application