go封装、继承、多态

我们知道,在 Go 语言中没有类(Class)的概念,但这并不意味着 Go 语言不支持面向对象编程,毕竟面向对象只是一种编程思想。
让我们回忆一下面向对象的三大基本特征:

  1. 封装 隐藏对象的属性和实现细节,仅对外提供公共方法访问
  2. 继承 子类可以继承父类的属性和实现细节,并且可以添加属性和覆盖父类的实现
  3. 多态 不同对象当中的相同行为有不同的实现

封装

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);
}

执行结果
image.png
怎么回事 值怎么没变化,难道方法调用传递的不是引用(指针)?调用方法时是新构建一个结构体?
我们尝试在方法当中打印结构体的引用地址。

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);
}

执行结果
image.png
果然调用方法时是新构建一个结构体。那怎么传递指针呢?像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);
}

执行结果 可以看到值成功的被改变了。
image.png

继承

在 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();
}

执行结果
image.png
可以看到 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();
}

执行结果
image.png
可以看到 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();
}

执行结果
image.png
可以看到 这个达到了我们的预期

总结

  1. go是支持面向对象编程的。
  2. 申明结构体方法时,如果需要对结构体方法当中的变量进行修改,千万要注意需要传递指针
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值