Go面向对象(三)
go语言中的大多数类型都是值予以,并且都可以包含对应的操作方法,在需要的时候你可以给任意类型增加新方法。二在实现某个接口时,无需从该接口集成,只需要实现该接口要求的所有方法即可。任何类型都可以被any类型引用。any类型是空接口 interface{}
package mainimport ("fmt")func main() {person.Go2School()}func (ps Person) Go2School() {fmt.Println("go to school")}
- 基本类型,如byte、int、bool、float32、float64和string等;
复合类型,如数组(array)、结构体(struct)和指针(pointer)等。
值语义和引用语义
a := 10b := ab = b + 1fmt.Println(b)fmt.Println(a)输出:11,10c := 10d := &c*d += 1fmt.Println(c)fmt.Println(*d)输出:11,11
Go语言中有4个类型比较特别,看起来像引用类型
接口(interface):对一组满足某个契约的类型的抽象
结构体
定义:type Rect struct {x, y float64width, height float64}初始化rect1 := new(Rect)rect2 := &Rect{}rect3 := &Rect{0, 0, 100, 200}rect4 := &Rect{width: 100, height: 200}
构造函数
package main//person类type Person struct {Name stringAge intSex string}//person构造函数func NewPerson(name string, sex string, age int) *Person {return &Person{Name: name, Sex: sex, Age: age}}//person类ResetName1方法 (传值)func (ps Person) ResetName1(name string) {ps.Name = name}//person类ResetName1方法 (传址)func (ps *Person) ResetName2(name string) {ps.Name = name}//student类type Student struct {Class stringGrade string*Person}//student构造函数func NewStudent(name string, sex string, age int, class string, grade string) *Student {return &Student{Person: NewPerson(name, sex, age), Class: class, Grade: grade}}
匿名组合:类的继承是使用了匿名组合的方式
package maintype Person struct {Name stringAge intSex string}//构造函数func NewPerson(name string, sex string, age int) *Person {return &Person{Name: name, Sex: sex, Age: age}}func (ps Person) ResetName1(name string) {ps.Name = name}func (ps *Person) ResetName2(name string) {ps.Name = name}//继承自Persontype Student struct {Class stringGrade stringPerson //或者*Person}这样Student就继承自了 Person类
可见性
要使某个符号对其他包(package)可见(即可以访问),需要将该符号定义为以大写字母开头
type Rect struct {X, Y float64Width, Height float64}
这样,Rect类型的成员变量就全部被导出了,可以被所有其他引用了Rect所在包的代码访问到。
func (r *Rect) area() float64 {return r.Width * r.Height}这样,Rect的area()方法只能在该类型所在的包内使用。
Go语言中符号的可访问性是包一级的而不是类型一级的
- 入侵接口c#和Java中的接口时入侵是接口
- 非入侵接口go的接口是非入侵式接口
type File struct {// ...}func (f *File) Read(buf []byte) (n int, err error)func (f *File) Write(buf []byte) (n int, err error)func (f *File) Seek(off int64, whence int) (pos int64, err error)func (f *File) Close() error
type IFile interface {
Read(buf []byte) (n int, err error)Write(buf []byte) (n int, err error)Seek(off int64, whence int) (pos int64, err error)Close() error
}type IReader interface {Read(buf []byte) (n int, err error)}type IWriter interface {Write(buf []byte) (n int, err error)}type ICloser interface {Close() error}
var file1 IFile = new(File)var file2 IReader = new(File)var file3 IWriter = new(File)var file4 ICloser = new(File)
其一,Go语言的标准库,再也不需要绘制类库的继承树图。你一定见过不少C++、Java、C#类库的继承树图。在Go中,类的继承树并无意义,你只需要知道这个类实现了哪些方法,每个方法是啥含义就足够了。其二,实现类的时候,只需要关心自己应该提供哪些方法,不用再纠结接口需要拆得多细才合理。接口由使用方按需定义,而不用事前规划。其三,不用为了实现一个接口而导入一个包,因为多引用一个外部的包,就意味着更多的耦合。接口由使用方按自身需求来定义,使用方无需关心是否有其他模块定义过类似的接口
- 将对象实例赋值给接口;
- 将接口实例赋值给接口;
//对象赋值给接口var interfaces IStudent = NewStudent("Jessica", "male", 18, "class1", "grade1")interfaces.Go2School()
package one
type ReadWriter interface {
Read(buf []byte) (n int, err error)
Write(buf []byte) (n int, err error)
}
package two
type IStream interface {
Write(buf []byte) (n int, err error)
Read(buf []byte) (n int, err error)
}
任何实现了one.ReadWriter接口的类,均实现了two.IStream; 任何one.ReadWriter接口对象可赋值给two.IStream,反之亦然; 在任何地方使用one.ReadWriter接口与使用two.IStream并无差异。
var file1 two.IStream = new(File)
var file2 one.ReadWriter = file1
var file3 two.IStream = file2
type Writer interface {Write(buf []byte) (n int, err error)}
var file1 two.IStream = new(File)var file4 Writer = file1
// OOPTest project main.go
package main
type IStudent interface {
Go2School()
}
type IPerson interface {
Speak(word string)
Eat(food string)
}
func main() {
//std := NewStudent("Jessica", "male", 18, "class1", "grade1")
//psn := NewPerson("James", "female", 20)
//语句switch中的value必须是接口类型,变量str的类型为转换后的类型。/
var IStd interface{} = NewStudent("Jessica", "male", 18, "class1", "grade1")
switch per := IStd.(type) {
case IStudent:
per.Go2School()
case IPerson:
per.Eat("pig")
}
}类型断言
// OOPTest project main.go
package main
type IStudent interface {
Go2School()
}
type IPerson interface {
Speak(word string)
Eat(food string)
}
func main() {
//std := NewStudent("Jessica", "male", 18, "class1", "grade1")
//psn := NewPerson("James", "female", 20)
//语句switch中的value必须是接口类型,变量str的类型为转换后的类型。
var IStd interface{} = NewStudent("Jessica", "male", 18, "class1", "grade1")
//switch per := IStd.(type) {
//case IStudent:
// per.Go2School()
//case IPerson:
// per.Eat("pig")
//}
//上面的转换有一个问题,如果该值不包含一个字符串,则程序会产生一个运行时错误。为了避免这个问题,可以使用“comma, ok”的习惯用法来安全地测试值是否为一个字符串:
if types, ok := IStd.(IStudent); ok {
types.Go2School()
} else if types, ok := IStd.(IPerson); ok {
types.Eat("pig")
}
}
接口组合:接口的继承
type IStudentinterface{Go2School()}type IPersoninterface{Speak(word string)Eat(food string)}type Animalinterface{IPersonIStudent}
var v1 interface{}=1// 将int类型赋值给interface{}var v2 interface{}="abc"// 将string类型赋值给interface{}var v3 interface{}=&v2 // 将*interface{}类型赋值给interface{}var v4 interface{}=struct{ X int}{1}var v5 interface{}=&struct{ X int}{1}
func Printf(fmt string, args ...interface{})func Println(args ...interface{})
过接口查询和类型查询逐步了解它。
Go面向对象(三)的更多相关文章
- Python面向对象三要素-继承(Inheritance)
Python面向对象三要素-继承(Inheritance) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.继承概述 1>.基本概念 前面我们学习了Python的面向对象三 ...
- Python面向对象三要素-封装(Encapsulation)
Python面向对象三要素-封装(Encapsulation) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.封装概述 将数据和操作组织到类中,即属性和方法 将数据隐藏起来,给 ...
- JavaScript 面向对象(三) —— 高级篇
JavaScript 面向对象(一) —— 基础篇 JavaScript 面向对象(二) —— 案例篇 一.json方式的面向对象 首先要知道,js中出现的东西都能够放到json中.关于json数据格 ...
- JavaScript面向对象(三)——继承与闭包、JS实现继承的三种方式
前 言 JRedu 在之前的两篇博客中,我们详细探讨了JavaScript OOP中的各种知识点(JS OOP基础与JS 中This指向详解 . 成员属性.静态属性.原型属性与JS原型链).今天 ...
- Python之面向对象三
面向对象的三大特性: 多态 多态指的是一类事物有多种形态.Python3天生支持多态. 动物有多种形态:人,狗,猪 import abc class Animal(metaclass=abc.ABCM ...
- Python面向对象(三)
一.绑定方法与非绑定方法 一.绑定方法:绑定给谁就应该由谁来调用,谁来调用就会将谁当作第一个参数传入 1.绑定给对象的方法:类中定义的函数默认就是绑定给对象的 2.绑定给类的方法:为类中定义的函数加上 ...
- Python面向对象三要素-多态
Python面向对象3要素-多态 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.多态概述 OCP原则:多用“继承”,少修改. 继承的用途:在子类上实现对基类的增强,实现多态. ...
- javascript面向对象(三):非构造函数的继承
本文来自阮一峰 这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现"继承". 今天是最后一个部分,介绍不使用构造函数实现"继承" ...
- Objective-C面向对象(三)
1.类的继承 OC的继承是单继承,每个子类只有一个直接父类 1.1 继承的特点 OC继承的语法 @interface SubClass :SuperClass { //成员变量定义 } //方法定义部 ...
- Java学习笔记10(面向对象三:接口)
接口: 暂时可以理解为是一种特殊的抽象类 接口是功能的集合,可以看作是一种数据类型,是比抽象类更抽象的"类" 接口只描述所应该具备的方法,并没有具体实现,具体实现由接口的实现类(相 ...
随机推荐
- git 忽略已经添加到版本库的文件
第一步: 指令:git rm -r --cached YOUR_PATH YOUR_PATH 即 你的文件,-r 指定了递归所有的子文件夹. 第二步: 修改项目根目录下的 .gitignore 文件, ...
- mysql innodb_buffer_pool_size mysql占用内存大小和主从复制并行线程数量
innodb_buffer_pool_size set global slave_parallel_workers=4;
- 百度地图Api进阶教程-地图鼠标左右键操作实例和鼠标样式6.html
<!DOCTYPE html> <html> <head> <meta name="viewport" content="ini ...
- pdf ppt word office转图片 教学白板
https://zh-cn.libreoffice.org/ http://www.imagemagick.org/script/ 首先用libreoffice将ppt转换为pdf格式,然后再用con ...
- 微信小程序文字水平垂直居中对齐问题
我们知道常用的居中对齐方式有很多种例如: text-align:center; align-items:center; justify-content: center; margin: auto; # ...
- Navi.Soft31.代码生成器(含下载地址)
1系统简介 1.1功能简述 在Net软件开发过程中,大部分时间都是在编写代码,并且都是重复和冗杂的代码.比如:要实现在数据库中10个表的增删改查功能,大部分代码都是相同的,只需修改10%的代码量.此时 ...
- Java设计模式(6)桥模式(Bridge模式)
Bridge定义:将抽象和行为划分开来,各自独立,但能动态的结合. 为什么使用桥模式 通常,当一个抽象类或接口有多个具体实现(concrete subclass),这些concrete之间关系可能有以 ...
- 100 行代码实现的 JavaScript MVC 样式框架
介绍 使用过 JavaScript框架(如 AngularJS, Backbone 或者Ember)的人都很熟悉在UI(用户界面,前端)中mvc的工作机理.这些框架实现了MVC,使得在一个单页面中实现 ...
- LINUX ORACLE 启动与关闭
1.环境变量 如果没有配置环境变量的要配置哟,已配置就不用配置了! export ORACLE_BASE=/home/oracle/app export ORACLE_HOME=$ORACLE_BAS ...
- Numpy 用于数组的文件输入和输出
将数组以二进制格式保存 np.save 和np.load 是读写磁盘数组数据的两个主要函数.默认情况下,数组是以未压缩的原始二进制格式进行保持在扩展名 为.npy的文件中的 如果文件路径末尾没有扩展名 ...