15-Go语言面向对象

Go语言起别名

  • 在Go语言中可以通过type给某种类型起一个别名
    • 格式一:type 新类型名 原类型名
    • 格式二: type 新类型名=原类型名
  • 注意点:
    如果通过格式一, 代表定义了一个新的类型叫做 新类型名
    如果通过格式二, 代表给原类型名起了一个别名叫做新类型名
    也就是说通过格式一定义的 新类型 和 原类型在编译器看来是两个不同的类型
    通过格式二定义的 新类型 和 原类型在编译器看来是同一个类型
package main

import "fmt"

//1.第一种起别名方式
type Integer int
//2.第二种起别名方式
type Integer = int

func main() {
    /*
    1.在Go语言中可以通过type给某种类型起一个别名
    格式一: type 新类型名 原类型名
    格式二: type 新类型名=原类型名

    注意点:
    如果通过格式一, 代表定义了一个新的类型叫做 `新类型名`
    如果通过格式二, 代表给原类型名起了一个别名叫做`新类型名`
    也就是说通过格式一定义的 新类型 和 原类型在编译器看来是两个不同的类型
           通过格式二定义的  新类型 和 原类型在编译器看来是同一个类型
    */

    //第一种起别名方式
    var num1 int = 10
    fmt.Println(num1)
    fmt.Printf("%T\n", num1)
    var num2 Integer
    //不是相同类型的不能赋值
    //num2 = num1

    fmt.Println(num2)
    fmt.Printf("%T\n", num2)

    //第二种起名方式
    var num1 int = 10
    fmt.Println(num1)
    fmt.Printf("%T\n", num1)
    var num2 Integer
    //相同的类型可以相互赋值
    num2 = num1

    fmt.Println(num2)
    fmt.Printf("%T\n", num2)
}

Go语言属性方法公私有

  • 在Go语言中, 同一个包中的内容可以随意访问
  • 在Go语言中, 要想访问其它包中的内容, 那么内容名称的首字母必须大写
  • 要想访问全局变量, 导入对应的包之后, 可以通过 包名.变量名 的方式访问
  • 要想访问方法, 导入对应的包之后, 可以通过 包名.方法名 的方式访问
  • main包中的代码
package main

import (
    "fmt"
    "demo"
)

type person1 struct {
    name string
}
func main() {
    /*
    1.在Go语言中, 同一个包中的内容可以随意访问
    2.在Go语言中, 要想访问其它包中的内容, 那么内容名称的首字母必须大写

    3.要想访问全局变量, 导入对应的包之后, 可以通过 `包名.变量名` 的方式访问
    4.要想访问方法, 导入对应的包之后, 可以通过 `包名.方法名` 的方式访问
    */

    //1.访问不同包中的全局变量
    //fmt.Println(demo.value1) 访问不到
    fmt.Println(demo.Value2)

    //2.访问不同包中的函数
    //demo.say1()  访问不到
    demo.Say2()

    //访问本包中的结构体
    per1 := person1{"wjh"}
    fmt.Println(per1)
    //3.访问不同包中的函数
    //per2 := person2{"wjh"}  访问不到
    //注意点: 不仅结构体的类型名称首字母要大写, 结构体属性的名称首字母也要大写
    per3 := demo.Person3{"lnj"}
    //4.访问其他包中的方法
    per3.Run()
}
  • demo包中的代码
package demo

import "fmt"

//1.定义全局变量
var value1 = 10
var Value2 = 20

//2.定义函数
func say1()  {
    fmt.Println("say1")
}

func Say2()  {
    fmt.Println("say2")
}

//3.定义结构体
type person2 struct {
    name string
}

type Person3 struct {
    Name string
}

func (per person2)eat()  {
    fmt.Println("吃饭了")
}

func (per Person3)Run()  {
    fmt.Println("跑步啦")
}



Go语言面向对象

面向过程和面向对象
  • 面向过程
    • 强调的是功能行为
    • 关注的是解决问题需要哪些步骤
    • 所有事情都需要亲力亲为
  • 面向对象
    • 强调具备了功能的对象
    • 关注的是解决问题需要哪些对象
    • 所有事情都可以交给具备了功能的对象完成, 不用亲力亲为

创建对象
  • 在编程开发中如何创建一个对象?
    • 定义一个类
    • 通过定义的类创建对象

现实生活中要创建一个对象, 必须现有一个模型
例如: 生产汽车, 必须有图纸, 然后再根据图纸生产出具体的汽车
现实生活中的图纸, 就是用于描述汽车有哪些属性和行为
在编程中, 要想创建对象, 必须先有类编程中的类和现实生活中的图纸一样, 也是用于描述将来创建出来的对象有哪些属性和行为

//根据类创建一个对象
    per := Person{"wjh", 19}
    per.eat()
    per.run()

  • 如何定义一个类
    • 在类中说明有哪些属性和行为, 在Go语言中可以通过结构体来说明有哪些属性和行为
      结构体的属性 就是用于说明 属性的
      结构体的方法 就是用于说明 行为的
//定义一个类
type Person struct {
    name string //属性
    age int //属性
}

//定义行为(方法)
func (per Person)eat()  {
    fmt.Println(per.name, "吃饭啦")
}

func (per Person)run()  {
    fmt.Println(per.name, "跑步啦")
}

面向对象三大特征
  • 继承
    • 当一个类把自己的成员变量暴露给外部的时候,那么该类就失去对该成员变量的管理权,别人可以任意的修改你的成员变量
    • 封装之后: 提供了数据的安全性, 将变化隔离到了自己当中, 外界不用关心内部的处理, 只需要拿到方法使用即可
    • 封装的原则: 将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共的方法对其访问
package main

import (
    "demo"
    "fmt"
)

//定义一个类
//type Person struct {
//  name string
//  age int
//}

func main() {
    //当一个类把自己的成员变量暴露给外部的时候,那么该类就失去对该成员变量的管理权,别人可以任意的修改你的成员变量
    //创建一个对象
    //per := Person{"wjh", 19}
    //per.name = "haha" //外界可以随意修改类属性
    //fmt.Println(per)


    // 封装之后: 提供了数据的安全性, 将变化隔离到了自己当中, 外界不用关心内部的处理, 只需要拿到方法使用即可
    // 封装的原则: 将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共的方法对其访问
    //创建一个对象
    per := demo.Person{}
    per.SetName("lnj")
    per.SetAge(30)
    fmt.Println(per)

    fmt.Println(per.GetName()) //lnj
    fmt.Println(per.GetAge())  //30
}
package demo

//定义一个类
type Person struct {
    name string
    age int
}
//给外部提供访问
//本质就是提供两个公开的方法
func (per *Person)SetName(name string)  {
    per.name = name
}

func (per *Person)SetAge(age int)  {
    if age < 0 {
        age = 0
    }else if age >= 100 {
        age = 100
    }
    per.age = age

}

//获取属性参数的方法
func (per *Person)GetName()(name string)  {
    name = per.name
    return
}

func (per *Person)GetAge()(age int)  {
    age = per.age
    return
}
  • 继承
    • Go语言中继承的本质就是结构体嵌套,父类的结构体以子类匿名属性存在
    • 继承注意点
      • 子类可以使用父类的属性和方法
      • 如果子类和父类出现了重名的属性, 那么采用就近原则
      • 如果子类和父类出现了重名的属性, 要想访问父类的属性, 必须逐级查找
      • 如果子类和父类出现了重名的方法, 那么采用就近原则 (方法重载)
      • 如果子类和父类出现了重名的方法, 要想访问父类的方法, 必须逐级查找 (方法重载)
package main

import (
    "fmt"
)

//定义父类结构体
type Person struct {
    name string
    age  int
}

func (per *Person) say1() {
    fmt.Println(per.name, per.age, "是父类的方法")
}

type Student struct {
    Person       //继承父类的属性
    name  string //同名属性
    score float64
}

func (stu *Student) say1() {
    fmt.Println(stu.name, stu.age, "是子类的重名方法")
}

func (stu *Student) say2() {
    fmt.Println(stu.name, stu.age, stu.score, "是子类的方法")
}

//定义子类结构体
func main() {
    /*
    Go语言中继承的本质就是结构体嵌套,父类的结构体以子类匿名属性存在
    继承注意点:
    子类可以使用父类的属性和方法
    如果子类和父类出现了重名的属性, 那么采用就近原则
    如果子类和父类出现了重名的属性, 要想访问父类的属性, 必须逐级查找
    如果子类和父类出现了重名的方法, 那么采用就近原则 (方法重载)
    如果子类和父类出现了重名的方法, 要想访问父类的方法, 必须逐级查找 (方法重载)
    */

    //子类使用父类的属性和方法
    stu := Student{Person{"wjh", 19}, "lnj", 38.5}
    stu.name = "wjh" //使用父类的属性
    stu.age = 18
    stu.score = 32.5
    fmt.Println(stu)
    使用父类的方法
    stu.say1()
    stu.say2()

    fmt.Println(stu.name)        //lnj 就近原则
    fmt.Println(stu.Person.name) //wjh 逐级查找
    //方法的继承
    stu.say1()        //方法重载
    stu.Person.say1() //想访问父类方法,必须逐级查找
}
  • 多态
    • 多态就是某一类事物的多种形态
    • 在Go语言中通过接口来实现多态
package main

import "fmt"

//定义一个动物接口
type Animals interface {
    eat()
}

//定义狗的类
type Dog struct {
    name string
}

//实现接口方法
func (d Dog) eat() {
    fmt.Println(d.name, "吃东西")
}

//定义猫的类
type Cat struct {
    name string
}

//实现接口方法
func (c Cat) eat() {
    fmt.Println(c.name, "吃东西")
}
func main() {
    /*
    1.什么是多态?
    多态就是某一类事物的多种形态

    2.在Go语言中通过接口来实现多态
    */
    //旺财的狗形态
    //var dog Dog = Dog{"旺财"}
    //旺财的动物形态
    var dog Animals = Dog{"旺财"}
    dog.eat()

    //喵喵猫的形态
    //var cat = Cat{"喵喵"}
    //cat.eat()
    //喵喵动物的形态
    var cat Animals = Cat{"喵喵"}
    cat.eat()
    fmt.Printf("%T\n", cat)

    eat(cat)
    eat(dog)
}
//定义一个所有动物吃东西的函数
//提升了代码的复用性
func eat(ani Animals) {
    ani.eat()
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容