行く語学自習ノート(D)

免責事項:この記事はブロガーオリジナル記事です、続くBY-SAのCC 4.0を著作権契約、複製、元のソースのリンクと、この文を添付してください。
このリンク: https://blog.csdn.net/qq_18800771/article/details/97250277

オブジェクト指向プログラミング:継承、カプセル化、多型、再利用、マルチスレッド、低い結合。

パッケージ:方法によって達成。

継承:匿名フィールドによって達成されます。

多型:インターフェースを介して。

ゴー/匿名のポートフォリオ/組み込み分野での匿名フィールド:

匿名フィールド構造タイプ:匿名のメンバ変数フィールドは、両方のフィールドを継承するフィールド法(以下に詳述する方法)を継承します。

type Person struct{
    name string
    sex byte
    age int
}
type Student struct{
    Person    //匿名字段,只有类型,没有名字。继承字段实现代码复用即继承了Person全部成员
    id int
    addr string
}
func (tmp *Person) PrintInfo(){    //Person实现的方法,通过匿名字段可以被Student调用
    fmt.Printf("name=%s, sex=%c, age=%d\n",tmp.name,tmp.sex,tmp.age)
}

匿名フィールドの初期化:

初期化/完全初期化の順序:

var s1 Student = Student{Person{"tom",'m',18},1,"北京"}
fmt.Printf("s = %+v",s)    //格式化打印:%+v占位,详细输出

指定されたメンバーの初期化は、初期化されていないメンバーは自動的に0に割り当てられています:

s2:=Student{Person:Person{name:"tom"},addr:"北京"}

操作部材:構造と完全に一致

匿名フィールド全体の割り当て:

s1.Person=Person{"tom",'m',18}

同じ名前のフィールドフィールドの匿名治療:

type Person struct{
    name string
    sex byte
    age int
}
type Student struct{
    Person
    id int
    addr string
    name string    //同名字段
}

同じ名前の割り当てフィールド:近接の原則、同名のローカル/グローバル変数のルールと同じ。あなたは、フィールドを見つけられませんでした検索操作を継承した場合に行うには、この遊びの範囲内でこのメンバーを見つけることができれば。同じ名前継承されたフィールドを直接操作フィールドは、次の構文を使用します。明示的な呼び出しを

s1.Person.name = "go"

非匿名フィールド構造:

type Person struct{
    name string
    sex byte
    age int
}
type Student struct{
    Person    //结构体匿名字段
    int        //非结构体匿名字段
    string
}

割り当ての正常な構造に違いは、非匿名フィールド構造を使用しているとき、あなたは直接メンバー名を使用するのではなく、タイプ名を使用することができることに注目すべきではありません。以下のような:

s1.Person
s1.int

型構造ポインタフィールド匿名:

type Student struct{
    *Person    //指针匿名字段
    id int
    addr string
}

匿名ポインタフィールドが初期化されます。ポインタ型全体の印刷の場合にのみメモリアドレス。

直接初期化:

s1 := Student{&Person{"tom",'m',18},1,"北京"}

スペースの割り当ておよび割り当ての初期化:

var s2 Student
s2.Person=new(Person)    //分配空间
s2.name="tom"
s2.sex='m'
s2.age=18
s2.id=1
s2.addr="北京"

方法/メソッドメソッドタイ機能:FUNC(リバイバータイプ)funname(){}

レシーバreciver、結合型タイプ。機能は、受信者のメソッドと呼ばれています。

プロセスのためのプロセスによって、オブジェクト関数を装っ違いについて説明します。

プロセス指向:

func add(a,b int)int{
    return a+b
}
func main(){
    result:=add(1,1)
}

オブジェクト指向:

type long int    //int别名为long
func (tmp long) add(other long) long{    //add方法绑定类型接收者,tmp接收者,就是一个传递参数
    return tmp+other
}
func main(){
    var a long = 2
    result:=a.add(3)    //调用格式:变量名.函数(参数)
}

なお:お互いを受信することはできませんlong int型で、言語は非常に厳格な型チェックで、この時間を移動します。オブジェクト指向の機能は、単に表現の形式を変更しました。

構造型の結合機能メソッドを追加します。

type Person struct{
    name string
    sex byte
    age int
}
func (tmp Person) PrintInfo(){
    fmt.Println(tmp)
}
func main(){
    p:=Person{"tom",'m',18}
    p.PrintInfo()
}

受信者としてのポインタ:

func (p *Person) SetInfo(n string,s byte,a int){
    p.name=n
    p.sex=s
    p.age=a
}
func main(){
    var p2 Person
    (&p2).SetInfo("tom",'m',18)
    p2.PrintInfo()
}

なお:受信者は、元のポインタ型ではなく、オーバーロードされたメソッド/複製定義サポートしていない(受信機の種類を、同じ名前のメソッドをオーバーロードしていません)。

セマンティック値と基準セマンティクス:配信タイプ

値のセマンティクス(コピー):通常の変数としてレシーバ

func (p Person) SetInfoValue(n string,s byte,a int){
    p.name=n
    p.sex=s
    p.age=a
}
func main(){
    s1:=new(Person)
    s1.SetInfoValue("tom",'m',18)
}

受信者のポインタ変数:参照セマンティクス(配信アドレス)

func (p *Person) SetInfoValue(n string,s byte,a int){
    p.name=n
    p.sex=s
    p.age=a
}
func main(){
    s1:=new(Person)
    (&s1).SetInfoValue("tom",'m',18)
}

方法論言語を行く:メソッド定義された変数を呼び出すことができるメソッドのセットです。

ポインタ変数の呼び出し通常の変数:

通常の呼び出し:(* P).SetInfoValue()

内部転換:p.SetInfoValue()を呼び出してポインタP * Pの中に入れ、

ポインタ変数ポインタ変数を呼び出します。

通常の呼び出し:p.SetInfoPointer()

内部変換(* P).SetInfoValue()は最初のP *はPに変換された後、呼び出し

ポインタ変数ポインタ変数を呼び出します。

内部転換:p.SetInfoPointer()最初のP&Pの内側、その後に呼び出します

一般的な変数の呼び出し通常の変数:

通常の呼び出し:p.SetInfoValue()

要約:メソッドのセットにより拘束値の例と(匿名フィールドを持つ)メソッドポインタを呼び出すと、コンパイラは常に、すべてのメソッドを探し、自動変換レシーバ引数。

継承メソッド:メソッドは、他の構造体への匿名の場で継承することができますが、他の構造を直接呼び出すことができます。

書き換え/同じ名前のメソッドを:

type Person struct{
    name string
    sex byte
    age int
}
type Student struct{
    Person
    id int
    addr string
}
func (tmp *Person) PrintInfo(){    //Person实现的方法,通过匿名字段可以被Student调用
    fmt.Printf("name=%s, sex=%c, age=%d\n",tmp.name,tmp.sex,tmp.age)
}
func (tmp *Student) PrintInfo(){    //Srudent实现的同名方法
    fmt.Printfln(tmp)
}

近接、この方法の優先順位範囲の原則:それは同じメソッドを呼び出します。同じ名前の直接操作は、メソッドを継承している場合、明示的な方法が必要とされます。

s.Person.PrintInfo()

メソッド値と表現の方法:

func (p Person) SetInfoValue(){
    fmt.Printf("SetInfoValue: %p, %v\n", &p, p)
}
func (p *Person) SetInfoPointer(){
    fmt.Printf("SetInfoPointer: %p, %v\n", p, p)
}

メソッドの値:関数ポインタを使用して。

p.SetInfoPointer()    //传统调用方式
pFunc:=p.SetInfoPointer    //方法值保存函数入口
pFunc()    //调用函数,不需要再传递接收者,接收者被隐藏

メソッド式:

f1:=(*Person).SetInfoPointer    //显式传递接收者
f1(&p)        //也可去掉&
f2:=(Person).SetInfoValue
f2(p)

言語インタフェースを行く機能がインスタンス化される宣言だけではなく、メソッドの範囲の組み合わせが記載されています。唯一の実装行動に関する。

インタフェースの定義:

type Humaner interface{
    sayhi()        //只有声明,由自定义类型实现
}

インタフェースの実装:

func (tmp *Student) sayhi(){
   }

変数の定義と割り当てをインターフェイス、呼び出します。

var i Humaner
s:=&Student{}
i=s
i.sayhi()    //只要实现了此接口方法的类型,那么这个类型的变量就可以给i赋值,调用自动匹配方法

マルチ状態:パラメータを定義する通常の機能、インターフェイスタイプの機能:

func WhoSayHi(i Humaner){
    i.sayhi()    //只有一个函数,拥有不同表现--多态
}

インタフェースの呼び出し:

WhoSayHi(s)    //普通调用
x:=make([]Humaner, 1)    //创建切片
x[0]=s
for _,data:=range x{    //通过迭代调用
    i.sayhi()
}

インタフェースの継承:

type Humaner interface{    //子集
    sayhi()
}
type Personer interface{    //超集
    Humaner    //匿名字段,继承了sayhi()
    sing(lrc string)    //含有参数的方法
}
func (tem *Student) sayhi(){
}
func (tem *Student) saing(lrc string){
}
func main(){
    var i Personer
    s:=&Student{}
    i=s
    i.sayhi()    //继承的方法
    i.sing("song")
}

インタフェースコンバータ:変数のスーパーセットはのサブセットに変換することができますが、その逆はありません

var iPro Personer    //超集
var i Humaner    //子集
iPro=i    //err
i=iPro

エアインタフェースタイプ:ユニバーサルタイプ、あなたは、任意の型の値を保持することができます。方法はありません、すべての種類は、このインタフェースを実装しています。

var i interfave{}=1
i="abc"
var a []int        //切片空接口
var b []interface{}        //空接口

パラメータは、タイプの空のインタフェース機能であります:

func fun(args ...interface{}){
}    //可以报错0-多个不限类型的参数

アサーション/クエリの種類を入力します。

アサーションの場合タイプ別:

func main(){
    i := make([]interface{}, 3)
	i[0] = 1    //int
    i[1] = "hello go"    //string
    i[3] = Student{}    //struct
    for index, data := range i{        //index返回的是下标,data返回空接口变量
        if value, ok := data.(int); ok==true{        //value返回接口变量本身,ok返回bool类
            fmt.Printf("x[%d] 类型为int,内容为%d\n", index, value)
        }else if value, ok := data.(string); ok==true{
            fmt.Printf("x[%d] 类型为string,内容为%s\n", index, value)
        }else if value, ok := data.(Student); ok==true{
            fmt.Printf("x[%d] 类型为Student,内容为name=%s,id=%d\n", index, value.name, value.id)
        }
}

スイッチアサーションのタイプ別:

for index, data := range i{
    switch value := data.(type){
    case int:
        fmt.Printf("x[%d] 类型为int,内容为%d\n", index, value)
    case string:
        fmt.Printf("x[%d] 类型为string,内容为%s\n", index, value)
    case Student:
        fmt.Printf("x[%d] 类型为Student,内容为name=%s,id=%d\n", index, value.name, value.id)
    }
}

フォーマットされた出力の種類によってアサート:

for index, data := range i{
    fmt.Printf("x[%d]的类型为%T,内容为%v\n", index, value, value)
}    //自动类型的类型断言

 

おすすめ

転載: blog.csdn.net/qq_18800771/article/details/97250277