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

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:面向对象总结的更多相关文章

  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. limanmanExp数据库审计设计思路与重要代码

    目的 在代码审计的时候经常会想看看某个访问会触发哪些数据库操作.目前已知的数据库审计有多家大型厂商的设备,还有seay源码审计系统中的数据库监控1.0 但是.开源的已知的就只有seay源码审计系统中的 ...

  2. 【10.5NOIP普及模拟】sum

    [10.5NOIP普及模拟]sum 文章目录 [10.5NOIP普及模拟]sum 题目描述 输入 输出 输入输出样例 样例输入 样例输出 解析 code 题目描述 小x有很多糖果,分成了 N 堆,排成 ...

  3. 几十行代码实现ASP.NET Core自动依赖注入

    在开发.NET Core web服务的时候,我们习惯使用自带的依赖注入容器来进行注入. 于是就会经常进行一个很频繁的的重复动作:定义一个接口->写实现类->注入 有时候会忘了写Add这一步 ...

  4. 「HTML+CSS」--自定义加载动画【014】【疑问未解决】

    前言 Hello!小伙伴! 首先非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 哈哈 自我介绍一下 昵称:海轰 标签:程序猿一只|C++选手|学生 简介:因C语言结识编程,随后转入计算机 ...

  5. Julia语言程序基础

    Julia-lang 新兴的Julia语言,Julia 一开始就是为高性能而设计的. Julia 程序通过 LLVM 编译成高效的多平台机器码. Julia中文社区: https://cn.julia ...

  6. 一起来看Java设计思想之23种设计模式

    目录 怎么使用设计模式 23种设计模式 创建型模式 结构型模式 行为型模式 总结 怎么使用设计模式 为什么要使用设计模式? 编写代码,写接口.写类.写方法 用设计模式做设计的作用是什么? 指导.规定如 ...

  7. JMeter 结果处理常见问题

    1. 前言 2. 结果处理常见问题 1)在察看结果树中只看失败情况 2)如何把日志放入文件查看 3)cvs 文件中文读取乱码 4)失败请求数据的采集 5)结果树响应数据中文乱码解决办法 1. 前言 工 ...

  8. 域迁移DA | Learning From Synthetic Data: Addressing Domain Shift for Se | CVPR2018

    文章转自:微信公众号「机器学习炼丹术」 作者:炼丹兄(已授权) 联系方式:微信cyx645016617 论文名称:"Learning From Synthetic Data: Address ...

  9. 1038 Recover the Smallest Number

    Given a collection of number segments, you are supposed to recover the smallest number from them. Fo ...

  10. Relatives(容斥)

    Relatives Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15708   Accepted: 7966 Descri ...