


























面向对象定义
面向对象三要素:
实现了以上特征的语言,才能成为面向对象编程范式语言。 严格意义来说,Go语言就是不想实现面向对象编程范式。但是面向对象又有一些不错的特性,Go语言 通过组合的方式实现了类似的功能。 只能说,Go语言实现了一种非常有自我特征的面向对象。
封装
通过结构体,可以把数据字段封装在内,还可以为结构体提供方法。
访问控制:
构造函数
Go没有提供类似C++、Java一样的构造函数、析构函数。在Go中,用构造结构体实例的函数,这个函数 没有特别的要求,只要返回结构体实例或其指针即可(建议返回指针,不然返回值会拷贝)。习惯上, 构造函数命名是New或new开头。如果有多个构造函数,可以使用不同命名函数,因为Go也没有函数重载。通过不同的函数名来模拟构造函数重载。
type Animal struct { name string age int } func NewDefaultAnimal() *Animal { return &Animal{"nobody", 1} } func NewAnimal(name string, age int) *Animal { return &Animal{name, age} }
继承
Go语言没有提供继承的语法,实际上需要通过匿名结构体嵌入(组合)来实现类似效果。
package main import "fmt" type Animal struct { name string age int } func (*Animal) run() { fmt.Println("Animal run~~~") } type Cat struct { Animal // 匿名结构体嵌入 color string } func main() { cat := new(Cat) cat.run() cat.Animal.run() }
通过匿名结构体嵌入,子结构体就拥有了父结构体的属性name、age,和run方法。
覆盖
覆盖override,也称重写。不是重载overload。
// 为Cat增加一个run方法,这就是覆盖。 func (*Cat) run() { fmt.Println("Cat run+++") }
上例增加run方法是完全覆盖,就是不依赖父结构体方法,重写功能。 如果是依赖父结构体方法,那就要在子结构体方法中显式调用它。
func (c *Cat) run() { c.run() // 这里不可这样写,成递归了 c.Animal.run() // 这是调用父结构体方法。 fmt.Println("Cat run+++") }
多态
Go语言不能像Java语言一样使用多态,但可以通过引入interface接口来解决。

package main import "fmt" type Runner interface { run() } type Animal struct { name string age int } func (*Animal) run() { fmt.Println("Animal run~~~") } type Cat struct { Animal // 匿名结构体嵌入 color string } func (c *Cat) run() { c.Animal.run() fmt.Println("Cat run+++") } type Dog struct { Animal // 匿名结构体嵌入 color string } func (d *Dog) run() { d.Animal.run() fmt.Println("Dog run+++") } func test(a Runner) { // 多态 a.run() } func main() { // var a Animal = Cat{} // Go做不到这样赋值 // a.run() // Go无法写出这2行,用接口 d := new(Dog) d.name = "snoopy" test(d) c := new(Cat) c.name = "Garfield" test(c) test(d) }
示例
test使用同一个类型的同一个接口却表现不同,这就是多态。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。