了解接口
将接口视为一组行为。当某人或某物实现此界面时,他们本身定义了这组行为。例如,让我们考虑一个接口生物。现在说,我们期望任何有机体都能执行某些动作或行为,例如breathe()
和move()
或eat()
。
这是一个接口,我们希望实体能够执行(或类型能够调用这些功能)的一组行为(或功能)。
什么是接口?
再次,什么是接口?它们是一种抽象类型,它定义了一组需要通过任何想要满足该接口的具体类型来实现的函数签名。为什么任何类型都想满足接口?我们会来的。
抽象和具体类型?
具体类型,简单地说是可以实例化的类型,这意味着可以创建和使用该类型的值。例如,int,string甚至结构。我可以将结构定义为新类型,为其创建对象并使用它。
抽象类型,无法实例化!接口是抽象类型。它们是其他类型的基础。其他类型可以实现接口,并且可以将它们作为参数发送到任何其他期望该接口实例的函数。
为什么要接口?
当您的类型实现接口时,可以在任何地方使用它,您可以在任何地方使用接口。例如,假设mouse
类型满足我们的organism
接口。因此,无论我期望有机体的实例,鼠标都可以通过。我为什么需要有机体?也许我有一个可以免费提供食物的功能,说freeFood()
!现在,我只想要一个可以执行饮食功能通过的对象。
我也可以为mouse
和dog
分别定义该函数,但随后我必须两次编写相同的功能。我们可以做的事情,我们可以将饮食方法的各自实施留给有机体,我们只希望有人可以吃。它将执行免费食品功能。
这次让我们以代码为例。让我们首先创建三个结构。一个用于dog
,一个用于nonVegetarian
,一个用于vegetarian
。
type dog struct {}
type nonVegetarian struct{}
type vegetarian struct{}
现在让我们定义一个界面,该界面将用于定义所有可以吃肉的人。
type canEatMeat interface {
eatMeat()
}
可以说具有eatMeat
的实现的任何类型是canEatMeat
的实例。
func (d dog) eatMeat() {
fmt.Println("Dog is eating meat... Bark")
}
func (nv nonVegetarian) eatMeat() {
fmt.Println("Non-vegetarian is eating meat... Yummy")
}
现在,我有一家商店,在那里卖免费的肉。但是我只希望那些人来我的商店可以吃肉。
func comeAndEatMeat(o canEatMeat) {
o.eatMeat()
}
如您所见,我可以定义一个接口,并且任何实现它的人都可以使用我的功能。如果有任何新类型,并且它具有该功能,则可以轻松地出现并没有任何问题。
相反,我已经在类型上定义了它,只有该类型才能执行它。
现在主要部分。
func main() {
myDog := dog{}
myNonVeg := nonVegetarian{}
myVeg := vegetarian{}
comeAndEatMeat(myDog) // Output: Dog is eating meat... Bark
comeAndEatMeat(myNonVeg) // Output: Non-vegetarian is eating meat... Yummy
comeAndEatMeat(myVeg) // Compilation error: vegetarian does not implement canEatMeat
}
我希望这篇文章对您有帮助。