一、 golang面向对象介绍

1、golang也支持面向对象编程,但是和传统的面向对象编程有区别,并不是纯粹的面向对象语言。
2、golang没有类(class),golang语言的结合体(struct)和其它编程语言的类有同等的地位。
3、golang面向对象编程,去掉了传统语言面向对象的继承、方法重载、结构函数和析构函数、隐藏的this指针等。
4、goalng仍然有面向对象编程的继承,封装和多态的特性,。
5、golang面向接口编程非常重要

二、结构体创建注意事项

1、字段申明语法同变量
2、字段的类型可以为:基本类型、数组或应用类型
3、在创建一个结构体变量后,如果没有给字段赋值,都对应改类型的默认值(如bool为false,int为0,string为"")
4、不同结构体变量的字段是独立互不影响的,一个结构体变量字段的更改不会影响另一个结构体的值类型。

三、创建struct语法

type 结构体名称 struct{
field type
}

创建例子:

type stru struct{
a1 string
a2 int
a3 [5]float64
a4 []int //切片
a5 *int //指针
a6 map[string]string //map
}

  

使用例子:

package main
import "fmt" func main(){
type ss struct{
Name string
Age int
}
//1、直接申明
var ss1 ss
ss1.Name = "张三"
ss1.Age = 20
fmt.Println(ss1)
//2、使用{}
var ss2 ss = ss{"李四",22}
fmt.Println(ss2)
//3、&
var ss3 *ss = new(ss)
(*ss3).Name = "王五"
(*ss3).Age = 30
fmt.Println(ss3,*ss3)
//4、{}
var ss4 *ss = &ss{}
ss4.Name = "韩梅梅"
ss4.Age = 66
fmt.Println(ss4,*ss4) } ###结果###
{张三 20}
{李四 22}
&{王五 30} {王五 30}
&{韩梅梅 66} {韩梅梅 66}

  

四、结构体使用注意事项

1、结构体的所有字段在内存中是连续的

例子:

package main
import "fmt" type Point struct {
x int
y int
} type Test1 struct {
s1,s2 Point
} func main(){
a1 := Test1{Point{1,2},Point{3,4}}
//打印地址
fmt.Printf("%p,%p,%p,%p",&a1.s1.x,&a1.s1.y,&a1.s2.x,&a1.s2.y) } ##结果##
0xc4200141e0,0xc4200141e8,0xc4200141f0,0xc4200141f8

  

2、结构体是用户单独定义的类型,和其它类型进行转换时需要有完全相同的字段(名字、个数和类型

例子:

package main
import "fmt" type A struct {
x int
} type B struct {
x int
} func main(){
var a A
var b B
b.x = 2
a = A(b) //可以转换,但是结构体的字段和类型必须完全一样
fmt.Println(a,b)
} ###结果###
{2} {2}

  

3、结构体进行 type 重新定义(相当于取别名),Golang 认为是新的数据类型,但是相互间可以强转

例子:

package main
import "fmt" func main(){
type A struct {
x int
}
type B A
var s1 A
var s2 B
s2 = B(s1) //强转
fmt.Println(s1,s2) } ##结果##
{0} {0}

  

4、struct 的每个字段上,可以写上一个 tag, 该 tag 可以通过反射机制获取,常见的使用场景就是序列化和反序列化

序列化的使用场景:

例子:

package main
import (
"fmt"
"encoding/json"
)
type A struct {
Name string `json:"name"` //`json:"name"`就是struct的tag
Age int `json:"age"`
} func main(){
s1 := A{"张三",20}
//将s1变量序列化为json格式字符串
jsonStr,err := json.Marshal(s1)
if err != nil {
fmt.Println("json错误处理",err)
}
fmt.Println(string(jsonStr))
} ###结果###
{"name":"张三","age":20}

  

五、结构体的方法

方法的声明和调用
type A struct {
Num int
}
func (a A) test() {
fmt.Println(a.Num)
}
语法的说明
1) func (a A) test() {} 表示 A 结构体有一方法,方法名为 test
2) (a A) 体现 test 方法是和 A 类型绑定的

例子:

package main
import "fmt" type A struct {
Name string
}
//test方法只能公告A类型的变量类调用,不能直接调用,也不能使用其它类型变量来调用
func (a A) test(){ //将test方法绑定到A类型中,a的名字是随意指定的
fmt.Println("test()",a.Name)
} func (b A) add(n1,n2 int) int {
return n1 + n2
} func main(){
var x A
x.Name = "zhang"
x.test()
fmt.Println(x.add(1,2))
}
####结果####
test() zhang
3

  

六、golang面向对象的三大特性

1、封装

封装(encapsulation)就是把抽象出的字段和对字段的操作封装在一起,数据被保护在内部,程序的其它包只有通过被授权的操作(方法),才能对字段进行操作封装的好处

1、隐藏实现细节
2、提可以对数据进行验证,保证安全合理

2、封装的实现步骤

1) 将结构体、字段(属性)的首字母小写(不能导出了,其它包不能使用,类似 private)
2) 给结构体所在包提供一个工厂模式的函数,首字母大写。类似一个构造函数
3) 提供一个首字母大写的 Set 方法(类似其它语言的 public),用于对属性判断并赋值
func (var 结构体类型名) SetXxx(参数列表) (返回值列表) {
//加入数据验证的业务逻辑
var.字段 = 参数
}
4) 提供一个首字母大写的 Get 方法(类似其它语言的 public),用于获取属性的值func (var 结构体类型名) GetXxx() {return var.age

例子:

[root@localhostgo_test]#cat src/fz/fz.go
package fz
import "fmt" type T1 struct {
Name string
age int //开头是小写,其它包不能直接访问
} func Ss(name string) *T1 {
return &T1{
Name:name,
}
} func (a *T1) Getage() int {
fmt.Println(a.age)
return a.age
} [root@localhostgo_test]#cat class6.go
package main
import (
"fmt"
"fz"
) func main(){
x := fz.Ss("root")
fmt.Println(x)
x.Getage()
}
[root@localhostgo_test]#go run class6.go
&{root 0}
0

  

2、继承

继承可以解决代码复用,让我们的编程更加靠近人类思维。
当多个结构体存在相同的属性(字段)和方法时,可以从这些结构体中抽象出结构体,在该结构体中定义这些相同的属性和方法
在 Golang 中,如果一个 struct 嵌套了另一个匿名结构体,那么这个结构体可以直接访问匿名结构体的字段和方法,从而实现了继承特性

继承给编程带来的便利

1) 代码的复用性提高了
2) 代码的扩展性和维护性提

嵌套匿名结构体的基本语法
type Goods struct {
Name string
Price int
}
type Book struct {
Goods //这里就是嵌套匿名结构体 Goods
Writer string
}

例子:

package main
import "fmt" type A struct {
name string
age int
} func (p *A) Run() {
fmt.Println("Run...")
} type B struct {
A
b1 int
} type C struct {
A
} func (p *C) Crun() {
fmt.Println(p.name,p.age)
} func main(){
var q B
q.name = "qq"
q.age = 3
q.b1 = 20
q.Run()
fmt.Println(q)
fmt.Println("==========")
var w C
w.name = "ww"
w.age = 222
w.Run()
fmt.Println(&w) } ####结果######
Run...
{{qq 3} 20}
==========
Run...
&{{ww 222}}

  

3、多态(多态基于接口interface)

介绍:

变量(实例)具有多种形态。面向对象的第三大特征,在 Go 语言,多态特征是通过接口实现的。可以按照统一的接口来调用不同的实现。这时接口变量就呈现不同的形态

接口体现多态的两种形式

1、在下面interface的 Usb 接口案例,Usb usb ,即可以接收手机变量,又可以接收相机变量,就体现了Usb接口多态

2、多态数组

例子:给 Usb 数组中,存放 Phone 结构体 和 Camera 结构体变量

package main
import ( "fmt"
)
//声明/定义一个接口
type Usb interface {
//声明了两个没有实现的方法
Start()
Stop()
}
type Phone struct {
name string
}
//让 Phone 实现 Usb 接口的方法
func (p Phone) Start() {
fmt.Println("手机开始工作。。。")
}
func (p Phone) Stop() {
fmt.Println("手机停止工作。。。")
}
type Camera struct {
name string
}
//让 Camera 实现 Usb 接口的方法
func (c Camera) Start() {
fmt.Println("相机开始工作。。。")
}
func (c Camera) Stop() {
fmt.Println("相机停止工作。。。")
}
func main() {
//定义一个 Usb 接口数组,可以存放 Phone 和 Camera 的结构体变量
//这里就体现出多态数组
var usbArr [3]Usb
usbArr[0] = Phone{"vivo"}
usbArr[1] = Phone{"小米"}
usbArr[2] = Camera{"尼康"}
fmt.Println(usbArr)
} #####结果#######
[{vivo} {小米} {尼康}]

  

七、接口interface

简介

1、interface 类型可以定义一组方法,但是这些不需要实现。并且 interface 不能包含任何变量。到某个自定义类型要使用的时候,在根据具体情况把这些方法写出来实现

2、 接口里的所有方法都没有方法体,即接口的方法都是没有实现的方法。接口体现了程序设计的多态和高内聚低偶合的思想。
3、 Golang 中的接口,不需要显式的实现。只要一个变量,含有接口类型中的所有方法,那么这个变量就实现这个接口。因此,Golang 中没有 implement 这样的关键字

基本语法

例子:

package main
import ( "fmt"
)
//声明/定义一个接口
type Usb interface {
//声明了两个没有实现的方法
Start()
Stop()
}
type Phone struct {
}
//让 Phone 实现 Usb 接口的方法
func (p Phone) Start() {
fmt.Println("手机开始工作。。。")
}
func (p Phone) Stop() {
fmt.Println("手机停止工作。。。")
}
type Camera struct {
}
//让 Camera 实现 Usb 接口的方法
func (c Camera) Start() {
fmt.Println("相机开始工作。。。")
}
func (c Camera) Stop() {
fmt.Println("相机停止工作。。。")
}
//计算机
type Computer struct {
}
//编写一个方法 Working 方法,接收一个 Usb 接口类型变量
//只要是实现了 Usb 接口 (所谓实现 Usb 接口,就是指实现了 Usb 接口声明所有方法)
func (c Computer) Working(usb Usb) { //usb 变量会根据传入的实参,来判断到底是 Phone,还是 Camera
//通过 usb 接口变量来调用 Start 和 Stop 方法
usb.Start()
usb.Stop()
}
func main() {
//测试
//先创建结构体变量
computer := Computer{}
phone := Phone{}
camera := Camera{}
//关键点
computer.Working(phone)
computer.Working(camera)
} #####结果####
手机开始工作。。。
手机停止工作。。。
相机开始工作。。。
相机停止工作。。。

  

使用接口注意事项

1、接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量(实例)
2、接口中所有的方法都没有方法体,即都是没有实现的方法。
3、在 Golang 中,一个自定义类型需要将某个接口的所有方法都实现,我们说这个自定义类型实现了该接口。
4、一个自定义类型只有实现了某个接口,才能将该自定义类型的实例(变量)赋给接口类型
5、只要是自定义数据类型,就可以实现接口,不仅仅是结构体类型。
6、一个自定义类型可以实现多个接口
7、Golang 接口中不能有任何变量
8、一个接口(比如 A 接口)可以继承多个别的接口(比如 B,C 接口),这时如果要实现 A 接口,也必须将 B,C 接口的方法也全部实现。
9、interface 类型默认是一个指针(引用类型),如果没有对 interface 初始化就使用,那么会输出 nil
10、空接口 interface{} 没有任何方法,所以所有类型都实现了空接口, 即我们可以把任何一个变量赋给空接口

接口最佳实践例子:

package main
import ( "fmt"
"sort"
"math/rand"
)
//1.声明 Hero 结构体
type Hero struct{
Name string
Age int
}
//2.声明一个 Hero 结构体切片类型
type HeroSlice []Hero //3.实现 Interface 接口
func (hs HeroSlice) Len() int {
return len(hs)
}
//Less 方法就是决定你使用什么标准进行排序
//1. 按 Hero 的年龄从小到大排序!!
func (hs HeroSlice) Less(i, j int) bool {
return hs[i].Age < hs[j].Age
//修改成对 Name 排序
//return hs[i].Name < hs[j].Name
}
func (hs HeroSlice) Swap(i, j int) {
//交换
hs[i], hs[j] = hs[j], hs[i]
}
//1.声明 Student 结构体
type Student struct{
Name string
Age int
Score float64
}
//将 Student 的切片,安 Score 从大到小排序!!
func main() {
//先定义一个数组/切片
var intSlice = []int{0, -1, 10, 7, 90}
//要求对 intSlice 切片进行排序
//1. 冒泡排序...
sort.Ints(intSlice)
fmt.Println(intSlice)
//测试看看我们是否可以对结构体切片进行排序
var heroes HeroSlice
for i := 0; i < 10 ; i++ {
hero := Hero{
Name : fmt.Sprintf("英雄|%d", rand.Intn(100)), Age : rand.Intn(100), }
//将 hero append 到 heroes 切片
heroes = append(heroes, hero)
}
//看看排序前的顺序
for _ , v := range heroes {
fmt.Println(v)
}
sort.Sort(heroes)
fmt.Println("-----------排序后------------")
//看看排序后的顺序
for _ , v := range heroes {
fmt.Println(v)
}
i := 10
j := 20
i, j = j, i
fmt.Println("i=", i, "j=", j) // i=20 j = 10
} ######运行结果######
[-1 0 7 10 90]
{英雄|81 87}
{英雄|47 59}
{英雄|81 18}
{英雄|25 40}
{英雄|56 0}
{英雄|94 11}
{英雄|62 89}
{英雄|28 74}
{英雄|11 45}
{英雄|37 6}
-----------排序后------------
{英雄|56 0}
{英雄|37 6}
{英雄|94 11}
{英雄|81 18}
{英雄|25 40}
{英雄|11 45}
{英雄|47 59}
{英雄|28 74}
{英雄|81 87}
{英雄|62 89}
i= 20 j= 10

  

golang面向对象和interface接口的更多相关文章

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

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

  2. PHP面向对象(OOP):PHP5接口技术(interface)

    PHP与大多数面向对象编程语言一样,不支持多重继承.也就是说每个类只能继承一个父类.为了解决这个问题,PHP引入了接口,接口的思想是指定了一个实现了该接口的类必须实现的一系列方法.接口是一种特殊的抽象 ...

  3. Golang 入门系列(四)如何理解interface接口

    前面讲了很多Go 语言的基础知识,包括go环境的安装,go语言的语法等,感兴趣的朋友,可以先看看之前的文章.https://www.cnblogs.com/zhangweizhong/category ...

  4. Golang基础(8):go interface接口

    一:接口概要 接口是一种重要的类型,他是一组确定的方法集合. 一个接口变量可以存储任何实现了接口方法的具体值.一个重要的例子就是io.Reader和io.Writer type Reader inte ...

  5. java 面向对象(二十四):interface:接口

    interface:接口1.使用说明: 1.接口使用interface来定义 * 2.Java中,接口和类是并列的两个结构 * 3.如何定义接口:定义接口中的成员 * * 3.1 JDK7及以前:只能 ...

  6. Java面向对象之 接口: [修饰符] interface 接口名 {...};子接口:[修饰符] interface 接口名 extends 父接口,父接口2...{...}

    1.什么是接口? 类比抽象类,把功能或者特性类似的一类 抽象的更彻底,可以提炼出更加特殊的"抽象类"----接口 2.如何定义接口 语法:  [修饰符] interface 接口名 ...

  7. GoLang之方法与接口

    GoLang之方法与接口 Go语言没有沿袭传统面向对象编程中的诸多概念,比如继承.虚函数.构造函数和析构函数.隐藏的this指针等. 方法 Go 语言中同时有函数和方法.方法就是一个包含了接受者的函数 ...

  8. golang 面向对象编程

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

  9. go interface接口

    一:接口概要 接口是一种重要的类型,他是一组确定的方法集合. 一个接口变量可以存储任何实现了接口方法的具体值.一个重要的例子就是io.Reader和io.Writer type Reader inte ...

随机推荐

  1. 学习ASP.NET Core Razor 编程系列十六——排序

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  2. Window环境下搭建Git服务器

    如果公司要搭建自己的 Git 服务器,可以使用 gitblit 这个开源的 Git 服务器 下载gitblit安装包 到 http://gitblit.com/下载安装包 解压缩下载的压缩包即可,无需 ...

  3. Asp.Net Core 轻松学-项目目录和文件作用介绍

    前言     上一章介绍了 Asp.Net Core 的前世今生,并创建了一个控制台项目编译并运行成功,本章的内容介绍 .NETCore 的各种常用命令.Asp.Net Core MVC 项目文件目录 ...

  4. SmartCode 正式开源,不只是代码生成器!

    SmartCode(https://github.com/Ahoo-Wang/SmartCode) SmartCode = IDataSource -> IBuildTask -> IOu ...

  5. Java基础系列-equals方法和hashCode方法

    原创文章,转载请标注出处:<Java基础系列-equals方法和hashCode方法> 概述         equals方法和hashCode方法都是有Object类定义的. publi ...

  6. 1分钟解决VS每次运行都显示“正在还原nuget程序包”问题

    VS一直停留在“正在还原nuget程序包” 在开发中,运行不同版本的vs会显示还原nuget程序包,还原需要不短的时间,并且不一定还原成功. 或者其他什么原因导致需要还原nuget程序包,这样很烦的有 ...

  7. jQuery(一)、核心

    我认为,学习一门语言,主要是掌握它的思想与用途,就好比谈恋爱一样,你只要猜测到了对方的想法,就能够知情达意.废话不多说,我们开始今天学习的进度,加油ヾ(◍°∇°◍)ノ゙ 1. jQuery([sele ...

  8. mysql索引结构及其原理

    1.定义 索引是一种数据结果,帮助提高获取数据的速度 为了提高查找速度,有很多查询优化算法.但是每种查找算法都只能应用于特定数据结构之上. 索引就是数据库创建的满足特定查找算法的数据结构,这些数据结构 ...

  9. 基于Odoo框架的开源在线客服系统

    cs_base 开源客服系统,基于 Odoo 的客服模块 cs_base 是在强大的 Odoo 框架的基础上实现的一个在线客服应用 基础模块包含完整的 Web 在线客服的接入,坐席管理等,通过扩展可方 ...

  10. (详细)华为荣耀4X CHE-TL00H的usb调试模式在哪里打开的步骤

    每当我们使用PC通过数据线链上安卓手机的时候,如果手机没有开启usb开发者调试模式,PC则没能成功读到我们的手机,有时,我们使用的一些功能较强的工具好比之前我们使用的一个工具引号精灵,老版本就需要打开 ...