Go_面向对象

GO语言中没有class的定义, 但是struct实现了class的功能(方法, 继承等)

struct声明

type 标识符 struct{
    field1 type
    field2 type
}

//例子
type Student struct{
    Name string
    Age int
    Score int
}

// 新名字,
定义了一种新的类型, 其中字段与Student相同
type Stu Student
type inter int

声明定义及访问

声明

var stu student
var stu *Student = new(Student) // 返回指针
var stu *Student = &Student{字段:值,字段:值}// 返回指针

访问

// 通过.的方式去取值和设置值
func main() {
	var stu Student
	stu.Name = "自由"
	stu.Age = 18
	stu.Score = 60
	fmt.Println(stu)
}

ps:

  •   无论变量是指针类型还是非指针类型都可以直接使用.的方式去操作
  •   结构体在内存中的布局是连续的, 是指类型, 函数传递要传递指针
  •   struct没有构造函数, 一般可以使用工厂模式来解决
    func NewStudent(name string, age int) *Student{
        return &student{
            Name:name,
            Age: age    
        }
    }
    

      

Tag :   我们可以为struct中的每个字段, 写上一个tag.这个tag可以通过反射机制获取到

type Student struct{
    Name string "this is name field"
    Age int "this is age field"
}

方法

go中的方法作用域特定类型的变量上, 因此自定义类型都可以有方法, 而不仅仅是struct

定义

func (object type) methodname (args) ( rets ){
  // 方法体  
} 

示例

type Student struct{
    Name string
    Age int
    Score int
    sex int
}

func (p Student) init(name string, age int, score int){
    p.Name = name
    p.Age = age
    p.Score = score
}

func main(){
    var stu Student
    stu.init("stu", 18, 100)
}

不过上面的例子中并不会对stu产生影响, 因为p是stu的备份, 我们可以修改方法,使其接收指针

func (p *Student) init(name string, age int, score int){
    (*p).Name = name
    (*p).Age = age
    (*p).Score = score
}

func main(){
    var stu Student
    stu.init("stu", 18, 100)
}

  向上面这种不断的取值很麻烦, 好在go帮我们解决了此事, 当传入的是个指针时我们可以直接通过.的方式去去柱子

func (p *Student) init(name string, age int, score int){
    p.Name = name
    p.Age = age
    p.Score = score
}
// 可以改变调用者的值

继承

结构体中的匿名字段, 变量可以直接去访问匿名变量的字段

type Animal struct{
	Name string
	Age int
}

type Dog struct{
	Animal
	Colour string
}

func main(){
	var dog Dog
	dog.Name = "旺财"
	dog.Age = 2
	dog.Colour = "斑点"
	fmt.Println(dog.Name, dog.Age, dog.Colour)
}

名称冲突

当结构体中的字段与其内部匿名字段中的字段同名时, 默认访问的是自己的

当两个匿名字段中的字段相同时

type Sitiaotui struct{
	Name string
}

type Dog struct{
	Animal
	Sitiaotui
	Colour string
}

func main(){
	var dog Dog
	dog.Animal.Name = "旺财"
	dog.Age = 2
	dog.Colour = "斑点"
	fmt.Println(dog.Animal.Name, dog.Age, dog.Colour)
}

方法的继承同字段相同

访问控制

属性及方法的首字母, 同包

接口

接口也是一种类型, 接口的应用相当的灵活. 

接口规定了了实现了他的类必须定义的方法, 而在Go中不需要声明实现接口, 只要实现了该接口中的方法就可以认为实现了该接口.

接口定义

Interface类型可以定义一组方法, 但是这些不需要实现. 并且interface不能包含任何变量

type Test interface{
    function(args)(rets)
}

实现
结构体有指定方法就实现了该接口, 接口变量是个指针类型
一个类型实现了一个接口, 这个类型就可以给这个接口赋值

package main

import "fmt"

type Student struct{
	Name string
	Age int
	Score int
	sex int
}

type Test interface {
	print()
}

func (p Student) print(){
	fmt.Println(p)
}

func main(){
	var t Test
	var stu Student = Student{
		Name :"lihua",
		Age : 18}
	t = stu  // 可以赋值给接口类型
	t.print()
}

接口的嵌套

type Writer interface{
    Write()
}

type Reader interface{
    Read()
}

type ReadWrite interface{
    Reader
    Writer
}

func Test(rw ReadWriter){
    rw.Read()
    rw.Write()
}

空接口 interface{}: 任何类型都可以赋值给空接口类型的变量

String()方法 : Print调用的方法

package main

import "fmt"

type Student struct{
	Name string
	Age int
	Score int
	sex int
}

func (p Student) String() string {
	return fmt.Sprintf("%s,%d, %d",p.Name, p.Age, p.sex)
}

func main(){

	var stu Student = Student{
		Name :"lihua",
		Age : 18}
	fmt.Println(stu) // lihua,18, 0
}

类型断言

将一个接口变量转换成类型

当确定类型时:

func main(){

	var a interface{}
	var b int
	a = b

	c := a.(int) // 转回其他类型
	fmt.Printf("%d %T", c,c)
}

当不确定类型时, 带有错误信息

func main(){
	s := 100
	if v, ok := interface{}(s).(string); ok {
		fmt.Println(v)
	}else{
		fmt.Println("不能转")
	}
}

上面这种也可以判断是否实现了某个接口

type Test interface {
	print()
}

func (p Student) print(){
	fmt.Println(p)
}

func main(){

	var stu Student = Student{
		Name :"lihua",
		Age : 18}

	t, ok := interface{}(stu).(Test)
	fmt.Println(t, ok, stu)
}

返回具体类型

package main

import (
	"fmt"
)

type Element interface {}

func main() {
	var e Element = 100
	switch value := e.(type) {
	case int:
		fmt.Println("int", value)
	case string:
		fmt.Println("string", value)
	default:
		fmt.Println("unknown", value)
	}
}

  

 

posted @ 2018-09-09 18:05  瓜田月夜  阅读(103)  评论(0)    收藏  举报