golang

15-Go语言面向对象

2018-09-25  本文已影响369人  极客江南

面向对象基本概念

面向对象思想


面向对象和面向过程区别






面向对象的特点


类与对象的关系


如何设计一个类

事物名称(类名):人(Person)
属性:身高(height)、年龄(age)
行为(功能):跑(run)、打架(fight)

如何分析一个类

飞机
炮弹
装甲车
老王
热狗
草泥马

如何定义一个类

type Person struct {
    name string // 人的属性
    age int // 人的属性
}
// 人的行为
func (p Person)Say()  {
    fmt.Println("my name is", p.name, "my age is", p.age)
}

如何通过类创建一个对象

// 3.创建一个结构体变量
    p1 := Person{"lnj", 33}
    per.say()

    p2 := Person{"zs", 18}
    per.Say()

不同包中变量、函数、方法、类型公私有问题

package demo

import "fmt"

var num1 int = 123 // 当前包可用
var Num1 int = 123 // 其它包也可用

type person struct { // 当前包可用
    name string // 当前包可用
    age int // 当前包可用
}

type Student struct { // 其它包也可用
    Name string // 其它包也可用
    Age int // 其它包也可用
}

func test1()  { // 当前包可用
    fmt.Println("test1")
}
func Test2()  { // 其它包也可用
    fmt.Println("Test2")
}

func (p person)say()  { // 当前包可用
    fmt.Println(p.name, p.age)
}
func (s Student)Say()  { // 其它包也可用
    fmt.Println(s.Name, s.Age)
}

面向对象三大特性

package model
import "fmt"
type Person struct { // 其它包也可用
    name string // 当前包可用
    age int // 当前包可用
}
func (p *person)SetAge(age int)  {
    // 安全校验
    if age < 0 {
        fmt.Println("年龄不能为负数")
    }
    p.age = age
}
package main
import (
    "fmt"
    "main/model"
)
func main()  {
    // 报错, 因为name和age不是公开的
    //p := model.Person{"lnj", 18}

    // 方式一
    //p := model.Person{}
    //p.SetAge(18)
    //fmt.Println(p)

    // 方式二
    //p := new(model.Person)
    //p.SetAge(18)
    //fmt.Println(p)
}

package main

import "fmt"

type Person struct {
    name string
    age int
}
type Student struct {
    Person // 学生继承了人的特性
    score int
}
type Teacher struct {
    Person // 老师继承了人的特性
    Title string
}
func main()  {
    s := Student{Person{"lnj", 18}, 99}
    //fmt.Println(s.Person.name)
    fmt.Println(s.name) // 两种方式都能访问
    //fmt.Println(s.Person.age)
    fmt.Println(s.age) // 两种方式都能访问
    fmt.Println(s.score)
}
package main

import "fmt"

type Person struct {
    name string // 属性重名
    age int
}
type Student struct {
    Person
    name string // 属性重名
    score int
}
func main()  {
    s := Student{Person{"zs", 18}, "ls", 99}

    fmt.Println(s.Person.name) // zs
    fmt.Println(s.name) // ls
    //fmt.Println(s.Person.age)
    fmt.Println(s.age) // 两种方式都能访问
    fmt.Println(s.score)
}
package main

import "fmt"

type Object struct {
    life int
}
type Person struct {
    Object
    name string
    age int
}
type Student struct {
    Person
    score int
}
func main()  {
    s := Student{Person{Object{77}, "zs", 33}, 99}
    //fmt.Println(s.Person.Object.life)
    //fmt.Println(s.Person.life)
    fmt.Println(s.life) // 三种方式都可以
    //fmt.Println(s.Person.name)
    fmt.Println(s.name) // 两种方式都能访问
    //fmt.Println(s.Person.age)
    fmt.Println(s.age) // 两种方式都能访问
    fmt.Println(s.score)
}
package main

import "fmt"

type Object struct {
    life int
}
type Person struct {
    name string
    age int
}
type Student struct {
    Object
    Person
    score int
}
func main()  {
    s := Student{Object{77}, Person{"zs", 33}, 99}
    //fmt.Println(s.Person.life)
    fmt.Println(s.life) // 两种方式都可以
    //fmt.Println(s.Person.name)
    fmt.Println(s.name) // 两种方式都能访问
    //fmt.Println(s.Person.age)
    fmt.Println(s.age) // 两种方式都能访问
    fmt.Println(s.score)
package main

import "fmt"
type Person struct {
    name string
    age int
}
// 父类方法
func (p Person)say()  {
    fmt.Println("name is ", p.name, "age is ", p.age)
}

type Student struct {
    Person
    score float32
} 

func main() {
    stu := Student{Person{"zs", 18}, 59.9}
    stu.say()
}
package main

import "fmt"
type Person struct {
    name string
    age int
}
// 父类方法
func (p Person)say()  {
    fmt.Println("name is ", p.name, "age is ", p.age)
}

type Student struct {
    Person
    score float32
}
// 子类方法
func (s Student)say()  {
    fmt.Println("name is ", s.name, "age is ", s.age, "score is ", s.score)
}
func main() {
    stu := Student{Person{"zs", 18}, 59.9}
    // 和属性一样, 访问时采用就近原则
    stu.say() 
    // 和属性一样, 方法同名时可以通过指定父类名称的方式, 访问父类方法
    stu.Person.say()
}

猫: 猫-->动物
狗: 狗-->动物
男人 : 男人 -->人 -->高级动物
女人 : 女人 -->人 -->高级动物
package main

import "fmt"
// 1.定义接口
type Animal interface { 
    Eat()
}
type Dog struct {
    name string
    age int
}
// 2.实现接口方法
func (d Dog)Eat()  {
    fmt.Println(d.name, "正在吃东西")
}

type Cat struct {
    name string
    age int
}
// 2.实现接口方法
func (c Cat)Eat()  {
    fmt.Println(c.name, "正在吃东西")
}
// 3.对象特有方法
func (c Cat)Special()  {
    fmt.Println(c.name, "特有方法")
}

func main()  {
    // 1.利用接口类型保存实现了所有接口方法的对象
    var a Animal
    a = Dog{"旺财", 18}
    // 2.利用接口类型调用对象中实现的方法
    a.Eat()
    a = Cat{"喵喵", 18}
    a.Eat()
    // 3.利用接口类型调用对象特有的方法
    //a.Special() // 接口类型只能调用接口中声明的方法, 不能调用对象特有方法
    if cat, ok := a.(Cat); ok{
        cat.Special() // 只有对象本身才能调用对象的特有方法
    }
}
上一篇 下一篇

猜你喜欢

热点阅读