ようこそ Golangチュートリアルシリーズ 26に。
サポートオブジェクト指向にそれを行きますか?
移動は完全にオブジェクト指向プログラミング言語ではありません。公式サイトの行く よくある質問 Goはオブジェクト指向言語であるかどうかの回答を、以下に要約されています。
言うことができないということができます。Goはありますが型およびメソッドは、オブジェクト指向のプログラミングスタイルをサポートする、ないタイプの階層はありません。「インターフェース」は、異なるアプローチを提供するという概念に行く、我々は使いやすく、そしてより一般的であると信じています。サブクラスで類似しているが同一ではない(サブクラス)であるネストされた構造であってもよい行きます。また、移動よりも一般的な特性は、C ++やJavaを提供する:サブクラスは、任意のタイプのデータによって定義された、あるいは内蔵タイプ(単純な「箱なし」整数として)ことができます。これは、構造(クラス)に限定されるものではありません。
次のチュートリアルでは、オブジェクト指向プログラミングの概念を実装するために移動を使用する方法について説明します。(Javaなど)他のオブジェクト指向言語と比較すると、移動は多くの異なる特性を持っています。
構造ではなく、クラスを使用します
Goでは、クラスをサポートしていませんが、提供する構造を。構造はに追加することができる方法。運転データと、データのそのような方法は、クラスと同様の効果を達成するために一緒に結合することができます。
理解を深めるために、我々はそれのサンプルを準備する必要があります。
この例では、我々はカスタム作成パッケージを、それは、私たちはより良い構造が効果的にクラスを交換する方法を理解するのに役立ちます。
ワークスペースに行くというファイル作成し oop
たフォルダを。で opp
サブフォルダを再作成します employee
。で employee
内部の、名前の作成 employee.go
ファイルを。
このようなフォルダ構造:
workspacepath -> oop -> employee -> employee.go
設定し employee.go
、以下に示す置き換えコードの内容を。
package employee
import ( "fmt" ) type Employee struct { FirstName string LastName string TotalLeaves int LeavesTaken int } func (e Employee) LeavesRemaining() { fmt.Printf("%s %s has %d leaves remaining", e.FirstName, e.LastName, (e.TotalLeaves - e.LeavesTaken)) }
プログラムでは、最初の行は、ファイルが属することを指定し employee
たパッケージ。7行目は宣言し Employee
た構造を。14行目では、構造が Employee
呼ばれる追加 LeavesRemaining
の方法を。この方法では、休暇の従業員の残りの数を計算して表示します。だから今、私たちは構造やクラスに非常によく似ている結合構造の方法を、持っています。
続く oop
という名前のファイルフォルダを作成します main.go
。
次のように今、ディレクトリ構造は次のとおりです。
workspacepath -> oop -> employee -> employee.go
workspacepath -> oop -> main.go
main.go
次のように内容は以下のとおりです。
package main
import "oop/employee" func main() { e := employee.Employee { FirstName: "Sam", LastName: "Adolf", TotalLeaves: 30, LeavesTaken: 20, } e.LeavesRemaining() }
私たちは、第三行で参照 employee
パッケージ。で main()
(ライン12)、我々は呼び出す メソッドを。Employee
LeavesRemaining()
そのためカスタムパッケージのため、このプログラムは、外出先の遊び場上で実行することはできません。あなたがお住まいの地域を実行することができ、中に workspacepath/bin/oop
入力されたコマンド go install opp
、プログラムがプリントアウトされます:
Sam Adolf has 10 leaves remaining
代わりにコンストラクタの、新しい()関数を使います
私たちは、上記の手順は問題はないように思わ書きますが、いくつかの詳細は、注意が必要があります。我々はゼロの値の定義を見てみると employee
、構造変数は、何が起こるのだろうとき。 main.go
次のようにコンテンツコードが修正されます。
package main
import "oop/employee" func main() { var e employee.Employee e.LeavesRemaining() }
我々の修飾は、ゼロ値を作成することである Employee
構造体変数(ライン6)。プログラムが出力されます:
has 0 leaves remaining
あなたが見ることができるように、使用して Employee
作成された変数のゼロは全く使用されません。これは、合理的な休暇の詳細はありません、法的な名前を持っていません。
Javaのオブジェクト指向言語のように、この問題を解決するために、コンストラクタを使用して。正当なオブジェクトが作成するために、パラメータ化されたコンストラクタを使用する必要があります。
Goではコンストラクタをサポートしていません。ゼロ値の型が利用できない場合、あなたは、このタイプを隠す他のパッケージからの直接アクセスを回避するために、プログラマが必要です。プログラマが提供するべきと呼ばれる 機能を初期化するために必要に応じて、 型の変数を。慣習に従ってを進み、作成する必要があります 名前付きの型の変数の関数を 。これは、コンストラクタに似ています。パケットが行くの慣例に従って、一種類のみが含まれている場合、この関数は名前を付ける必要があります 代わりに 。NewT(parameters)
T
T
NewT(parameters)
New(parameters)
NewT(parameters)
私はいつでも作成された元のコード変更してみましょう employee
時間は、それが利用可能です。
まず第一にすることが許されるべき Employee
非参照を構築した後、作成 New
作成機能 Employee
構造体変数を。で employee.go
、次のコードを入力します。
package employee
import ( "fmt" ) type employee struct { firstName string lastName string totalLeaves int leavesTaken int } func New(firstName string, lastName string, totalLeave int, leavesTaken int) employee { e := employee {firstName, lastName, totalLeave, leavesTaken} return e } func (e employee) LeavesRemaining() { fmt.Printf("%s %s has %d leaves remaining", e.firstName, e.lastName, (e.totalLeaves - e.leavesTaken)) }
我々はいくつかの重要な変更を行いました。我々は入れて Employee
最初の文字を小文字構造を e
つまり、 type Employee struct
に変更しました type employee struct
。この方法により、我々は持っている employee
構造が、それへのアクセスを防ぐために、非参照、他のパッケージとなります。特別なニーズがある場合を除き、すべてのフィールドは、すべての構造を参照することはできません非表示にする必要があります、それはベストプラクティスで行くのです。私たちは、外部のパケットは必要ありませんので employee
フィールドを、私たちは、これらのフィールド参照を任せることはできません。
同様に、我々はまた、修正 LeavesRemaining()
方法を。
今という employee
非参照ので、他のパッケージに直接作成することはできません Employee
変数の型。だから我々は、ライン14内の参照提供することができ New
、必要なパラメータを受信して、新しく作成された返す関数、 employee
構造体変数を。
プログラムはまた、いくつかの必要な変更を必要としますが、今のプログラムを実行するために、どのように現在の変更を理解しています。あなたは現在のプログラムを実行すると、以下のように、コンパイラは、文句を言うだろう:
go/src/constructor/main.go:6: undefined: employee.Employee
私たちがしますので、これはある Employee
非参照に設定するので、コンパイラは型がされていないことを示唆し、文句を言うでしょう main.go
定義。これは、他のパッケージは、簡単のゼロ値を作成することはできません、我々は予想通り、完璧である employee
変数を。我々は使用できないの作成を避けるために、管理 employee
構造体変数を。今作成 employee
唯一の方法は、変数を使用することで New
機能します。
以下に示すように、修正する main.go
内容を。
package main
import "oop/employee" func main() { e := employee.New("Sam", "Adolf", 30, 20) e.LeavesRemaining() }
唯一の変更は、ファイルの行6です。 New
必要なの着信機能変数、我々は新しい作成した employee
構造体変数を。
ここでは変更され、2つのファイルの内容があります。
employee.go
package employee
import ( "fmt" ) type employee struct { firstName string lastName string totalLeaves int leavesTaken int } func New(firstName string, lastName string, totalLeave int, leavesTaken int) employee { e := employee {firstName, lastName, totalLeave, leavesTaken} return e } func (e employee) LeavesRemaining() { fmt.Printf("%s %s has %d leaves remaining", e.firstName, e.lastName, (e.totalLeaves - e.leavesTaken)) }
main.go
package main
import "oop/employee" func main() { e := employee.New("Sam", "Adolf", 30, 20) e.LeavesRemaining() }
プログラムを実行し、その出力は以下となります。
Sam Adolf has 10 leaves remaining
Goはクラスをサポートしていませんが、今、あなたは、理解することができますが、構造はよくクラスを置き換えることができ、およびに New(parameters)
メソッドのシグネチャコンストラクタを置き換えることができます。
この最後のクラスとコンストラクタ上で移動します。私はあなたが幸せにしたいです。