golang:面向对象总结
所谓的面向对象其实就是找一个专门做这个事的人来做,不用关心具体怎么实现的。所以说,面向过程强调的是过程,步骤。而面向对象强调的是对象,也就是干事的人。
Go语言:面向对象语言特性
方法
嵌入
接口
没有类
支持类型。 特别是, 它支持structs。 Structs是用户定义的类型。 Struct类型(含方法)提供类似于其它语言中类的服务。
Structs
一个struct定义一个状态。 这里有一个strudent struct。 它有一个Name属性和一个布尔类型的标志Real,告诉我们它是一个真实的strudent还是一个虚构的strudent。 Structs只保存状态,不保存行为。
type Creature struct {
Name string
Real bool
}
为结构体添加方法
方法是对特定类型进行操作的函数。 它们有一个接收器条款,命令它们对什么样的类型可进行操作。 这里是一个Hello()方法,它可对student结构进行操作,并打印出它们的状态:
func (s Student) Hello() {
fmt.Printf("Name: '%s', Real: %t\n", s.Name, s.Real)
}
func (s Student) func_name(){} 这是一个不太常见的语法,但是它非常的具体和清晰,不像this的隐喻性。
一般在定义方法时,需要定义为结构体的指针,值类型的在修改结构体属性时,无法修改其内容
package main
import "fmt"
type human struct {
Name string
Real bool
}
type Student struct {
human
Id int
}
func (h human) Hello() {
fmt.Printf("姓名:%s\n", h.Name)
}
func (s Student) PrintId() {
fmt.Printf("学号:%d\n", s.Id)
}
func (s Student) EditId(id int) {
s.Id = id
}
func main() {
zhangsan := Student{
human: human{"zhangsan", true},
Id: 10,
}
zhangsan.Hello()
zhangsan.EditId(101)
zhangsan.PrintId()
}

嵌入(继承)
可以将匿名的类型嵌入进struct。 如果你嵌入一个匿名的struct那么被嵌入的struct对接受嵌入的struct直接提供它自己的状态(和方法)。 比如,strudent 有一个匿名子的被嵌入的 human struct,这意味着一个 student 就是一个 hunman。
package main
import "fmt"
type human struct {
Name string
Real bool
}
type Student struct {
human
Id int
}
func (h *human) Hello() {
fmt.Printf("姓名:%s", h.Name)
}
func main() {
zhangsan := &Student{
human: human{"zhangsan", true},
Id: 10,
}
zhangsan.Hello()
}

重写
就是子类(结构体)中的方法,将父类中的相同名称的方法的功能重新给改写了
注意:在调用时,默认调用的是子类中的方法
方法值和表达式值
方法表达式,即方法对象赋值给变量,方法表达式有两种使用方式:
- 隐式调用:方法值,调用函数时,无需再传递接收者,隐藏了接收者
- 显式调用:方法表达式,显示的把接收者*Student传递过去
实例:
package main
import "fmt"
type human struct {
Name string
Real bool
}
type Student struct {
human
Id int
}
func (h *human) Hello() {
fmt.Printf("姓名:%s\n", h.Name)
}
func (s Student) PrintId() {
fmt.Printf("学号:%d\n", s.Id)
}
func (s Student) EditId(id int) {
s.Id = id
}
func main() {
zhangsan := Student{
human: human{"zhangsan", true},
Id: 10,
}
// 常规调用
zhangsan.Hello()
// 方法值 无需传递接收者
hello := zhangsan.Hello
hello()
// 方法表达式,调用函数式,传递接收者
hello1 := (*Student).Hello // 括号是因为 . 的优先级要高于取指符,需要做特殊处理
hello1(&zhangsan)
}

Go语言:面向对象的设计
接口
接口是Go语言对面向对象支持的标志。 接口是声明方法集的类型。 实现所有接口方法的对象自动地实现接口。 它没有继承或子类或 implements 关键字。
接口的定义
type 接口名字 interface {
方法声明
}
接口的继承
package main
import "fmt"
type Fooer interface {
Foo1()
}
type Fooerson interface {
Fooer
Foo2()
}
type Foo struct {
}
type Fooson struct {
}
func (f Fooson) Foo1() {
fmt.Println("Foo1() here")
}
func (f Fooson) Foo2() {
fmt.Println("Foo2() here")
}
func (f Foo) Foo1() {
fmt.Println("Foo1() here")
}
func main() {
var fooerson Fooson
var fooson Fooerson
fooson = &fooerson
fooson.Foo1()
fooson.Foo2()
var foo Fooer
foo = fooson
fooson = foo // 这样是不允许的,fooson为Fooerson接口的实现,而foo是一个Fooer接口类型的变量,可以子转换为父不能反之
foo.Foo1()
}

空接口
空接口(interface{})不包含任何的方法,正因为如此,所有的类型都实现了空接口,因此空接口可以存储任意类型的数值
package main
import "fmt"
func main() {
var arr []interface{}
arr = append(arr, 1, "zhangsan", 3.3)
fmt.Println(arr)
}

类型断言
通过类型断言,可以判断空接口中存储的数据类型。
语法:value, ok := m.(T)
m:表空接口类型变量
T:是断言的类型
value: 变量m中的值。
ok: 布尔类型变量,如果断言成功为true,否则为false
func main() {
var a interface{}
a = 10
ok, value := a.(int)
fmt.Println(ok, value)
ok1, value1 := a.(string)
fmt.Println(ok1, value1)
}

封装
Go语言在包的级别进行封装。 以小写字母开头的名称只在该程序包中可见。 可以隐藏私有包中的任何内容,只暴露特定的类型,接口和工厂函数。
例如,在这里要隐藏上面的Foo类型,只暴露接口,你可以将其重命名为小写的foo,并提供一个NewFoo()函数,返回公共Fooer接口:
type foo struct {
}
func (f foo) Foo1() {
fmt.Println("Foo1() here")
}
func (f foo) Foo2() {
fmt.Println("Foo2() here")
}
func (f foo) Foo3() {
fmt.Println("Foo3() here")
}
func NewFoo() Fooer {
return &Foo{}
}
在另一个包的代码可以使用NewFoo()并访问由内部foo类型实现的Footer接口:
f := NewFoo()
f.Foo1()
f.Foo2()
f.Foo3()
继承
Go语言没有任何类型层次结构。 它允许你通过组合来共享实现的细节。 但Go语言,允许嵌入匿名组合。
通过嵌入一个匿名类型的组合等同于实现继承,这是它所有意图和目的。 一个嵌入的struct与基类一样脆弱。 你还可以嵌入一个接口, 如果嵌入类型没有实现所有接口方法,它甚至可能导致产生在编译时未被发现的运行错误。
这里SuperFoo嵌入Fooer接口,但是SuperFoo没有实现Foo的方法。 Go编译器会愉快地让你创建一个新的SuperFood并调用Fooer的方法,但很显然这在运行时会失败。 这会编译:
package main
import "fmt"
type Fooer interface {
Foo1()
Foo2()
Foo3()
}
type Foo struct {
}
func (f Foo) Foo1() {
fmt.Println("Foo1() here")
}
func (f Foo) Foo2() {
fmt.Println("Foo2() here")
}
func (f Foo) Foo3() {
fmt.Println("Foo3() here")
}
type SuperFooer struct {
Fooer
}
func main() {
s := SuperFooer{}
s.Foo3()
}

多态
多态性是面向对象编程的本质:只要对象坚持实现同样的接口,Go语言就能处理不同类型的那些对象。 Go接口以非常直接和直观的方式提供这种能力。
Golang当中的接口解决了这个问题,只要接口中定义的方法能对应的上,那么就可以认为这个类实现了这个接口。同一个接口,使用不同的实例而执行不同操作

package main
import (
"fmt"
)
type animal interface {
Say()
}
type human struct {
}
type cat struct {
}
func (h human) Say() {
fmt.Println("人类")
}
func (c cat) Say() {
fmt.Println("猫")
}
func main() {
var a animal
a = cat{}
a.Say()
a = human{}
a.Say()
}

golang:面向对象总结的更多相关文章
- golang面向对象和interface接口
一. golang面向对象介绍 1.golang也支持面向对象编程,但是和传统的面向对象编程有区别,并不是纯粹的面向对象语言.2.golang没有类(class),golang语言的结合体(struc ...
- Golang面向对象编程-struct(结构体)
Golang面向对象编程-struct(结构体) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是面向对象编程 面向对象编程(Object Oriented Program ...
- golang 面向对象编程
概述 Golang语言的面向对象与c++,py等语言有所不同,是由于Golang不支持继承:与上述支持聚合和继承的面向对象的语言不同,Golang只支持聚合(也叫做组合)和嵌入.聚合和嵌入的区别: t ...
- 【GoLang】golang 面向对象编程 & 面向接口编程
005.面向对象&接口编程 1 面向函数编程 1.1 将数据作为参数传递到函数入参 1.2 对象与函数是分离的 2 面向对象编程 2.1 使用者看起来函数作为对象的属性而非参数 2.2 函数属 ...
- golang面向对象实现
面向对象编程三大特点:封装.继承.多态. 1. 构造函数 Go不支持构造器.如果某类型的零值不可用,需要提供NewT(parameters)函数,用来初始化T类型的变量.按照Go的惯例,应该把创建T类 ...
- golang面向对象分析
说道面向对象(OOP)编程, 就不得不提到下面几个概念: 抽象 封装 继承 多态 其实有个问题Is Go An Object Oriented Language?, 随便谷歌了一下, 你就发现讨论这个 ...
- golang面向对象初识
struct是变量的集合 interface是方法的集合 struct与interface都支持匿名字段, 换言之, 支持组合实现继承. golang的struct与C++的class一样, 只能声明 ...
- golang 面向对象
深入理解GO语言的面向对象_Golang_脚本之家 https://www.jb51.net/article/94030.htm 深入理解GO语言的面向对象 更新时间:2016年10月04日 10:4 ...
- Golang面向对象_继承
package main import "fmt" type Person struct { name string //名字 sex byte //性别 age int //年龄 ...
- Golang 中的 面向对象: 方法, 类, 方法继承, 接口, 多态的简单描述与实现
前言: Golang 相似与C语言, 基础语法与C基本一致,除了广受争议的 左花括号 必须与代码同行的问题, 别的基本差不多; 学会了C, 基本上万变不离其宗, 现在的高级语言身上都能看到C的影子; ...
随机推荐
- 配置Java环境变量时的一个常见错误
我们在把JDK路径配置为环境变量时,有一个常用的配置方法,就是把JDK根路径配置为"JAVA_HOME"值,然后在Path中添加一条"%JAVA_HOME%\bin&qu ...
- 截取pod ip地址最后一列
资源清单: --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: init-demo namespace: test ...
- [枚举]P1089 津津的储蓄计划
津津的储蓄计划 题目描述 津津的零花钱一直都是自己管理.每个月的月初妈妈给津津300元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同. 为了让津津学习如何储蓄,妈妈提出,津津可以随时把整 ...
- Java中对象的生与灭- 核心篇
前言 大家好啊,我是汤圆,今天给大家带来的是<Java中对象的生与灭- 核心篇>,希望对大家有帮助,谢谢 文章纯属原创,个人总结难免有差错,如果有,麻烦在评论区回复或后台私信,谢啦 简介 ...
- 关于MySQL日志,我与阿里P9都聊了些啥?
写在前面 周末,我与阿里P9资深技术专家(这里就不说名字了),聊起了MySQL这个话题,为啥会聊这个呢?因为他看到我出版了一部<MySQL技术大全:开发.优化与运维实战>,对书籍的评价也是 ...
- Python中的多进程、多线程和协程
本文中的内容来自我的笔记.撰写过程中参考了胡俊峰老师<Python程序设计与数据科学导论>课程的内容. 并发处理:多进程和多线程 前置 概念: 并发:一段时间内同时推进多个任务,但不一定要 ...
- Axure常用操作备忘
目录 前言 技巧 边框重合 复制对象文本居中 复制粘贴样式 文本自适应 给图形添加连接点 导出图片无空白 前言 下面列出Axure画图过程中曾经遇到过的问题,备忘一下,避免别人也走弯路,法布施一下~ ...
- Day05_25_Super关键字
Super关键字 Super关键字的所用 Super关键字的用法有三种: 在子类的成员方法中,访问父类的成员变量. 在子类的成员方法中,访问父类的成员方法. 在子类的构造方法中,访问父类的构造方法. ...
- WPF之小米Logo超圆角的实现
某些新闻:小米logo换新,程序员一行代码(border-radius:19px)实现,目前此行代码价值200万 某程序员内心:所以还是因为我代码写太少了,所以这200万才没有我的份吗? 这事儿也成功 ...
- 微服务的进程间通信(IPC)
微服务的进程间通信(IPC) 目录 微服务的进程间通信(IPC) 术语 概述 通信视角 APIs 消息格式 RPC REST gRPC 断路器 API通信的健壮性 服务发现 异步消息 概念 消息 消息 ...