Go interface

This article comes from: CSDN blog

Thanks Author: fengfengdiandia

See original: Go Interface

Go Language is not a "traditional" object-oriented programming language: it is not inside and 继承concepts.

But the Go language has a very flexible 接口concept, we can achieve a lot through its 面向对象features.

接口 It defines a  方法的集合, but these methods  不包含实现代码, they are  抽象的, there is also the interface  不能包含变量.

Definition Format

The general format definition of the interface:

type Namer interface {
    Method1(param_list) return_type
    Method2(param_list) return_type
   ...
}

The above  Namer is an interface type.

However, in Go  接口 may have a value, a  接口类型 variable or a  接口值: var ai Namer , ai it is a  multiword data structure, its value is  nil
It's essentially a  指针, though not exactly the same thing. Value is a pointer to the interface 非法的will result in coding errors.

类型(Such as structure) implemented method interface method set achieved  Namer interface types can be assigned to a variable  ai, then the method table pointer points to the interface methods are implemented.

Implementation type of an interface, in addition to the implementation of the interface method, you can also have their own methods.

package main

import "fmt"

type Shaper interface {
    Area() float64
    //  Perimeter() float64
}

type Rectangle struct {
    length float64
    width  float64
}

// Implementation Shaper interface
func (r *Rectangle) Area() float64 {
    return r.length * r.width
}

// Set belongs Rectangle own way
func (r *Rectangle) Set(l float64, w float64) {
    r.length = l
    r.width = w
}

func main() {
    rect := new(Rectangle)
    rect.Set(2, 3)
    areaIntf := Shaper(rect)
    fmt.Printf("The rect has area: %f\n", areaIntf.Area())
}

If you remove  Shaper the  Perimeter() float64 comments, you will encounter the following compile time error, because  Rectangle not implemented  Perimeter() method.

cannot convert rect (type *Rectangle) to type Shaper: *Rectangle does not implement Shaper (missing Perimeter method)

Polymorphism

1, a plurality of types can implement the same interface.  
2, a plurality of types of interfaces may be achieved.

Here we add a type  Triangle, it is also implemented as  Shaper an interface.

package main

import "fmt"

type Shaper interface {
    Area() float64
    //  Perimeter() float64
}

// ==== Rectangle ====
type Rectangle struct {
    length float64
    width  float64
}

// Implementation Shaper interface
func (r *Rectangle) Area() float64 {
    return r.length * r.width
}

// Set belongs Rectangle own way
func (r *Rectangle) Set(l float64, w float64) {
    r.length = l
    r.width = w
}

// ==== Rectangle End ====

// ==== Triangle ====
type Triangle struct {
    bottom float64
    hight  float64
}

func (t *Triangle) Area() float64 {
    return t.bottom * t.hight / 2
}

func (t *Triangle) Set(b float64, h float64) {
    t.bottom = b
    t.hight = h
}

// ==== Triangle End ====

func main() {
    rect := new(Rectangle)
    rect.Set(2, 3)
    areaIntf := Shaper(rect)
    fmt.Printf("The rect has area: %f\n", areaIntf.Area())

    triangle := new(Triangle)
    triangle.Set(2, 3)
    areaIntf = Shaper(triangle)
    fmt.Printf("The triangle has area: %f\n", areaIntf.Area())
}

  

flexibility

Definition of the interface is more flexible.

Suppose in different types of interfaces, and packages, as long as the type implements all the methods in an interface, then it implements this interface.

Now we will  Shaper define in  shaper 包 the next,  Rectangle and  Triangle the definition on the  test 包 next:

[root@ src]# tree
├── test
│   └── test.go
├── main.go
└── shaper
    └── shaper.go
shaper.go
package shaper

type Shaper interface {
    Area() float64
}
test.go
package test

// ==== Rectangle ====
type Rectangle struct {
    length float64
    width  float64
}

// interface method to achieve Shaper
func (r *Rectangle) Area() float64 {
    return r.length * r.width
}

// Set belongs Rectangle own way
func (r *Rectangle) Set(l float64, w float64) {
    r.length = l
    r.width = w
}

// ==== Rectangle End ====

// ==== Triangle ====
type Triangle struct {
    bottom float64
    hight  float64
}

func (t *Triangle) Area() float64 {
    return t.bottom * t.hight / 2
}

func (t *Triangle) Set(b float64, h float64) {
    t.bottom = b
    t.hight = h
}

// ==== Triangle End ====
// main.go
package main

import (
    "fmt"
    "shaper"
    "test"
)

func main() {
    rect := new(test.Rectangle)
    rect.Set(2, 3)
    areaIntf := shaper.Shaper(rect)
    fmt.Printf("The rect has area: %f\n", areaIntf.Area())

    triangle := new(test.Triangle)
    triangle.Set(2, 3)
    areaIntf = shaper.Shaper(triangle)
    fmt.Printf("The triangle has area: %f\n", areaIntf.Area())
}

Now run  main.go to see the results of it, uh-huh, no problem, ^ _ ^

The rect has area: 6.000000
The triangle has area: 3.000000

 

Nesting Interface

An interface may comprise one or more other interfaces, which corresponds directly to the interfaces of these methods embedded in the outer layer include the same interface.

For example, the interface  File includes  ReadWrite and  Lock all methods, it also has an additional  Close() method.

type ReadWrite interface {
    Read(b Buffer) bool
    Write(b Buffer) bool
}

type Lock interface {
    Lock()
    Unlock()
}

type File interface {
    ReadWrite
    Lock
    Close()
}

  

Type assertion

If I wrote a structure type  MyFile to achieve the above  File interface, how do I know  MyFile whether to implement the  File interface to it?

Usually we use  类型断言 to test at some point  varI whether to include types of  T values:

if v, ok : = varI.(T) ; ok { // checked type assertion
    Process(v)
    return
}
// varI is not of type T

  

If you  v are  varI converting to the type of  T value ok will be  true; otherwise it  v is the type of  T zero value, ok is  false.

// main.go
package main

import "fmt"

type MyFile struct{}

func (m *MyFile) Read() bool {
    fmt.Printf("Read()\n")
    return true
}

// ...
// Let's say I have achieved here Write (), Lock (), Unlock () and Close () method

func main() {
    my := new(MyFile)
    fIntf := File(my)

    // look here, look here
    if v, ok := fIntf.(*MyFile); ok {
        v.Read()
    }
}

The output is: Read ()

If more than one type implements the same interface, such as front  areaIntf, how to test it? 
Then use  type-switch to judge.

type-switch type judgment

switch t := areaIntf.(type) {
case *Rectangle:
    // do something
case *Triangle:
    // do something
default:
    // do something
}

 

Guess you like

Origin www.cnblogs.com/-wenli/p/11803144.html