Golang继承中字段及方法的测试

Golang采用嵌入字段来实现继承,由于实现上存在多种可能,这里进行测试,看看Golang的设计思路。

待考察的问题包括:
     嵌入的是结构,还是指针?
     嵌入部分是匿名字段,还是命名字段?
     方法是传值,还是传指针?

最终结论:
     可以嵌入字段,也可以嵌入指针,其特性吻合惯性思维
     无论字段是否指针,无论方法的接收者是否指针,在字段引用时都不区分指针

以下是测试过程

     一共4组不同情形的测试
          结构中有另一个结构,这是最简单的情形
          结构中有一个匿名结构,测试用类型代替字段名,或直接引用
          结构中有指针指向另一个结构
          结构中有匿名指针指向另一个结构

     每组测3个项目
          继承后的引用
          传值方法的继承
          传指针方法的继承

     故一共12个测试



第1组测试
     结构中有另一个结构,这是最简单的情形


package   main
import   "fmt"

type   Person   struct   {
    name   string
    age   int
    tel   string
}

type   Student   struct   {
    person Person   // 有另一个字段
    school   string
}


func   main() {
    anna := new(Student)
    anna.person.name =   "Anna"
    anna.person.tel =   "12345678"
      //anna.school = "mit"
 
    fmt.Printf(   "My name is %s, and my tel number is %s\n" , anna.person.name, anna.person.tel)
 
}


第1.1组测试
     结构中有另一个结构,这是最简单的情形
     测试这种情况下方法的继承

package   main
import   "fmt"

type   Person   struct   {
    name   string
    age   int
    tel   string
}

type   Student   struct   {
    person Person   // 有另一个字段
    school   string
}

//在person上面定义了一个传值的method
func   (p Person) Hello() {
    fmt.Printf( "My name is %s, and my tel number is %s\n" , p.name, p.tel)
}
func   main() {
    anna := new(Student)
    anna.person.name =   "Anna"
    anna.person.tel =   "2345678"
      //anna.school = "mit"
     
        // anna.Hello() // 这是不行的,非匿名字段不能直接引用
      anna.person.Hello()
     
      //fmt.Printf( "My name is %s, and my tel number is %s\n", anna.person.name, anna.person.tel)
}

结论:
     如果字段没有匿名,则相当于中间隔了一层,不能跨越去引用

第1.2组测试
     结构中有另一个结构,这是最简单的情形
     测试这种情况下方法的继承
     但是定义传指针的method

package   main
import   "fmt"

type   Person   struct   {
    name   string
    age   int
    tel   string
}

type   Student   struct   {
    person Person   // 有另一个字段
    school   string
}

//在person上面定义了一个传指针的method
func   (p * Person) Hello() {
    fmt.Printf(   "My name is %s, and my tel number is %s\n" , p.name, p.tel)
}
func   main() {
    anna := new(Student)
    anna.person.name =   "Anna"
    anna.person.tel =   "345678"
      //anna.school = "mit"
    
         // anna.Hello() // 这是不行的,非匿名字段不能直接引用
      anna.person.Hello()
    
      //fmt.Printf( "My name is %s, and my tel number is %s\n", anna.person.name, anna.person.tel)
}

结论:
     没有问题,method传值或传指针没有区别

第2组测试
     结构中有一个匿名结构,测试用类型代替字段名,或直接引用

package   main
import   "fmt"

type   Person   struct   {
    name   string
    age   int
    tel   string
}

type   Student   struct   {
    Person   // 有一个匿名字段
    school   string
}


func   main() {
    anna := new(Student)
    anna.Person.name =   "Anna"   // 用类型代替字段名
    anna.tel =   "123456789"   // 或者直接引用
      //anna.school = "mit"
 
    fmt.Printf(   "My name is %s, and my tel number is %s\n" , anna.Person.name, anna.tel)
 
}



第2.1组测试
     结构中有一个匿名结构
     测试这种情况下方法的继承


package   main
import   "fmt"

type   Person   struct   {
    name   string
    age   int
    tel   string
}

type   Student   struct   {
    Person   // 有另一个字段
    school   string
}

//在person上面定义了一个传值的method
func   (p Person) Hello() {
    fmt.Printf( "My name is %s, and my tel number is %s\n" , p.name, p.tel)
}
func   main() {
    anna := new(Student)
    anna.Person.name =   "Anna"
    anna.tel =   "2345"
      //anna.school = "mit"
     
      anna.Hello()   // 匿名字段,相当于匿名结构直接嵌入,在同一层面
     
      //fmt.Printf( "My name is %s, and my tel number is %s\n", anna.person.name, anna.person.tel)
}

结论:匿名字段,相当于匿名结构直接嵌入,在同一层面

第2.2组测试
     结构中有一个匿名结构
     测试这种情况下方法的继承
     但是定义传指针的method

package   main
import   "fmt"

type   Person   struct   {
    name   string
    age   int
    tel   string
}

type   Student   struct   {
    Person   // 有另一个字段
    school   string
}

//在person上面定义了一个传指针的method
func   (p * Person) Hello() {
    fmt.Printf(   "My name is %s, and my tel number is %s\n" , p.name, p.tel)
}
func   main() {
    anna := new(Student)
    anna.Person.name =   "Anna"
    anna.tel =   "345"
      //anna.school = "mit"
    
      anna.Hello()   // 匿名字段,相当于匿名结构直接嵌入,在同一层面
    
      //fmt.Printf( "My name is %s, and my tel number is %s\n", anna.person.name, anna.person.tel)
}

结论:
     传指针无影响

第3组测试
     结构中有指针指向另一个结构

package   main
import   "fmt"

type   Person   struct   {
    name   string
    age   int
    tel   string
}

type   Student   struct   {
    person * Person   // 指针指向一个字段
    school   string
}


func   main() {
    anna := new(Student)
    anna.person = new(Person)   // 必须,否则panic
    anna.person.name =   "Anna"
    anna.person.age = 22
    anna.person.tel =   "12345"
    anna.school =   "mit"
  
    fmt.Printf(   "My name is %s, and my tel number is %s\n" , anna.person.name, anna.person.tel)
  
}


第3.1组测试
     结构中有指针指向另一个结构
     测试方法的继承

package   main
import   "fmt"

type   Person   struct   {
    name   string
    age   int
    tel   string
}

type   Student   struct   {
    person * Person   // 指针指向一个字段
    school   string
}

//在person上面定义了一个传值的method
func   (p Person) Hello() {
    fmt.Printf( "My name is %s, and my tel number is %s\n" , p.name, p.tel)
}

func   main() {
    anna := new(Student)
    anna.person = new(Person)
    anna.person.name =   "Anna"
    anna.person.tel =   "234567"
     
      anna.person.Hello()   // 匿名字段,相当于匿名结构直接嵌入,在同一层面
     
}

结论:
     非常正常的使用

第3.2组测试
     结构中有指针指向另一个结构
     测试方法的继承
     但是定义传指针的method

package   main
import   "fmt"

type   Person   struct   {
    name   string
    age   int
    tel   string
}

type   Student   struct   {
    person * Person   // 指针指向一个字段
    school   string
}

//在person上面定义了一个传指针的method
func   (p * Person) Hello() {
    fmt.Printf(   "My name is %s, and my tel number is %s\n" , p.name, p.tel)
}

func   main() {
    anna := new(Student)
    anna.person = new(Person)
    anna.person.name =   "Anna"
    anna.person.tel =   "345678"
    
      anna.person.Hello()   // 匿名字段,相当于匿名结构直接嵌入,在同一层面
    
}

结论:
     指针无影响

第4组测试
     结构中有匿名指针指向另一个结构

package   main
import   "fmt"

type   Person   struct   {
    name   string
    age   int
    tel   string
}

type   Student   struct   {
    * Person   // 匿名指针指向一个字段
    school   string
}


func   main() {
    anna := new(Student)
    anna.Person = new(Person)
    anna.Person.name =   "Anna"
      //anna.Person.age = 22
    anna.tel =   "123"
      //anna.school = "mit"
 
    fmt.Printf(   "My name is %s, and my tel number is %s\n" , anna.Person.name, anna.tel)
 
}

结论:
     anna.Person = new(Person) 居然也行
     匿名相当于直接嵌入,在同一层面
     Golang似乎是尽量识别,如果有字段名,包括指针,则必须用字段名,如果是匿名,则可用匿名字段的类型
  
第4.1组测试
     结构中有匿名指针指向另一个结构
     测试方法的继承

package   main
import   "fmt"

type   Person   struct   {
    name   string
    age   int
    tel   string
}

type   Student   struct   {
    * Person   // 匿名指针指向一个字段
    school   string
}


//在person上面定义了一个传值的method
func   (p Person) Hello() {
    fmt.Printf( "My name is %s, and my tel number is %s\n" , p.name, p.tel)
}

func   main() {
    anna := new(Student)
    anna.Person = new(Person)
    anna.Person.name =   "Anna"
    anna.tel =   "23456789"

     
      anna.Person.Hello()   // 匿名字段,相当于匿名结构直接嵌入,在同一层面
      anna.Hello()   // 匿名字段,相当于匿名结构直接嵌入,在同一层面
}

结论
     在同一层面,当然加上匿名指针也可

第4.2组测试
     结构中有匿名指针指向另一个结构
     测试方法的继承
     但是定义传指针的method

package   main
import   "fmt"

type   Person   struct   {
    name   string
    age   int
    tel   string
}

type   Student   struct   {
    * Person   // 匿名指针指向一个字段
    school   string
}


//在person上面定义了一个传指针的method
func   (p * Person) Hello() {
    fmt.Printf(   "My name is %s, and my tel number is %s\n" , p.name, p.tel)
}

func   main() {
    anna := new(Student)
    anna.Person = new(Person)
    anna.Person.name =   "Anna"
    anna.tel =   "34"

    
      anna.Person.Hello()   // 匿名字段,相当于匿名结构直接嵌入,在同一层面
      anna.Hello()   // 匿名字段,相当于匿名结构直接嵌入,在同一层面
}

结论:
     一样使用



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值