プログラミングについて話すとき、私たちは通常、データを変更したり操作したりする一連の関数を書くことを意味します。オブジェクト指向プログラミング (OOP) は、データを含み、関連する機能がいくつか関連付けられている「オブジェクト」に焦点を当てたプログラミング モデルです。オブジェクト指向プログラミングには、継承、カプセル化、ポリモーフィズム、抽象化という 4 つの柱があります。このブログでは、Golang でそれぞれを実装する方法を例を挙げて見ていきます。 OOP に関するいくつかの基本的な考え方をお勧めしますが、そうでない場合は、4 つの柱すべてが何を意味するのかについて簡単に説明します。
クラス、オブジェクト、メソッド
オブジェクト指向プログラミングの核となる考え方は、次の箇条書きに要約できます。
- データとそのデータに対して呼び出すことができる関数のコレクションである「クラス」を定義します。
- これらの特定の関数は、その特定のクラスの「メソッド」と呼ばれます。
- クラスの実際のインスタンスは「オブジェクト」と呼ばれます。
これら 3 つの概念を理解するために、Golang のコードを見てみましょう:
package main import "fmt" type Batman struct { actor string year int } func (b Batman) SayImBatman() { fmt.Printf("I'm %s and I'm Batman from year %d\n", b.actor, b.year) } func main() { b1 := Batman{actor: "Michael Keaton", year: 1989} b2 := Batman{actor: "Christian Bale", year: 2005} b1.SayImBatman() b2.SayImBatman() }
Golang では、クラスは私たちが定義した型にすぎません。これらの型は必ずしも構造体である必要はありませんが、OOP では任意の型 (文字列、整数など) のデータのコレクションを扱うため、通常は構造体になります。
クラスはオブジェクトの設計図です。クラスをインスタンス化するたびに、オブジェクトが形成されます。この例では、b1 と b2 は Batman クラスのオブジェクトです。
SayImBatman 関数は、クラスの任意のオブジェクトに対して呼び出すことができます。これは Batman クラスに関連付けられているため、通常の関数と呼ぶのではなく、クラスのメソッドと呼ばれます。
これで OOP の基本が十分に理解できたので、次のセクションに進んで OOP の 4 つの柱について説明する必要があると思います。
継承
継承では、OOP の 親 クラスと 子 クラスの概念が導入されます。子クラスは親クラスから派生したクラスであり、そのすべてのメソッドとプロパティ (データ) を継承します。これを理解するのに役立つコードをいくつか見てみましょう:
package main import "fmt" type Hero struct { team string } type Batman struct { Hero name string } type Ironman struct { Hero power int } func (h Hero) SayTeam() { fmt.Println("My Team is", h.team) } func (b Batman) SayImBatman() { fmt.Printf("I'm %s and I'm Batman\n", b.name) } func (i Ironman) SayPowerLevel() { fmt.Printf("I'm Ironman and my powerlevel is %d\n", i.power) } func main() { b1 := Batman{Hero{team: "Justice League"}, "Christian Bale"} i1 := Ironman{Hero{team: "Avengers"}, 23} b1.SayImBatman() b1.SayTeam() i1.SayPowerLevel() i1.SayTeam() }
この例では、バットマンとアイアンマンはヒーローの親クラスの子クラスです。これらは、親クラスのプロパティ (チーム) とそのメソッド (SayTeam) にアクセスできます。 b1 インスタンスと i1 インスタンスを宣言するときにわかるように、親クラスのプロパティと、それぞれのクラスの固有のプロパティを指定します。どちらも、親クラスで定義されている SayTeam メソッドを呼び出すことができます。ただし、それぞれに固有の個別のプロパティとメソッドもあります。
Golang は、合成を使用して (構造体内の構造体を使用して) 継承を実装します。 C や Java などの他の OOP 言語のような、クラスベースの継承が組み込まれていません。
カプセル化
カプセル化は、オブジェクトの内部プロパティを隠し、直接変更できないようにする原則です。代わりに、これらのプロパティを取得および更新するメソッドの提供に依存します。これをよりよく理解するために例を見てみましょう:
package main import "fmt" type Batman struct { actor string year int } func (b Batman) SayImBatman() { fmt.Printf("I'm %s and I'm Batman from year %d\n", b.actor, b.year) } func main() { b1 := Batman{actor: "Michael Keaton", year: 1989} b2 := Batman{actor: "Christian Bale", year: 2005} b1.SayImBatman() b2.SayImBatman() }
package main import "fmt" type Hero struct { team string } type Batman struct { Hero name string } type Ironman struct { Hero power int } func (h Hero) SayTeam() { fmt.Println("My Team is", h.team) } func (b Batman) SayImBatman() { fmt.Printf("I'm %s and I'm Batman\n", b.name) } func (i Ironman) SayPowerLevel() { fmt.Printf("I'm Ironman and my powerlevel is %d\n", i.power) } func main() { b1 := Batman{Hero{team: "Justice League"}, "Christian Bale"} i1 := Ironman{Hero{team: "Avengers"}, 23} b1.SayImBatman() b1.SayTeam() i1.SayPowerLevel() i1.SayTeam() }
Golang では、パッケージからエクスポートされるプロパティとメソッドは大文字で始まります。 utils パッケージでアクターと年を小文字で定義すると、それらを直接変更できないようになります。代わりに、main.go ファイルで見られるように、エクスポートされたメソッド (大文字で始まる) - GetActor、SetActor などを使用して、それらを取得して変更する必要があります。
これがカプセル化の意味です。データへの誤った変更を確実に防ぎ、その代わりにデータを安全に操作する方法を提供します。
異なる点の 1 つは、Batman クラスのすべてのメソッドで、前の例のように値レシーバー Batman の代わりにポインター レシーバー *Batman を使用していることです。これは、Set メソッドで元の構造体を変更できるようにするためです。また、Golang では、一部のメソッドでポインタ レシーバが必要な場合は、一貫性を保つためにすべてのメソッドでポインタ レシーバを使用することがベスト プラクティスです。そのため、Get メソッドは、元の構造体を変更していないにもかかわらず、ポインター レシーバーも使用しています。
また、もう 1 つ注意すべき点は、ポインター レシーバーを使用しているからといって、(&b1).GetActor を実行する必要はないということです。 Golang では、ポインター引数を持つ関数はポインターを受け取る必要がありますが、ポインター レシーバーを持つメソッドは値またはポインターをレシーバーとして受け取ることができます。
TL;DR: GetActor メソッドにはポインター レシーバーがあるため、Golang は自動的に b1.GetActor を (&b1).GetActor に変換しますが、GetActor が通常の関数であった場合には GetActor(b1) を GetActor(&b1) に変換しません。ポインタ引数。
ポリモーフィズムと抽象化
OOP の次の 2 つの柱は、コード サンプルが非常に似ているため、クラブ化できます。ポリモーフィズムとは、2 つの異なるクラスの 2 つの異なるオブジェクトを同じ共通スーパークラスのオブジェクトとして扱うことができるプログラミング手法を指します。つまり、2 つの異なるオブジェクトに対して、それらが同じクラスのオブジェクトであるかのように、同じ関数を呼び出すことができます。これにより、インターフェイスが関与していることがわかり始めるはずです :)
これをよりよく理解するために、いくつかのコードを見てみましょう:
package main import "fmt" type Batman struct { actor string year int } func (b Batman) SayImBatman() { fmt.Printf("I'm %s and I'm Batman from year %d\n", b.actor, b.year) } func main() { b1 := Batman{actor: "Michael Keaton", year: 1989} b2 := Batman{actor: "Christian Bale", year: 2005} b1.SayImBatman() b2.SayImBatman() }
この例では、互いに関連性がないにもかかわらず、StartFight 関数に b1 オブジェクトと i1 オブジェクトの両方を渡すことができます。これが、子クラスが親クラスのメソッドにアクセスできる継承とどのように異なるのかを理解してください。この例では、子クラスと親クラスはありません (また、共有されるメソッドもありません)。代わりに、2 つの異なるオブジェクトが 関数 によって同じものとして扱われます。これはポリモーフィズムと呼ばれます。
さて、これも抽象化の一例として扱うことができます。名前が示すように、抽象化とは、実装の詳細を隠し、代わりに処理を行う関数だけを提供するプログラミング手法です。この例では、個々のヒーローのメソッドがどのように構成されているかを気にする必要はありません。ヒーローのいずれかのファイト機能を使用したい場合はいつでも、StartFight 機能を使用し続けることができます。このようにして、実装の詳細はユーザーから隠されたままとなり、重要な詳細のみが公開されます。
ここでポリモーフィズムに戻りますが、さらに 2 つの一般的な例があります。それらはメソッドのオーバーライドとオーバーロードです。
メソッドのオーバーライド
メソッドのオーバーライドとは、親クラスで定義されたメソッドの独自の実装を定義する子クラスを指します。この実装は、元の親クラスの実装の代わりに使用されるようになりました。先ほど継承に使用したコードを取り上げ、メソッドのオーバーライドでどのように見えるかを見てみましょう:
package main import "fmt" type Hero struct { team string } type Batman struct { Hero name string } type Ironman struct { Hero power int } func (h Hero) SayTeam() { fmt.Println("My Team is", h.team) } func (b Batman) SayImBatman() { fmt.Printf("I'm %s and I'm Batman\n", b.name) } func (i Ironman) SayPowerLevel() { fmt.Printf("I'm Ironman and my powerlevel is %d\n", i.power) } func main() { b1 := Batman{Hero{team: "Justice League"}, "Christian Bale"} i1 := Ironman{Hero{team: "Avengers"}, 23} b1.SayImBatman() b1.SayTeam() i1.SayPowerLevel() i1.SayTeam() }
このプログラムの出力は次のとおりです:
//oops-in-go/utils/utils.go package utils type Batman struct { actor string year int } func (b *Batman) GetActor() string { return b.actor } func (b *Batman) GetYear() int { return b.year } func (b *Batman) SetActor(actor string) { b.actor = actor } func (b *Batman) SetYear(year int) { b.year = year }
Batman クラスのオブジェクトは、親 Hero クラスのメソッドではなく、独自の SayTeam メソッドを使用するようになりました。 Ironman クラスには独自の SayTeam メソッドがないため、そのオブジェクトは依然として親クラスのメソッドを使用します。これがメソッドのオーバーライドを意味し、子クラスが親クラスで定義されたメソッドを「オーバーライド」します。
メソッドのオーバーロード
これは、同じ関数が複数の異なる引数を取ることができることを指します。これらの引数は、数や型が異なる場合があります。 Golang は、これを実現する 2 つの方法を提供します。1 つは可変引数関数を使用する方法、もう 1 つはインターフェイスを使用する方法です。
理解を深めるのに役立つ両方のコードを見てみましょう:
可変引数関数の使用
// oops-in-go/main.go package main import ( "fmt" "oops-in-go/utils" ) func main() { b1 := utils.Batman{} b1.SetActor("Michael Keaton") b1.SetYear(1989) fmt.Printf("I'm %s and I'm Batman from year %d\n", b1.GetActor(), b1.GetYear()) b1.SetActor("Christian Bale") b1.SetYear(2005) fmt.Printf("I'm %s and I'm Batman from year %d\n", b1.GetActor(), b1.GetYear()) }
ここで、任意の 数 の引数を使用して listMembers 関数を「オーバーロード」できます。
インターフェースの使用
package main import "fmt" type Hero interface { Fight() } type Batman struct { weapon string } type Ironman struct { weapon string } func (b Batman) Fight() { fmt.Printf("Batman hits with a %s\n", b.weapon) } func (i Ironman) Fight() { fmt.Printf("Ironman hits with a %s\n", i.weapon) } func StartFight(h Hero) { fmt.Println("Fight has started.") h.Fight() } func main() { b1 := Batman{"Batarang"} i1 := Ironman{"Repulsor rays"} StartFight(b1) StartFight(i1) }
このプログラムの出力は次のとおりです:
package main import "fmt" type Hero struct { team string } type Batman struct { Hero name string } type Ironman struct { Hero power int } func (h Hero) SayTeam() { fmt.Println("My Team is", h.team) } func (b Batman) SayImBatman() { fmt.Printf("I'm %s and I'm Batman\n", b.name) } func (i Ironman) SayPowerLevel() { fmt.Printf("I'm Ironman and my powerlevel is %d\n", i.power) } func (b Batman) SayTeam() { fmt.Printf("I'm Batman and my team is %s\n", b.team) } func main() { b1 := Batman{Hero{team: "Justice League"}, "Christian Bale"} i1 := Ironman{Hero{team: "Avengers"}, 23} b1.SayImBatman() b1.SayTeam() i1.SayPowerLevel() i1.SayTeam() }
ここでは、saySomething メソッドを「オーバーロード」して、さまざまな型の引数を受け取ります。空のインターフェイスを引数として受け取ります。これは任意の型であり、switch case を使用してその型をチェックし、それに応じて出力を出力します。
結論
これが長文だったことは承知しています。もし最後まで読んでいただけたなら、私が本当に幸せであることを知っていただきたいです :) オブジェクト指向プログラミングについて多くの新しいことを学んでいただければ幸いですそしてそれをGolangで実装する方法。私は自分のウェブサイトでさまざまな技術的概念に関するブログを書いています。新しいことを学ぶことに興味がある場合は、ニュースレターに登録することをお勧めします。
以上がGolang のオブジェクト指向プログラミング (OOP) の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

Goの文字列パッケージは、さまざまな文字列操作機能を提供します。 1)文字列を使用して、サブストリングを確認します。 2)文字列を使用して、ストリングをサブストリングスライスに分割します。 3)文字列を通して文字列をマージします。 4)文字列または文字列を使用して、文字列の最初と端でブランクまたは指定された文字を削除します。 5)指定されたすべてのサブストリングを文字列に置き換えます。ReplaceAll。 6)文字列を使用して、hasprefixまたは文字列hassuffixを使用して、文字列の接頭辞または接尾辞を確認します。

GO言語文字列パッケージを使用すると、コードの品質が向上します。 1)文字列を使用して()join()を使用して、パフォーマンスのオーバーヘッドを避けるために、文字列アレイをエレガントに接続します。 2)strings.split()とstrings.contains()を組み合わせて、テキストを処理し、ケースの感度の問題に注意を払います。 3)文字列の乱用を避け、replace()を回避し、多数の置換に正規表現を使用することを検討します。 4)文字列を使用して、ビルダーを使用して、頻繁にスプライシング文字列の性能を向上させます。

GoのBYTESパッケージは、バイトスライスを処理するためのさまざまな実用的な機能を提供します。 1.bites.containsは、バイトスライスに特定のシーケンスが含まれているかどうかを確認するために使用されます。 2.bites.splitは、バイトスライスをスモールピースに分割するために使用されます。 3.bites.joinは、複数のバイトスライスを1つに連結するために使用されます。 4.bites.trimspaceは、バイトスライスのフロントブランクとバックブランクを削除するために使用されます。 5.バイト。エクアルは、2つのバイトスライスが等しいかどうかを比較するために使用されます。 6.bytes.indexは、大規模なスライスでサブスライスの開始インデックスを見つけるために使用されます。

エンコード/binaryPackageIngoisESSENTINESTENTINESTINESTIDANDARDIZEDWAIDTOREADANDWRITEBINIRYDATA、クロスプラットフォームコンパティビティアンドハンドリングの可能性を確保することを確認します

byteSpackageingocialforforhandlingbyteslicesandbuffers、offering foreffisememorymanagementanddatamanipulation.1)Itprovidesは、バイテッツを使用して、n

テキストデータを処理するためのツールを提供し、基本的な文字列から高度な正規表現のマッチングにスプライシングするためのツールを提供するため、Goの「文字列」パッケージに注意する必要があります。 1)「文字列」パッケージは、パフォーマンスの問題を回避するために文字列をスプライスするために使用される結合関数など、効率的な文字列操作を提供します。 2)contensany関数などの高度な関数が含まれており、文字列に特定の文字セットが含まれているかどうかを確認します。 3)交換関数は、文字列のサブストリングを交換するために使用され、交換順序とケースの感度に注意を払う必要があります。 4)分割関数は、セパレーターに従って文字列を分割することができ、しばしば正規表現処理に使用されます。 5)使用するときは、パフォーマンスを考慮する必要があります。

GOでBYTESパッケージをマスターすると、コードの効率と優雅さを向上させることができます。 1)バイナーズパッケージは、バイナリデータの解析、ネットワークプロトコルの処理、およびメモリ管理に不可欠です。 2)bytes.bufferを使用して、バイトスライスを徐々に構築します。 3)BYTESパッケージは、バイトスライスの検索、交換、およびセグメント化の関数を提供します。 4)BYTES.READERタイプは、特にI/O操作でのバイトスライスのデータを読み取るのに適しています。 5)BYTESパッケージは、GoのGarbage Collectorと協力して機能し、ビッグデータ処理の効率を向上させます。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

SecLists
SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

ドリームウィーバー CS6
ビジュアル Web 開発ツール

MinGW - Minimalist GNU for Windows
このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

メモ帳++7.3.1
使いやすく無料のコードエディター
