我们知道,在 Go 语言中没有类(Class)的概念,但这并不意味着 Go 语言不支持面向对象编程,毕竟面向对象只是一种编程思想。
让我们回忆一下面向对象的三大基本特征:
go当中没有class,但是有struct
package main
import "fmt"
type MyStruct struct{
aint int;
}
func (myStruct MyStruct) getAint() int{
return myStruct.aint;
}
func (myStruct MyStruct) setAint(aint int){
myStruct.aint=aint;
}
func (myStruct MyStruct) gogo(){
myStruct.aint=12;
}
func main(){
var myStruct MyStruct;
myStruct.aint=123;
fmt.Printf("%p\n",&myStruct);
fmt.Printf("%d\n",myStruct);
myStruct.gogo();
fmt.Printf("%p\n",&myStruct);
fmt.Printf("%d\n",myStruct);
myStruct.setAint(66)
aint:=myStruct.getAint();
fmt.Printf("%p\n",&myStruct);
fmt.Printf("%d\n", aint);
}
执行结果
怎么回事 值怎么没变化,难道方法调用传递的不是引用(指针)?调用方法时是新构建一个结构体?
我们尝试在方法当中打印结构体的引用地址。
package main
import "fmt"
type MyStruct struct{
aint int;
}
func (myStruct MyStruct) getAint() int{
fmt.Printf("%p\n",&myStruct)
return myStruct.aint;
}
func (myStruct MyStruct) setAint(aint int){
myStruct.aint=aint;
fmt.Printf("%p\n",&myStruct)
}
func (myStruct MyStruct) gogo(){
myStruct.aint=12;
fmt.Printf("%p\n",&myStruct)
}
func main(){
var myStruct MyStruct;
myStruct.aint=123;
fmt.Printf("%p\n",&myStruct);
fmt.Printf("%d\n",myStruct);
myStruct.gogo();
fmt.Printf("%p\n",&myStruct);
fmt.Printf("%d\n",myStruct);
myStruct.setAint(66)
aint:=myStruct.getAint();
fmt.Printf("%p\n",&myStruct);
fmt.Printf("%d\n", aint);
}
执行结果
果然调用方法时是新构建一个结构体。那怎么传递指针呢?像java一样
package main
import "fmt"
type MyStruct struct{
aint int;
}
func (myStruct *MyStruct) getAint() int{
fmt.Printf("%p\n",myStruct)
return myStruct.aint;
}
func (myStruct *MyStruct) setAint(aint int){
myStruct.aint=aint;
fmt.Printf("%p\n",myStruct)
}
func (myStruct *MyStruct) gogo(){
myStruct.aint=12;
fmt.Printf("%p\n",myStruct)
}
func main(){
var myStruct MyStruct;
myStruct.aint=123;
fmt.Printf("%p\n",&myStruct);
fmt.Printf("%d\n",myStruct);
myStruct.gogo();
fmt.Printf("%p\n",&myStruct);
fmt.Printf("%d\n",myStruct);
myStruct.setAint(66)
aint:=myStruct.getAint();
fmt.Printf("%p\n",&myStruct);
fmt.Printf("%d\n", aint);
}
在 Go 语言中没有 extends 关键字,它使用在结构体中内嵌匿名类型的方法来实现继承。
匿名类型:即这些类型没有显式的名字。
package main
import "fmt"
type Father struct{
name string;
age int;
}
func (baba Father) call(){
fmt.Printf("baba\n");
}
type MyStruct struct{
student string;
Father;
}
func main(){
father:=Father{
name:"ni",
age:12,
}
mystruct:=MyStruct{
student:"你好",
}
father.call();
mystruct.call();
}
执行结果
可以看到 mystruct 继承了 father的call方法
怎么覆盖呢?
package main
import "fmt"
type Father struct{
name string;
age int;
}
func (baba Father) call(){
fmt.Printf("baba\n");
}
type MyStruct struct{
student string;
Father;
}
func (mystruct MyStruct) call(){
fmt.Printf("fugai\n");
}
func main(){
father:=Father{
name:"ni",
age:12,
}
mystruct:=MyStruct{
student:"你好",
}
father.call();
mystruct.call();
}
执行结果
可以看到 mystruct 覆盖了继承的father的call方法
在面向对象中,多态的特征为:不同对象中同种行为的不同实现方式。在 Go 语言中可以使用接口实现这一特征。
package main
import "fmt"
type Phone interface{
call();
}
type IPhone struct{
}
func (iphone IPhone) call(){
fmt.Printf("iphone call\n")
}
type HuaWei struct{
}
func (huawei HuaWei) call(){
fmt.Printf("huawei call\n")
}
func main(){
var phone Phone;
phone=new(IPhone);
phone.call();
phone=new(HuaWei);
phone.call();
}