golang是否支持面向对象
答案是肯定的。golang官方虽然没有明确提出面向对象的概念,但是基于已有的语法设计,我们可以实现面向对象的编程设计。
我们可以借助 struct
和 interface
来实现。
表示一个对象
struct
和 class
type Program struct{
name string
ver float32
}
program := Program{"golang",1.13}
此结构体表示了一个编程语言类,用面向对象来看, name
和 ver
就是成员变量。有了成员变量,那么又该如何表示 成员方法
呢,来看一下代码:
func (program *Program) showProgramInfo(){
fmt.Printf("this languge is %s , ver is %d", languge.name,languge.ver)
}
func (program *Program) setVer(ver float32){
languge.ver = ver
}
program := Program{"golang",1.13}
program.showLangugeInfo()
program.setVer(1.14)
fmt.Println(program)
在函数名之前使用小括号,传入声明的结构体指针、变量名
,也可以不用指针,写成(languge Languge)
,但是这样就无法覆盖实参来改变结构体内部的值,所以一般都用指针。这样 showLangugeInfo() , setVer()
实际上就是面向对象的 成员方法了
。
继承
在面向对象的语言中,一般都是用关键字 extends
来表示继承的,golang中没有这种明确的继承方法,但实际来表示继承非常简单,不需要额外关键字。
type Application struct{
Program
platform string
port string
}
func (app *Application) showProgramInfo(){
fmt.Println("this is a app ...")
}
func (app *Application) writeLog(){
fmt.Println("golang app write log ...")
}
app := Application{
Program{"golang",1.13},
"linux",
"8080"
}
app.showProgramInfo()
app.setVer()
app.writeLog()
在声明 Application struct 时,使用 Program
作为匿名变量,相当于 Application 继承自 Program,Application 继承了 Program 的成员变量和成员方法,可以重写继承的方法,也可以新增成员方法。
多态
package main
import "fmt"
type Languge interface{
sayHello(program string)
}
type Golang struct{
}
type PHP struct{
}
func(golang Golang) sayHello(program string) {
fmt.Printf("say hello %s\n",program)
}
func(php PHP) sayHello(program string) {
fmt.Printf("say hello %s\n",program)
}
func main() {
var golang Languge
var php Languge
golang = Golang {}
php = PHP {}
golang.sayHello("golang")
php.sayHello("php")
}
作为对比,可以这样写
package main
import (
"fmt"
)
type Languge interface{
sayHello()
}
type Golang struct{
}
type PHP struct{
}
func(golang Golang) sayHello() {
fmt.Println("say hello golang")
}
func(php PHP) sayHello() {
fmt.Println("say hello php")
}
func langugeSayHello(languge Languge){
languge.sayHello()
}
func main(){
var languge Languge
languge = Golang {}
langugeSayHello(languge)
//say hello golang
languge = PHP {}
langugeSayHello(languge)
//say hello php
}
可以看到,不同的结构体实现了同一个接口,调用时会根据具体的结构体对象,调用了不同的具体实现方法。