面向对象的区别
Golang是一门具备面向对象编程风格的语言,但是却不具备Java等传统面向对象语言中“继承(extends)、实现(implements)”的关键字。
在Golang中,通过接口或结构体的组合来实现非严格的“继承”,通过非侵入式的接口来实现非严格的“多态”,通过结构体及包和函数实现了代码细节的“封装”,有了封装、继承与多态,就可以很好地通过OO思维实现与现实需求所对应的程序了。
Java
- Person
public abstract class Person {
protected String name;
protected int age;
public abstract void work();
}
- Student
public class Student extends Person{
@Override
public void work() {
System.out.println(age+"岁的"+name+"的工作是学习");
}
}
- main
public class Main {
public static void main(String[] args) {
Person person=new Student();
person.name="tom";
person.age=6;
person.work(); ///6岁的tom的工作是学习
}
}
Golang
在Golang中,可以这样通过结构体的组合来实现继承:
- entity
package entity
import "fmt"
type Person struct {
Name string
Age int
//id string
}
type Student struct {
Person
}
func (stu *Student) Work() {
fmt.Printf("%d岁的%s的工作是学习",stu.Age,stu.Name)
}
- main
package main
import "entity"
func main() {
stu:=&entity.Student{entity.Person{
Name: "tom",
Age: 6,
}}
stu.Work() ///6岁的tom的工作是学习
}
Golang使用了非侵入式接口来实现“多态”。
Golang非侵入式接口
Go语言的接口并不是其他语言(C++、Java、C#等)中所提供的接口概念。
在Go语言出现之前,接口主要作为不同组件之间的契约存在。对契约的实现是强制的,你必须声明你的确实现了该接口。为了实现一个接口,你需要从该接口继承:
interface IFoo {
void Bar();
}
class Foo implements IFoo { // Java文法
// ...
}
class Foo : public IFoo { // C++文法
// ...
}
IFoo foo = new Foo;
这类接口我们称为侵入式接口。“侵入式”的主要表现在于实现类需要明确声明自己实现了某个接口。
Golang的非侵入式接口不需要通过任何关键字声明类型与接口之间的实现关系,只要一个类型实现了接口的所有方法,那么这个类型就是这个接口的实现类型。
假设现在有一个Factory接口,该接口中定义了Produce()方法及Consume()方法,CafeFactory结构体作为其实现类型,那么可以通过以下代码实现:
package oom
type Factory interface {
Produce() bool
Consume() bool
}
type CafeFactory struct {
ProductName string
}
func (c *CafeFactory) Produce() bool {
fmt.Printf("CafeFactory生产%s成功", c.ProductName)
return true
}
func (c *CafeFactory) Consume() bool {
fmt.Printf("CafeFactory消费%s成功", c.ProductName)
return true
}
// --------------
package main
func main() {
factory := &oom.CafeFactory{"Cafe"}
doProduce(factory)
doConsume(factory)
}
func doProduce(factory oom.Factory) bool {
return factory.Produce()
}
func doConsume(factory oom.Factory) bool {
return factory.Consume()
}
Golang的非侵入式接口有许多好处:
1.在Go中,类型的继承树并无意义,我们只需要知道这个类型实现了哪些方法,每个方法是啥含义就足够了
2.实现类型的时候,只需要关心自己应该提供哪些方法,不用再纠结接口需要拆得多细才合理。接口由使用方按需定义,而不用事前规划
3.不用为了实现一个接口而导入一个包,因为多引用一个外部的包,就意味着更多的耦合。接口由使用方按自身需求来定义,使用方无需关心是否有其他模块定义过类似的接口
一句话总结非侵入式接口的好处就是简单、高效、按需实现。
golang空接口
interface{} 空接口是任意类型的接口,所有的类型都是空接口的实现类型。因为Golang对于实现类型的要求是实现了接口的所有方法,而空接口不存在方法,所以任意类型都可以充当空接口。