go語言interface接口繼承多態(tài)示例及定義解析
1.什么是接口
接口就是一種規(guī)范與標準,在生活中經(jīng)常見接口,例如:筆記本電腦的USB接口,可以將任何廠商生產(chǎn)的鼠標與鍵盤,與電腦進行鏈接。為什么呢?原因就是,USB接口將規(guī)范和標準制定好后,各個生產(chǎn)廠商可以按照該標準生產(chǎn)鼠標和鍵盤就可以了。
在程序開發(fā)中,接口只是規(guī)定了要做哪些事情,干什么。具體怎么做,接口是不管的。這和生活中接口的案例也很相似,例如:USB接口,只是規(guī)定了標準,但是不關心具體鼠標與鍵盤是怎樣按照標準生產(chǎn)的.
在企業(yè)開發(fā)中,如果一個項目比較龐大,那么就需要一個能理清所有業(yè)務的架構師來定義一些主要的接口,這些接口告訴開發(fā)人員你需要實現(xiàn)那些功能。
2.接口定義
接口定義的語法如下:
方式一:interface接收任意數(shù)據(jù)格式
//先定義接口 一般以er結尾 根據(jù)接口實現(xiàn)功能
type CurrencyEr2 interface{
Symbol() string
}
方式二:指定類型
type Currency string
怎樣具體實現(xiàn)接口中定義的方法呢?
func (c Currency)Symbol() string {
m := ""
switch c {
case "CNY":
// 人民幣
m = "¥"
case "KRW":
// 韓幣
m = "?"
case "TWD":
// 臺幣
m = "$"
case "JPY":
// 日元
m = "¥"
case "USD":
// 美元
m = "$"
}
return m
}
具體的調用如下:
func main() {
// 方式一:
a:=CurrencyEr2(Currency("CNY")).Symbol()
fmt.Println(a)
// 方式二:
b:=Currency("CNY").Symbol()
fmt.Println(b)
}
只要類(結構體)實現(xiàn)對應的接口,那么根據(jù)該類創(chuàng)建的對象,可以賦值給對應的接口類型。
接口的命名習慣以er結尾。
3.多態(tài)
接口有什么好處呢?實現(xiàn)多態(tài)。
多態(tài)就是同一個接口,使用不同的實例而執(zhí)行不同操作
所謂多態(tài)指的是多種表現(xiàn)形式,如下圖所示:
使用接口實現(xiàn)多態(tài)的方式如下:
package main
import "fmt"
//先定義接口 一般以er結尾 根據(jù)接口實現(xiàn)功能
type CurrencyEr2 interface {
//方法 方法的聲明
Symbol() string
}
type Currency string
type Currency2 string
func (c Currency) Symbol() string {
m := ""
switch c {
case "CNY":
m = "¥"
}
return m
}
func (c Currency2) Symbol() string {
m := ""
switch c {
case "USD":
m = "$"
}
return m
}
//多態(tài)的實現(xiàn)
//將接口作為函數(shù)參數(shù) 實現(xiàn)多態(tài)
func Start(c CurrencyEr2) string {
return c.Symbol()
}
func main() {
//調用多態(tài)函數(shù)
a := Start(Currency("CNY"))
fmt.Println(a)
//調用多態(tài)函數(shù)
b := Start(Currency2("USD"))
fmt.Println(b)
}
多態(tài)加減計算器
package main
import "fmt"
//定義接口
type Opter interface {
//方法聲明
Result() int
}
//父類結構體
type Operate struct {
num1 int
num2 int
}
//加法子類結構體
type Add struct {
Operate
}
//實現(xiàn)加法子類的方法
func (a *Add) Result() int {
return a.num1 + a.num2
}
//減法子類結構體
type Sub struct {
Operate
}
//實現(xiàn)減法子類的方法
func (s *Sub) Result() int {
return s.num1 - s.num2
}
//創(chuàng)建一個類負責對象創(chuàng)建
//工廠類
type Factory struct {
}
func (f *Factory) Result(num1 int, num2 int, ch string) int {
sum := 0
switch ch {
case "+":
var a Add
a.num1 = num1
a.num2 = num2
sum = Opter.Result(&a)
case "-":
var s Sub
s.num1 = num1
s.num2 = num2
sum = Opter.Result(&s)
}
return sum
}
//通過設計模式調用
func main() {
//創(chuàng)建工廠對象
var f Factory
a:= f.Result(10, 20, "+")
fmt.Println(a)
}
4.接口繼承與轉換
接口也可以實現(xiàn)繼承:
package main
import "fmt"
//先定義接口 一般以er結尾 根據(jù)接口實現(xiàn)功能
type Humaner2 interface { //子集
//方法 方法的聲明
sayhi()
}
type Personer interface { //超集
Humaner2 //繼承sayhi()
sing(string)
}
type student13 struct {
name string
age int
score int
}
func (s *student13)sayhi() {
fmt.Printf("大家好,我是%s,今年%d歲,我的成績%d分\n",s.name,s.age,s.score)
}
func (s *student13)sing(name string) {
fmt.Println("我為大家唱首歌",name)
}
func main() {
//接口類型變量定義
var h Humaner2
var stu student13 = student13{"小吳",18,59}
h = &stu
h.sayhi()
//接口類型變量定義
var p Personer
p = &stu
p.sayhi()
p.sing("大碗面")
}
接口繼承后,可以實現(xiàn)“超集”接口轉換“子集”接口,代碼如下:
package main
import "fmt"
//先定義接口 一般以er結尾 根據(jù)接口實現(xiàn)功能
type Humaner2 interface { //子集
//方法 方法的聲明
sayhi()
}
type Personer interface { //超集
Humaner2 //繼承sayhi()
sing(string)
}
type student13 struct {
name string
age int
score int
}
func (s *student13)sayhi() {
fmt.Printf("大家好,我是%s,今年%d歲,我的成績%d分\n",s.name,s.age,s.score)
}
func (s *student13)sing(name string) {
fmt.Println("我為大家唱首歌",name)
}
func main() {
//接口類型變量定義
var h Humaner2 //子集
var p Personer //超集
var stu student13 = student13{"小吳",18,59}
p = &stu
//將一個接口賦值給另一個接口
//超集中包含所有子集的方法
h = p //ok
h.sayhi()
//子集不包含超集
//不能將子集賦值給超集
//p = h //err
//p.sayhi()
//p.sing("大碗面")
}
5.空接口
空接口(interface{})不包含任何的方法,正因為如此,所有的類型都實現(xiàn)了空接口,因此空接口可以存儲任意類型的數(shù)值。
例如:
var i interface{}
//接口類型可以接收任意類型的數(shù)據(jù)
//fmt.Println(i)
fmt.Printf("%T\n",i)
i = 10
fmt.Println(i)
fmt.Printf("%T\n",i)
當函數(shù)可以接受任意的對象實例時,我們會將其聲明為interface{},最典型的例子是標準庫fmt中PrintXXX系列的函數(shù),例如:
func Printf(fmt string, args ...interface{})
func Println(args ...interface{})
如果自己定義函數(shù),可以如下:
func Test(arg ...interface{}) {
}
Test( )函數(shù)可以接收任意個數(shù),任意類型的參數(shù)。
6.接口轉換
結論:超集可以轉換為子集,子集不可以轉換為超集
package main
import "fmt"
type Humaner interface { //子集
sayhi()
}
type Personer interface { //超集
Humaner //匿名字段,繼承了sayhi()
sing(lrc string)
}
type Student struct {
name string
id int
}
//Student實現(xiàn)了sayhi()
func (tmp *Student) sayhi() {
fmt.Printf("Student[%s, %d] sayhi\n", tmp.name, tmp.id)
}
func (tmp *Student) sing(lrc string) {
fmt.Println("Student在唱著:", lrc)
}
func main() {
//超集可以轉換為子集,反過來不可以
var iPro Personer //超集
iPro = &Student{"mike", 666}
var i Humaner //子集
//iPro = i //err
i = iPro //可以,超集可以轉換為子集
i.sayhi()
}
7.實現(xiàn)map字典接口
package main
import (
"fmt"
"sync"
)
type UserAges struct {
ages map[string] int
sync.Mutex
}
func (u *UserAges)Add(name string,age int) {
u.Lock()
defer u.Unlock()
u.ages[name] = age
}
func (u *UserAges)Get(name string)int{
if age,ok:=u.ages[name];ok{
return age
}
return -1
}
func main() {
dic:=make(map[string]int)
dic["age"] = 18
r:=UserAges{ages: dic}
r.Add("jeff",20)
fmt.Println(r)
age:=r.Get("age")
fmt.Println(age)
}
8.interface案例
package main
import "fmt"
type Bike interface {
save()
update()
insert()
}
type User struct {
name string
}
func (this *User) save() {
fmt.Println("保存成功", this.name)
}
func (this *User) update() {
fmt.Println("更新成功", this.name)
}
func (this *User) insert() {
fmt.Println("插入成功", this.name)
}
func main() {
var data Bike = &User{name: "jeff"}
data.save()
data.update()
data.insert()
}以上就是go語言interface接口繼承多態(tài)示例及定義解析的詳細內容,更多關于go語言interface接口繼承多態(tài)的資料請關注腳本之家其它相關文章!
相關文章
使用GO語言實現(xiàn)Mysql數(shù)據(jù)庫CURD的簡單示例
本文主要介紹了使用GO語言實現(xiàn)Mysql數(shù)據(jù)庫CURD的簡單示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08
go?module化?import?調用本地模塊?tidy的方法
這篇文章主要介紹了go?module化?import?調用本地模塊?tidy的相關知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-09-09

