所谓的面向对象其实就是找一个专门做这个事的人来做,不用关心具体怎么实现的。所以说,面向过程强调的是过程,步骤。而面向对象强调的是对象,也就是干事的人。

Go语言:面向对象语言特性

  • 方法

  • 嵌入

  • 接口

  • 没有类

  • 支持类型。 特别是, 它支持structs。 Structs是用户定义的类型。 Struct类型(含方法)提供类似于其它语言中类的服务。

Structs

一个struct定义一个状态。 这里有一个strudent struct。 它有一个Name属性和一个布尔类型的标志Real,告诉我们它是一个真实的strudent还是一个虚构的strudent。 Structs只保存状态,不保存行为。

  1. type Creature struct {
  2. Name string
  3. Real bool
  4. }

为结构体添加方法

方法是对特定类型进行操作的函数。 它们有一个接收器条款,命令它们对什么样的类型可进行操作。 这里是一个Hello()方法,它可对student结构进行操作,并打印出它们的状态:

  1. func (s Student) Hello() {
  2. fmt.Printf("Name: '%s', Real: %t\n", s.Name, s.Real)
  3. }

func (s Student) func_name(){} 这是一个不太常见的语法,但是它非常的具体和清晰,不像this的隐喻性。

一般在定义方法时,需要定义为结构体的指针,值类型的在修改结构体属性时,无法修改其内容

  1. package main
  2. import "fmt"
  3. type human struct {
  4. Name string
  5. Real bool
  6. }
  7. type Student struct {
  8. human
  9. Id int
  10. }
  11. func (h human) Hello() {
  12. fmt.Printf("姓名:%s\n", h.Name)
  13. }
  14. func (s Student) PrintId() {
  15. fmt.Printf("学号:%d\n", s.Id)
  16. }
  17. func (s Student) EditId(id int) {
  18. s.Id = id
  19. }
  20. func main() {
  21. zhangsan := Student{
  22. human: human{"zhangsan", true},
  23. Id: 10,
  24. }
  25. zhangsan.Hello()
  26. zhangsan.EditId(101)
  27. zhangsan.PrintId()
  28. }

嵌入(继承)

可以将匿名的类型嵌入进struct。 如果你嵌入一个匿名的struct那么被嵌入的struct对接受嵌入的struct直接提供它自己的状态(和方法)。 比如,strudent 有一个匿名子的被嵌入的 human struct,这意味着一个 student 就是一个 hunman

  1. package main
  2. import "fmt"
  3. type human struct {
  4. Name string
  5. Real bool
  6. }
  7. type Student struct {
  8. human
  9. Id int
  10. }
  11. func (h *human) Hello() {
  12. fmt.Printf("姓名:%s", h.Name)
  13. }
  14. func main() {
  15. zhangsan := &Student{
  16. human: human{"zhangsan", true},
  17. Id: 10,
  18. }
  19. zhangsan.Hello()
  20. }

重写

就是子类(结构体)中的方法,将父类中的相同名称的方法的功能重新给改写了

注意:在调用时,默认调用的是子类中的方法

方法值和表达式值

方法表达式,即方法对象赋值给变量,方法表达式有两种使用方式:

  • 隐式调用:方法值,调用函数时,无需再传递接收者,隐藏了接收者
  • 显式调用:方法表达式,显示的把接收者*Student传递过去

实例:

  1. package main
  2. import "fmt"
  3. type human struct {
  4. Name string
  5. Real bool
  6. }
  7. type Student struct {
  8. human
  9. Id int
  10. }
  11. func (h *human) Hello() {
  12. fmt.Printf("姓名:%s\n", h.Name)
  13. }
  14. func (s Student) PrintId() {
  15. fmt.Printf("学号:%d\n", s.Id)
  16. }
  17. func (s Student) EditId(id int) {
  18. s.Id = id
  19. }
  20. func main() {
  21. zhangsan := Student{
  22. human: human{"zhangsan", true},
  23. Id: 10,
  24. }
  25. // 常规调用
  26. zhangsan.Hello()
  27. // 方法值 无需传递接收者
  28. hello := zhangsan.Hello
  29. hello()
  30. // 方法表达式,调用函数式,传递接收者
  31. hello1 := (*Student).Hello // 括号是因为 . 的优先级要高于取指符,需要做特殊处理
  32. hello1(&zhangsan)
  33. }

Go语言:面向对象的设计

接口

接口是Go语言对面向对象支持的标志。 接口是声明方法集的类型。 实现所有接口方法的对象自动地实现接口。 它没有继承或子类或 implements 关键字。

接口的定义

  1. type 接口名字 interface {
  2. 方法声明
  3. }

接口的继承

  1. package main
  2. import "fmt"
  3. type Fooer interface {
  4. Foo1()
  5. }
  6. type Fooerson interface {
  7. Fooer
  8. Foo2()
  9. }
  10. type Foo struct {
  11. }
  12. type Fooson struct {
  13. }
  14. func (f Fooson) Foo1() {
  15. fmt.Println("Foo1() here")
  16. }
  17. func (f Fooson) Foo2() {
  18. fmt.Println("Foo2() here")
  19. }
  20. func (f Foo) Foo1() {
  21. fmt.Println("Foo1() here")
  22. }
  23. func main() {
  24. var fooerson Fooson
  25. var fooson Fooerson
  26. fooson = &fooerson
  27. fooson.Foo1()
  28. fooson.Foo2()
  29. var foo Fooer
  30. foo = fooson
  31. fooson = foo // 这样是不允许的,fooson为Fooerson接口的实现,而foo是一个Fooer接口类型的变量,可以子转换为父不能反之
  32. foo.Foo1()
  33. }

空接口

空接口(interface{})不包含任何的方法,正因为如此,所有的类型都实现了空接口,因此空接口可以存储任意类型的数值

  1. package main
  2. import "fmt"
  3. func main() {
  4. var arr []interface{}
  5. arr = append(arr, 1, "zhangsan", 3.3)
  6. fmt.Println(arr)
  7. }

类型断言

通过类型断言,可以判断空接口中存储的数据类型。

语法:value, ok := m.(T)

m:表空接口类型变量

T:是断言的类型

value: 变量m中的值。

ok: 布尔类型变量,如果断言成功为true,否则为false

  1. func main() {
  2. var a interface{}
  3. a = 10
  4. ok, value := a.(int)
  5. fmt.Println(ok, value)
  6. ok1, value1 := a.(string)
  7. fmt.Println(ok1, value1)
  8. }

封装

Go语言在包的级别进行封装。 以小写字母开头的名称只在该程序包中可见。 可以隐藏私有包中的任何内容,只暴露特定的类型,接口和工厂函数。

例如,在这里要隐藏上面的Foo类型,只暴露接口,你可以将其重命名为小写的foo,并提供一个NewFoo()函数,返回公共Fooer接口:

  1. type foo struct {
  2. }
  3. func (f foo) Foo1() {
  4. fmt.Println("Foo1() here")
  5. }
  6. func (f foo) Foo2() {
  7. fmt.Println("Foo2() here")
  8. }
  9. func (f foo) Foo3() {
  10. fmt.Println("Foo3() here")
  11. }
  12. func NewFoo() Fooer {
  13. return &Foo{}
  14. }

在另一个包的代码可以使用NewFoo()并访问由内部foo类型实现的Footer接口:

  1. f := NewFoo()
  2. f.Foo1()
  3. f.Foo2()
  4. f.Foo3()

继承

Go语言没有任何类型层次结构。 它允许你通过组合来共享实现的细节。 但Go语言,允许嵌入匿名组合。

通过嵌入一个匿名类型的组合等同于实现继承,这是它所有意图和目的。 一个嵌入的struct与基类一样脆弱。 你还可以嵌入一个接口, 如果嵌入类型没有实现所有接口方法,它甚至可能导致产生在编译时未被发现的运行错误。

这里SuperFoo嵌入Fooer接口,但是SuperFoo没有实现Foo的方法。 Go编译器会愉快地让你创建一个新的SuperFood并调用Fooer的方法,但很显然这在运行时会失败。 这会编译:

  1. package main
  2. import "fmt"
  3. type Fooer interface {
  4. Foo1()
  5. Foo2()
  6. Foo3()
  7. }
  8. type Foo struct {
  9. }
  10. func (f Foo) Foo1() {
  11. fmt.Println("Foo1() here")
  12. }
  13. func (f Foo) Foo2() {
  14. fmt.Println("Foo2() here")
  15. }
  16. func (f Foo) Foo3() {
  17. fmt.Println("Foo3() here")
  18. }
  19. type SuperFooer struct {
  20. Fooer
  21. }
  22. func main() {
  23. s := SuperFooer{}
  24. s.Foo3()
  25. }

多态

多态性是面向对象编程的本质:只要对象坚持实现同样的接口,Go语言就能处理不同类型的那些对象。 Go接口以非常直接和直观的方式提供这种能力。

Golang当中的接口解决了这个问题,只要接口中定义的方法能对应的上,那么就可以认为这个类实现了这个接口。同一个接口,使用不同的实例而执行不同操作

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type animal interface {
  6. Say()
  7. }
  8. type human struct {
  9. }
  10. type cat struct {
  11. }
  12. func (h human) Say() {
  13. fmt.Println("人类")
  14. }
  15. func (c cat) Say() {
  16. fmt.Println("猫")
  17. }
  18. func main() {
  19. var a animal
  20. a = cat{}
  21. a.Say()
  22. a = human{}
  23. a.Say()
  24. }

golang:面向对象总结的更多相关文章

  1. golang面向对象和interface接口

    一. golang面向对象介绍 1.golang也支持面向对象编程,但是和传统的面向对象编程有区别,并不是纯粹的面向对象语言.2.golang没有类(class),golang语言的结合体(struc ...

  2. Golang面向对象编程-struct(结构体)

    Golang面向对象编程-struct(结构体) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是面向对象编程 面向对象编程(Object Oriented Program ...

  3. golang 面向对象编程

    概述 Golang语言的面向对象与c++,py等语言有所不同,是由于Golang不支持继承:与上述支持聚合和继承的面向对象的语言不同,Golang只支持聚合(也叫做组合)和嵌入.聚合和嵌入的区别: t ...

  4. 【GoLang】golang 面向对象编程 & 面向接口编程

    005.面向对象&接口编程 1 面向函数编程 1.1 将数据作为参数传递到函数入参 1.2 对象与函数是分离的 2 面向对象编程 2.1 使用者看起来函数作为对象的属性而非参数 2.2 函数属 ...

  5. golang面向对象实现

    面向对象编程三大特点:封装.继承.多态. 1. 构造函数 Go不支持构造器.如果某类型的零值不可用,需要提供NewT(parameters)函数,用来初始化T类型的变量.按照Go的惯例,应该把创建T类 ...

  6. golang面向对象分析

    说道面向对象(OOP)编程, 就不得不提到下面几个概念: 抽象 封装 继承 多态 其实有个问题Is Go An Object Oriented Language?, 随便谷歌了一下, 你就发现讨论这个 ...

  7. golang面向对象初识

    struct是变量的集合 interface是方法的集合 struct与interface都支持匿名字段, 换言之, 支持组合实现继承. golang的struct与C++的class一样, 只能声明 ...

  8. golang 面向对象

    深入理解GO语言的面向对象_Golang_脚本之家 https://www.jb51.net/article/94030.htm 深入理解GO语言的面向对象 更新时间:2016年10月04日 10:4 ...

  9. Golang面向对象_继承

    package main import "fmt" type Person struct { name string //名字 sex byte //性别 age int //年龄 ...

  10. Golang 中的 面向对象: 方法, 类, 方法继承, 接口, 多态的简单描述与实现

    前言: Golang 相似与C语言, 基础语法与C基本一致,除了广受争议的 左花括号 必须与代码同行的问题, 别的基本差不多; 学会了C, 基本上万变不离其宗, 现在的高级语言身上都能看到C的影子; ...

随机推荐

  1. DNS 缓存中毒--Kaminsky 攻击复现

    0x00 搭建实验环境 使用3台Ubuntu 16.04虚拟机,可到下面的参考链接下载 攻击的服务是BIND9,由于条件限制,这里使用本地的一台虚拟机当作远程DNS解析器,关闭了DNSSEC服务,其中 ...

  2. Hadoop学习笔记—HDFS

    目录 搭建安装 三个核心组件 安装 配置环境变量 配置各上述三组件守护进程的相关属性 启停 监控和性能 Hadoop Rack Awareness yarn的NodeManagers监控 命令 hdf ...

  3. Scrum完整项目实例

    一.背景 在谈 JIRA 之前,就不得不说说敏捷开发了.正式由于项目是基于敏捷开发进行的,因此才引入了 JIRA 这款适合于敏捷开发的项目管理工具.当然,这里不会大篇章的介绍敏捷开发,之前的文章有详细 ...

  4. 快速排序(QuickSort)Java版

    快速排序 快速排序是对冒泡排序的一种改进. 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排 ...

  5. 翻译:《实用的Python编程》08_02_Logging

    目录 | 上一节 (8.1 测试) | 下一节 (8.3 调试) 8.2 日志 本节对日志模块(logging module)进行简单的介绍. logging 模块 logging 模块是用于记录诊断 ...

  6. CIE标准色度系统(上)

    一.颜色匹配 为了满足工业生产对颜色特性的定量化和标准化的需要,由国际照明委员会(CIE)的协调和指导下,先后提出CIE1931和CIE1964标准色度观察者光谱三刺激值,由此奠定了现代色度学基础. ...

  7. Anacoda下报错conda command not found 以及TypeError: __new__() got an unexpected keyword argument 'serialized_options'

    在anacoda安装完成后,执行conda list命令,显示command not found 解决方法: 对于anaconda 2  , 输入export PATH=~/anaconda2/bin ...

  8. PAT A1025 考生排名问题

    题目要求:有n个考场,每个考场有若干个考生,现给出各个考场中考生的准考证号与分数,按照分数从高到低排序,并按顺序输出所有考生的准考证号,排名,考场号以及所在的考场排名 #include<cstd ...

  9. redhat 7.6 部署禅道 yum [Errno 14] curl#37 - "Couldn't open file /mnt/repodata/repomd.

    记个流水账 redhat 7.6 上部署 禅道.  禅道官网下载 http://dl.cnezsoft.com/zentao/9.8.3/ZenTaoPMS.9.8.3.zbox_64.tar.gz ...

  10. LNMP架构上线动态网站

    第一步,一键安装所需程序 yum install -y nginx php php-mysql php-fpm mariadb-server 第二步,修改Nginx配置文件/etc/nginx/ngi ...