高朗界面


接口是抽象类型。

接口描述方法集的所有方法,并提供每个方法的签名。

创建界面使用 接口 关键字,后跟包含方法名称列表的大括号,以及该方法应具有的任何参数或返回值。

// Declare an 接口 Type 和 methods does not have a body
type 雇员 接口 {
	PrintName() string                // Method with string return type
	PrintAddress(id int)              // Method with int parameter
	PrintSalary(b int, t int) float64 // Method with parameters 和 return type
}

接口充当方法集的蓝图,必须在使用它们之前实现它们。据说满足接口的类型可以实现它。


定义满足接口的类型

定义一个名为的接口类型 雇员 有两种方法。然后定义一个名为 Emp 满足 雇员.

我们定义了所有方法 Emp 它需要满足 雇员

package main

import "fmt"

// 雇员 is an 接口 for printing employee details
type 雇员 接口 {
	PrintName(name string)
	PrintSalary(basic int, tax int) int
}

// Emp  user-defined type
type Emp  int

// PrintName method to print employee name
func (e Emp ) PrintName(name string) {
	fmt.Println("雇员 Id:\t", e)
	fmt.Println("雇员 Name:\t", name)
}

// PrintSalary method to calculate employee salary
func (e Emp ) PrintSalary(basic int, tax int) int {
	var salary = (basic * tax) / 100
	return basic - salary
}

func main() {
	var e1 雇员
	e1 = Emp (1)
	e1.PrintName("John Doe")
	fmt.Println("雇员 Salary:", e1.PrintSalary(25000, 5))
}

如果类型具有在接口中声明的所有方法,则无需进一步的声明即可明确地指出 Emp 满足 雇员.

声明一个 e1 可变 雇员 作为其类型,然后创建一个 Emp 值并将其分配给 e1.


定义满足多个接口的类型

接口允许任何用户定义的类型一次满足多种接口类型。

使用 类型断言 您可以返回一个具体类型的值,并且可以在其上调用在其他接口上定义的方法,但这些方法并不令人满意。

package main

import "fmt"

type Polygons 接口 {
	Perimeter()
}

type Object 接口 {
	NumberOfSide()
}

type Pentagon int

func (p Pentagon) Perimeter() {
	fmt.Println("Perimeter of Pentagon", 5*p)
}

func (p Pentagon) NumberOfSide() {
	fmt.Println("Pentagon has 5 sides")
}

func main() {
	var p Polygons = Pentagon(50)
	p.Perimeter()
	var o Pentagon = p.(Pentagon)
	o.NumberOfSide()

	var obj Object = Pentagon(50)
	obj.NumberOfSide()
	var pent Pentagon = obj.(Pentagon)
	pent.Perimeter()
}

当用户定义类型实现接口类型声明的方法集时,可以将用户定义类型的值分配给接口类型的值。此分配将用户定义类型的值存储到接口值中。当针对接口值进行方法调用时,将执行与存储的用户定义值等效的方法。由于任何用户定义的类型都可以实现任何接口,因此针对接口值的方法调用本质上是多态的。这种关系中的用户定义类型通常称为 具体类型.


常用方法的接口

方法集列表中,两个或多个接口可以具有一个或多个通用方法。这里, 结构体 是两个接口之间的通用方法 车辆人的.

package main

import "fmt"

type 车辆 接口 {
	Structure() []string // Common Method
	Speed() string
}

type 人的 接口 {
	Structure() []string // Common Method
	Performance() string
}

type Car string

func (c Car) 结构体() []string {
	var parts = []string{"ECU", "Engine", "Air Filters", "Wipers", "Gas Task"}
	return parts
}

func (c Car) Speed() string {
	return "200 Km/Hrs"
}

type Man string

func (m Man) 结构体() []string {
	var parts = []string{"Brain", "Heart", "Nose", "Eyelashes", "Stomach"}
	return parts
}

func (m Man) Performance() string {
	return "8 Hrs/Day"
}

func main() {
	var bmw 车辆
	bmw = Car("World Top Brand")

	var labour 人的
	labour = Man("Software Developer")

	for i, j := range bmw.Structure() {
		fmt.Printf("%-15s <=====> %15s\n", j, labour.Structure()[i])
	}
}

编译并执行上述代码后,将产生以下结果-

C:\Golang>go run main.go
ECU             <=====>           Brain
Engine          <=====>           Heart
Air Filters     <=====>            Nose
Wipers          <=====>       Eyelashes
Gas Task        <=====>         Stomach

变量的接口接受地址

打印() 方法接受接收者指针。因此,接口还必须接受接收者指针。

如果方法接受类型值,则接口必须接收类型值;否则,接口必须接收类型值。如果方法具有指针接收器,则接口必须接收相应类型的变量的地址。

package main

import "fmt"

type Book struct {
	author, title string
}

type Magazine struct {
	title string
	issue int
}

func (b *Book) Assign(n, t string) {
	b.author = n
	b.title= t
}
func (b *Book) 打印() {
	fmt.Printf("Author: %s, Title: %s\n", b.author, b.title)
}

func (m *Magazine) Assign(t string, i int) {
	m.title= t
	m.issue = i
}
func (m *Magazine) 打印() {
	fmt.Printf("Title: %s, Issue: %d\n", m.title, m.issue)
}

type Printer 接口 {
	Print()
}

func main() {
	var b Book                                 // Declare instance of Book
	var m Magazine                             // Declare instance of Magazine
	b.Assign("Jack Rabbit", "Book of Rabbits") // Assign values to b via method
	m.Assign("Rabbit Weekly", 26)              // Assign values to m via method

	var i Printer // Declare variable of 接口 type
	fmt.Println("Call 接口")
	i = &b    // Method has pointer receiver, 接口 does not
	i.Print() // Show book values via the 接口
	i = &m    // Magazine also 满足 shower 接口
	i.Print() // Show magazine values via the 接口
}

空接口类型

方式 接口{} 被称为 空接口,它用于接受任何类型的值。空接口没有满足其要求的任何方法,因此每种类型都可以满足它。

package main

import "fmt"

func printType(i 接口{}) {
	fmt.Println(i)
}

func main() {
	var manyType 接口{}
	manyType = 100
	fmt.Println(manyType)

	manyType = 200.50
	fmt.Println(manyType)

	manyType = "Germany"
	fmt.Println(manyType)

	printType("Go programming language")
	var countries = []string{"india", "japan", "canada", "australia", "russia"}
	printType(countries)

	var employee = map[string]int{"Mark": 10, "Sandy": 20}
	printType(employee)

	country := [3]string{"Japan", "Australia", "Germany"}
	printType(country)
}

manyType 变量声明为类型 接口{} 并可以为其分配不同类型的值。的 printType() 函数采用类型的参数 接口{},因此此函数可以采用任何有效类型的值。

编译并执行上述代码后,将产生以下结果-

go run main.go
100
200.5
Germany
Go programming language
[india japan canada australia russia]
map[Mark:10 Sandy:20]
[Japan Australia Germany]

多态性

多态是编写代码的能力,这些代码可以通过类型的实现来承担不同的行为。

我们声明了一个名为Pentagon,Hexagon,Octagon和Decagon的结构,并实现了 几何 接口。

package main

import (
	"fmt"
)

// 几何 is an 接口 that defines Geometrical Calculation
type 几何 接口 {
	Edges() int
}

// Pentagon defines a geometrical object
type Pentagon struct{}

// Hexagon defines a geometrical object
type Hexagon struct{}

// Octagon defines a geometrical object
type Octagon struct{}

// Decagon defines a geometrical object
type Decagon struct{}

// 边缘 implements the 几何 接口
func (p Pentagon) 边缘() int { return 5 }

// 边缘 implements the 几何 接口
func (h Hexagon) 边缘() int { return 6 }

// 边缘 implements the 几何 接口
func (o Octagon) 边缘() int { return 8 }

// 边缘 implements the 几何 接口
func (d Decagon) 边缘() int { return 10 }

// 参数 calculate parameter of object
func 参数(geo 几何, value int) int {
	num := geo.Edges()
	calculation := num * value
	return calculation
}

// main is the entry point for the application.
func main() {
	p := new(Pentagon)
	h := new(Hexagon)
	o := new(Octagon)
	d := new(Decagon)

	g := [...]Geometry{p, h, o, d}

	for _, i := range g {
		fmt.Println(Parameter(i, 5))
	}
}

编译并执行上述代码后,将产生以下结果-

C:\Golang>go run main.go
25
30
40
50

我们有多态 边缘 接受实现 几何 接口。使用多态方法在这里创建的方法 参数 由传入的每个具体类型值使用。


接口嵌入

接口可以嵌入其他接口,此行为是接口多态性的一个方面,称为 临时多态性.

package main

import "fmt"

type 几何 接口 {
	Edges() int
}

type Polygons 接口 {
	Geometry // 接口 embedding another 接口
}

type Pentagon int
type Hexagon int
type Octagon int
type Decagon int

func (p Pentagon) 边缘() int { return 5 }
func (h Hexagon) 边缘() int  { return 6 }
func (o Octagon) 边缘() int  { return 8 }
func (d Decagon) 边缘() int  { return 10 }

func main() {
	p := new(Pentagon)
	h := new(Hexagon)
	o := new(Octagon)
	d := new(Decagon)

	polygons := [...]Polygons{p, h, o, d}
	for i := range polygons {
		fmt.Println(polygons[i].Edges())
	}
}

当一种类型嵌入另一种类型时,嵌入类型的方法可用于嵌入类型。嵌入式接口可访问嵌入式接口的方法。