This is the 13th day of my participation in the August More Text Challenge. For details, see:August is more challenging

In Go, an interface is a set of method signatures. When a type provides definitions for all the methods in an interface, it is called the implementation interface. It is very similar to OOP. The interface specifies the methods that the type should have, and the type determines how those methods are implemented.

It defines all the common methods together, and any other type that implements these methods implements the interface

An interface defines a set of methods. An object implements an interface if it implements all of its methods.

Interface definition syntax

/* Define the interface */
type interface_name interface {
   method_name1 [return_type]
   method_name2 [return_type]
}

/* Define structure */
type struct_name struct {
   /* variables */
}

/* Implement the interface method */
func (struct_name_variable struct_name) method_name1(a) [return_type] {
   /* method implementation */}...func (struct_name_variable struct_name) method_namen2(a) [return_type] {
   /* method implementation */
}
Copy the code

Example code:

package main

import (
    "fmt"
)

type Phone interface {
    call()
}

type NokiaPhone struct{}func (nokiaPhone NokiaPhone) call(a) {
    fmt.Println("I am Nokia, I can call you!")}type IPhone struct{}func (iPhone IPhone) call(a) {
    fmt.Println("I am iPhone, I can call you!")}func main(a) {
    var phone Phone

    phone = new(NokiaPhone)
    phone.call()

    phone = new(IPhone)
    phone.call()

}
Copy the code

Running result:

I am Nokia, I can call you!
I am iPhone, I can call you!
Copy the code

Example code:

package main

import (
    "fmt"
)


type USB interface {
    Name() string
    PlugIn()
}

type FlashDisk struct {
    name string
}

func (fd FlashDisk)Name(a) string  {
    return fd.name
}

func (fd FlashDisk) PlugIn(a)  {
    fmt.Println(fd.name,"Plug it into the computer.")}type Mouse struct {
    name string
}

func (m Mouse)Name(a) string  {
    return m.name
}

func (m Mouse) PlugIn(a)  {
    fmt.Println(m.name,"Plug in the computer and get ready to work.")}func main(a)  {
    /* Interface: is a method or collection of method declarations. As long as a type has all the declarations for the interface, it implements the interface. There is no need to show which interface the declaration implements. This is called Structural typing. Interface declarations have only method declarations, no method implementations, and no data fields */
     fd := FlashDisk{"U disk"}
     fmt.Println(fd.Name())
     fd.PlugIn()

     m1:=Mouse{"Mouse"}
     fmt.Println(m1.Name())
     m1.PlugIn()
}
Copy the code

Running result:

U drive U drive is connected to the computer. Mouse Mouse connected to the computer, ready to work.Copy the code
  • Interfaces can be implemented by any object
  • An object can implement any number of interfaces
  • Any type implements an empty interface(defined as interface{}), which contains zero methods

Interface values

Example code:

package main

import "fmt"

type Human struct {
    name  string
    age   int
    phone string
}
type Student struct {
    Human  // Anonymous field
    school string
    loan   float32
}
type Employee struct {
    Human   // Anonymous field
    company string
    money   float32
} //Human implements the Sayhi method
func (h Human) SayHi(a) {
    fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
} //Human implements the Sing method
func (h Human) Sing(lyrics string) {
    fmt.Println("La la la la...", lyrics)
} Employee overrides Human's SayHi method
func (e Employee) SayHi(a) {
    fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name,
        e.company, e.phone) //Yes you can split into 2 lines here.
}

// Interface Men is implemented by Human,Student and Employee
// Because all three types implement both methods
type Men interface {
    SayHi()
    Sing(lyrics string)}func main(a) {
    mike := Student{Human{"Mike".25."222-222-XXX"}, "MIT".0.00}
    paul := Student{Human{"Paul".26."111-222-XXX"}, "Harvard".100}
    sam := Employee{Human{"Sam".36."444-222-XXX"}, "Golang Inc.".1000}
    Tom := Employee{Human{"Sam".36."444-222-XXX"}, "Things Ltd.".5000}
    // Define the variable I of type Men
    var i Men
    // I can store Student
    i = mike
    fmt.Println("This is Mike, a Student:")
    i.SayHi()
    i.Sing("November rain")
    // I can also store Employee
    i = Tom
    fmt.Println("This is Tom, an Employee:")
    i.SayHi()
    i.Sing("Born to be wild")
    // Slice Men is defined
    fmt.Println("Let's use a slice of Men and see what happens")
    x := make([]Men, 3)
    //T These three are different types of elements, but they implement the same interface
    x[0], x[1], x[2] = paul, sam, mike
    for _, value := range x {
        value.SayHi()
    }
}
Copy the code

So what values can be stored in an interface? If we define an interface variable, then that variable can hold any type of object that implements that interface. For example, in the example above, we define a variable m of type Men Interface, so m can hold Human, Student, or Employee values

Of course, you can also use Pointers

However, the interface object cannot call the properties of the implementation object

Example code:

package main

import "fmt"

type Run interface{
    start()
    end()
}

type Runner struct {
    name string
}

type Human2 struct {
    Runner
    age int
}

type Pig struct{
    Runner
    Color string
}

func (r Runner) start(a) {
    fmt.Println(r.name,"Start running.")}func (r Runner) end(a)  {
    fmt.Println(r.name,"Stop running.")}// Method override
func (h Human2) start(a)  {
    fmt.Println(h.name, "This year",h.age,"I am old enough to warm up before running. Then start running.")}func main(a)  {
    h1:=Human2{Runner{"Zhang"},30}
    p1:=Pig{Runner{Peppa Pig},"Pink"}
    h1.start()
    h1.end()
    p1.start()
    p1.end()

    fmt.Println("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --")
    // Define an interface type variable that can point to an object that implements the class. Simulation of polymorphic
    var r1 Run
    r1 = h1
    r1.start()
    r1.end()
    fmt.Println(h1.age)
    // fmt.println (r1.age) // Interface type object, can not access the specific subclass object fields

    fmt.Printf("%T,%T\n",h1,r1) // main.Human2,main.Human2

    var r2 Run
    r2 = p1
    r2.start()
    r2.end()


    fmt.Println("-- -- -- -- -- -- -- -- -- -- -- -- --")
    // Create an array: defined as an interface type, but can actually be stored in any subclass object
    arr := [2]Run{h1,p1}
    for _,v := range  arr{
        v.start()
        v.end()
    }

    testRun(p1)
    testRun(r1)

}

func testRun(r Run)  { // Define a function that takes an object of type excuse as an argument.
    fmt.Println("Test runner...")
    r.start()
    r.end()
}

Copy the code

Running result:

Zhang s is 30 years old this year and needs to warm up before running. Then start running. Zhang SAN stops running. Peppa Pig, start running. Peppa Pig stops running. ------------------ Zhang SAN is 30 years old this year and needs to warm up before running. Then start running. Zhang SAN stops running. 30 main.Human2,main.Human2 Peppa Pig, run. Peppa Pig stops running. ------------- Zhang SAN is 30 years old this year and needs to warm up before running. Then start running. Zhang SAN stops running. Peppa Pig, start running. Peppa Pig stops running. Test runners... Peppa Pig, start running. Peppa Pig stops running. Test runners... Zhang s is 30 years old this year and needs to warm up before running. Then start running. Zhang SAN stops running.Copy the code

Parameter of interface function

The variable of interface can hold any object that implements the type of interface, which gives us some extra thought about how we can write functions (including methods) that accept various types of parameters by defining interface parameters.

package main

import (
    "fmt"
)

type sharp interface {
    area() float64
}

type sqrt struct{
    l float64
}

func (s sqrt) area(a) float64 {
    return s.l * s.l
}

type circle struct{
    r float64
}

func (c circle)area(a) float64  {
    return c.r * 3.14 * c.r
}


// Take the interface type as the parameter
func getArea(s sharp)  {
    fmt.Println(s.area())
}


func main(a)  {
    /* Interface as parameter */
     s1:=sqrt{6.5}
     c1:=circle{2.5}

     getArea(s1)
     getArea(c1)


}
Copy the code

Running result:

42.25
19.625
Copy the code