golang中的接口实现(二)

指针类型 vs 值类型实现接口

package main

import (
    "fmt"
)

// 定义接口
type Describer interface {
    Describe()
}

// 定义一个类
type Person struct {
    name string
    age  int
}

// 值类型的Person 实现了 Describe 方法
func (p Person) Describe() {
    fmt.Printf("%s is %d years old
", p.name, p.age)
}

// 定义一个类
type Address struct {
    province string // 省
    city     string // 市
}

// 指针类型的 Address 实现了 Describe方法
func (a *Address) Describe() {
    fmt.Printf("%s省 %s市 
", a.province, a.city)
    fmt.Println("35", &a)
}

func main() {
    var d1 Describer // 接口类型变量
    p1 := Person{"Sheldon", 18}
    d1 = p1 //值类型
    d1.Describe()

    p2 := Person{"Leonard", 20}
    d1 = &p2 // 指针类型
    d1.Describe()

    var d2 Describer
    a1 := Address{"山东", "临沂"}

    //d2 = a1 // tip ①

    d2 = &a1
    d2.Describe()
    a1.Describe()
    return

    // ① &a1(*Address) 实现了 Describe 方法, 而 a1(值类型)没有实现Describe方法, 
    // 所以只有指针类型的 Address 对象可以转换为 Describe 接口对象。

实现多个接口

package main

import "fmt"

// 定义接口1
type Animal interface {
    Eat()
}

// 定义接口2
type People interface {
    Talk()
}

type Man struct {
    name string
    age  int
}
// 实现接口1
func (m Man) Eat() {
    fmt.Println("男人吃东西")
}
// 实现接口2
func (m Man)Talk() {
    fmt.Println("男人讲话")
}

func main() {
    var sheldon Man
    sheldon.Eat()
    sheldon.Talk()
}

接口的嵌套

(go 中没有类似 Java,C# 中的父类这种东西, 但是可以通过嵌入其他接口来创建新的接口.)

type Interface111 interface {
    Method111()
}

type Interface222 interface {
    Method222() int
}

type EmployeeOperations interface {
    Interface111
    Interface222
}

type Employee struct {
}

func (e Employee) Method111() {

}

func (e Employee) Method222() int {
    return 18
}

func main() {
    e := Employee{ }
    var empOp EmployeeOperations = e
    empOp.Method111() // 大接口对象操作方法
    
    var i2 Interface111 = e
    i2.Method111() // 小接口对象操作方法
}

接口零值

type Interface111 interface {
    Method111()
}

func main() {
    var i1 Interface111
    if i1 == nil { ①
        fmt.Printf("i1 is nil and 类型: %T 值: %v
", i1, i1)
        // i1 is nil and 类型: <nil> 值: <nil>
   } else {
        i1.Method111()
    }
}
// ① 使用 nil 接口对象调用方法的话,则程序会 panic, 
// 因为 nil interface既没有底层的值也没有对应的具体类型. 类似于 JAVA 的空指针异常!
原文地址:https://www.cnblogs.com/sweetXiaoma/p/10688018.html