当前位置: 首页 > article >正文

Go语言面向对象编程

文章目录

      • Go语言面向对象
  • 一、结构体定义
      • 结构体定义
      • 结构体语法格式
  • 二、实例化结构体
      • 结构体的使用
      • 结构体实例化语法
      • new关键字
  • 三、初始化结构体变量
      • 结构体初始化
      • 顺序初始化
      • 指定初始化
  • 四、匿名结构体
      • 匿名结构体定义
      • 匿名结构体语法格式
  • 五、结构体内嵌
      • 结构体内嵌语法、特性
      • 键值对形式
      • 多值列表形式
      • 通过嵌套匿名结构体实现继承

在这里插入图片描述

银行ATM的例子
在这里插入图片描述
相较于面向过程,面向对象有以下优势:

  1. 容易命名
  • 在面向对象中,方法名相同但属于不同的类,这不会引起冲突,因为每个类定义了自己的方法和属性。相比之下,函数式编程中的函数名必须唯一,否则会导致冲突。
  1. 代码管理方便
  • 易于模块化开发。类中包含方法和属性,属性用来记录数据,方法表示行为,类实例化后为对象,行为和数据由对象来统一管理。写出来的代码方法与属性各归各类,代码逻辑清晰,利于扩展;函数也表示行为,但是与函数配合的数据却散落摆放,缺乏“类”这样的结构来统一管理。
  1. 重用性高
  • 代码冗余量小、重用性高。面向对象的代码在使用时,通过调用各个对象中的方法和属性,不同的排列组合就能适应各种不同的业务场景。

Go语言面向对象

  • 在其他编程语言中大多使用class关键字来定义封装对象,表示该类的具体特征,然而Go并不是一个纯面向对象的编程语言。在Go语言中的面向对象,采用更灵活的结构体替代了类。
  • Go语言并没有提供类class,但是它提供了结构体struct,方法method,可以在结构体上添加。提供了捆绑数据和方法的行为,这些数据和方法与类相似。
  • Go语言设计的非常简洁优雅,Go没有沿袭传统面向对象编程中的诸多概念,例如继承、虚方法、构造方法和析构方法等。
  • 虽然Go语言没有继承和多态。但是Go语言可以通过匿名字段实现继承,通过接口实现多态。在Go语言中学习面向对象,主要学习结构体struct、方法method、接口interface。

一、结构体定义

结构体定义

  • Go语言中没有“类”的概念,通过struct来实现面向对象
  • 通常用于表达一个事物的全部或部分属性
  • 一种自定义数据类型,可以封装多个基本数据类型
  • 本质是将零个或者多个任意类型的命名变量组合在一起的聚合数据类型
  • 每个变量叫做结构体的成员,变量名必须唯一,可用“_”补位
  • 支持使用自身指针类型成员

结构体语法格式

type 类型名 struct {
 字段名 字段类型
 字段名 字段类型
 ......
}

语法

  • 类型名:标识自定义结构体的名称,在同一个包内不能重复。
  • 字段名:表示结构体字段名,结构体中的字段名必须唯一。
  • 字段类型:表示结构体字段的具体类型。

案例

 type Student struct {
        stuID int
        stuName string
        age int
    }//成员变量通常一行写一个,变量的名称在类型的前面
 type Student struct {
        stuID,age int
        stuName string
}//相同类型的连续成员变量可以写在一行上。

示例1

 type Student1 struct {
        stuId,age int
        stuName,address string
        class,teacher string
    }

示例2

 type Student2 struct {
        stuId int
        address,stuName string
        age int
        class,teacher string
    }

  • 成员变量的顺序对于结构体同一性很重要
  • 相同类型的不连续成员变量不可以写在一行上

二、实例化结构体

结构体的使用

  • 结构体属于数据类型,因此和声明Go语言内置数据类型一样使用var关键字声明结构体类型
  • 只有当结构体实例化时,才会真正地分配内存
  • 必须实例化后才能使用结构体的字段

结构体实例化语法

var 结构体实例 结构体类型

示例:

package main
import "fmt"
func main()  {
    type person struct {
        name string
        city string
        age  int8
    }
    var p1 person	//实例化结构体
}

在定义一些临时数据结构等场景下还可以使用匿名结构体

package main
import "fmt"
func main()  {
    var p1 struct{name string;city string; age int}
}

new关键字

结构体实例 := new(结构体类型)
  • 使用new关键字实例化结构体后,得到的是结构体的地址;结构体类型为指针类型,但结构体本身仍然是值类型
  • 通过&符号对结构体取地址
  • 取地址的同时会将结构体实例化
package main
import "fmt"
func main()  {
    type person struct {
        name string
        city string
        age  int8
    }
    var p1 =new(person)
    //p1 := &person{}//相当于这样定义
}

三、初始化结构体变量

结构体初始化

  • 结构体类型的值可以通过结构体字面量来设置,即通过结构体的成员变量来设置
  • 有两种格式的结构体字面量:顺序初始化、指定成员初始化

顺序初始化

  • 要求顺序为每个成员变量指定一个值,这种格式必须记住每个成员变量的顺序

指定初始化

  • 通过指定部分或者全部成员变量的名称和值来初始化结构体变量,如果成员被忽略的话将默认用零值

在这里插入图片描述

package main
import (
	"fmt"
)
func main()  {
    type person struct {
        name string
        city string
        age  int8
    }
 //顺序初始化,每个成员必须初始化
    var p1 person
    p1.name = "Go语言"
    p1.city = "深圳"
    p1.age = 18
    fmt.Println(p1)
    //指定成员初始化,没有初始化的成员自动赋值为零
    p2 := person{name: "Golang"}
    fmt.Println(p2)
}


//运行结果为:
//{Go语言 深圳 18}
//{Golang  0}

四、匿名结构体

匿名结构体定义

  • 匿名结构体,顾名思义,即没有名字的结构体,与匿名函数类似
  • 匿名结构体无须type关键字就可以直接使用,匿名结构体在创建的同时也要创建对象
  • 匿名结构体的初始化和使用更加简单,无须通过type关键字定义,且不用写出类型名称

匿名结构体语法格式

结构体实例 := struct{
	//匿名结构体定义
	成员变量1 类型1
	成员变量2 类型2
	...
}{
  	//成员变量初始化(可选)
	成员变量1:1, 
	成员变量2:2,}

示例:

attribute2 := struct {
	Title, Publisher string
	Price            float64
	BookId           uint
	Discount         string
}{
	"唐宋传奇选",
	"人民文学出版社",
	15.1,
	566357,
	"6折",
}

五、结构体内嵌

结构体内嵌语法、特性

语法:

type 结构体1 struct{
    字段名1  字段类型1
    字段名2  字段类型2
}
type 结构体2 struct{
    结构体1
    字段名3  字段类型3
}

特性:

  • 是一种组合特性
  • 使用结构体内嵌可构建一种面向对象编程思想中的继承关系
  • 结构体实例化后,可直接访问内嵌结构体的所有成员变量和方法

示例:

//定义关于圆心坐标、圆、圆柱的结构体:
type Point struct {
    x,y int
}
type Circle struct {
    x,y,r int
}
type Cylinder struct {
    x,y,r,h int
}


//嵌入相同部分:
type Point struct {
    x,y int
}
type Circle struct {
    P Point
    r int
}
type Cylinder struct {
    C Circle
    h int
}

在这里插入图片描述

键值对形式

type 结构体1 struct{
    字段名1  字段类型1
    字段名2  字段类型2
}
type 结构体2 struct{
    结构体1
    字段名3  字段类型3
}


func main(){
    结构体实例 := 结构体2 {
        结构体1{
            字段名1:字段名1值
            字段名2:字段名2},
        字段名3:字段名3}
}

  • 键值对之间以逗号分割
  • 键值之间以冒号分割
  • 结构体成员的字段名应该具有唯一性

示例:

package main
import "fmt"
type rectangle struct {
    length,wide int
}
type cuboid struct {
    r rectangle
    high int
}


func main(){
    c :=cuboid{
        r:rectangle{
            length: 5,
            wide: 6,
        },
        high:7,
    }
    fmt.Println(c.r.length)
    fmt.Println(c.r.wide)
    fmt.Println(c.high)
}


//运行结果为:
//5
//6
//7

当访问结构体成员时会先在结构体中查找该字段,找不到再去匿名结构体中查找,但嵌套结构体内部可能存在相同的字段名。
这个时候为了避免歧义需要指定具体的内嵌结构体的字段。

package main
import "fmt"
type Address struct {
	City    string
	Country string   }
type ContactInfo struct {
	Phone string
         City  string    }
type Person struct {
	Name    string
	Address     // 匿名嵌套
	ContactInfo // 匿名嵌套
}
func main(){
   p := Person{
Name: "Alice",
Address: Address{
City:    "New York",
Country: "USA",     },
ContactInfo: ContactInfo{
Phone: "123-456-7890",
City:  "Los Angeles",
},   }   
fmt.Println("Person Name:", p.Name)
fmt.Println("Address City:", p.Address.City)}
fmt.Println("ContactInfo City:", p.ContactInfo.City)

当访问结构体成员时会先在结构体中查找该字段,找不到再去匿名结构体中查找,但嵌套结构体内部可能存在相同的字段名。
这个时候为了避免歧义需要指定具体的内嵌结构体的字段。

多值列表形式

type 结构体1 struct{
    字段名1  字段类型1
    字段名2  字段类型2
}
type 结构体2 struct{
    结构体1
    字段名3  字段类型3
}
func main(){
    结构体实例 := 结构体2 {
        结构体1{
            字段名1值
            字段名2},
        字段名3}
}

!必须初始化结构体所有字段 每一个初始值的填充顺序必须与字段在结构体中的声明顺序一致 键值对与多值列表的初始化形式不能混用

示例:

package main
import "fmt"
type rectangle struct {
    length,wide int
}
type cuboid struct {
    r rectangle
    high int
}
func main(){
    c :=cuboid{
        rectangle{
            5,
            6,
        },
        7,
    }
    fmt.Println(c.r.length)
    fmt.Println(c.r.wide)
    fmt.Println(c.high)
}


//运行结果为:
//5
//6
//7

通过嵌套匿名结构体实现继承

package main
import "fmt"
//Animal 动物
type Animal struct {
    name string
}
func (a *Animal) move() {
    fmt.Printf("%s会动!\n", a.name)
}
//Dog 狗
type Dog struct {
    Feet    int8
    *Animal //通过嵌套匿名结构体实现继承
}
func (d *Dog) wang() {
    fmt.Printf("%s会汪汪汪~\n", d.name)
}
func main() {
    d1 := &Dog{
        Feet: 4,
      Animal: &Animal{  //注意嵌套的是结构体指针
            name: "乐乐",
        },
    }
    d1.wang()
    d1.move()
}



//运行结果为:
//乐乐会汪汪汪~
//乐乐会动!


http://www.kler.cn/a/387199.html

相关文章:

  • HTTP常见的请求头有哪些?都有什么作用?在 Web 应用中使用这些请求头?
  • 【go从零单排】JSON序列化和反序列化
  • Python →爬虫实践
  • Android Studio 将项目打包成apk文件
  • 卓胜微嵌入式面试题及参考答案(2万字长文)
  • 除了 Mock.js,前端还有更方便的 Mock 数据工具吗?
  • 【GESP】C++一级真题练习(202312)luogu-B3921,小杨的考试
  • mysql的高级进阶
  • 前端刺客系列----Vue 3 入门介绍
  • 数据挖掘(十)
  • Elasticsearch与Redis的Netty冲突
  • CentOS 9 Stream 上安装 PostgreSQL 16
  • C++builder中的人工智能(18):神经网络中的SoftMax函数
  • el-tab使用
  • 新手如何快速搭建一个Springboot项目
  • 代码随想录刷题记录(二十五)——54. 替换数字
  • 【信号处理】绘制IQ信号时域图、星座图、功率谱
  • 吾店云介绍 – 中国人的WordPress独立站和商城系统平台
  • docker进行SRS直播服务器搭建
  • WPS 默认模板修改
  • 关于qiskit版本>1.0.0,execute函数被替换
  • Java基于微信小程序的美食推荐系统(附源码,文档)
  • ONLYOFFICE 办公套件测评:高效办公新选择
  • 「Mac畅玩鸿蒙与硬件32」UI互动应用篇9 - 番茄钟倒计时应用
  • Python自动化运维:配置管理工具到自动化部署与版本控制
  • Flutter错误: uses-sdk:minSdkVersion 16 cannot be smaller than version 21 declared