Go語言中的面向對象編程(OOP)
在Go語言中,雖然沒有像面向對象語言那樣的類,但通過結構體類型和方法,仍然支持部分面向對象編程(OOP)的概念。
封裝(Encapsulation)
封裝是一種將一個對象的實現細節隱藏起來,使其對其他對象不可見的做法,這樣可以實現解耦。
例如,考慮以下結構體:
type Student struct{
name string
rollNo uint64
}
其中的name和rollNo字段是私有的,因為它們以小寫字母開頭。為了提供公共訪問,可以為這些字段定義對應的getter和setter方法。
func (s *Student) GetName() string {
return s.name
}
func (s *Student) SetName(name string) {
s.name = name
}
func (s *Student) GetRollNo() uint64 {
return s.rollNo
}
func (s *Student) SetRollNo(roll uint64) {
s.rollNo = roll
}
現在,程序的其他部分也可以創建Student結構體的對象,并通過公共的getter和setter方法訪問name和rollNo,從而實現了封裝。
抽象(Abstraction)
數據抽象是一種設計模式,其中數據僅對語義相關的函數可見,以防止誤用。數據抽象的成功導致在面向對象和純函數式編程中頻繁地將數據隱藏作為設計原則。
在Go語言中,可以通過接口實現抽象。接口定義了一組必須實現的方法,以滿足接口的要求。
例如,考慮以下接口:
type iStudent interface{
calcPercentage() float64
}
該接口定義了一個名為calcPercentage()的方法,用于計算學生的百分比。
繼承(Inheritance)
在Go語言中,不支持傳統意義上的繼承。相反,Go使用組合來實現類似的功能。一個結構體可以嵌入另一個結構體,從而繼承其字段和方法。
例如,考慮以下結構體:
type Person struct {
name string
age uint64
}
type Student struct {
Person
studentID uint64
}
在這里,Student結構體嵌入了Person結構體,這意味著它繼承了Person的name字段。Student結構體還有自己的studentID字段。現在,任何對Person操作的方法也可以對Student操作,因為Student是一個帶有額外字段的Person。
多態(Polymorphism)
多態是指調用代碼可以獨立于所支持層次結構中的類(父類或其子類)而運行的情況。
在Go語言中,可以通過使用接口來實現多態。由于Go是一種靜態類型的語言,變量的類型必須在編譯時已知。然而,通過使用接口,可以編寫可以在滿足相同接口要求的不同類型上操作的代碼,而無需在編譯時知道其具體類型。
例如,考慮以下代碼:
func PrintStudentDetails(s *Student) {
fmt.Println("Student Name:", s.GetName())
fmt.Println("Student Age:", s.GetAge())
fmt.Println("Percentage",s.CalcPercentage())
}
現在,我們可以將任何實現了PrintStudentDetails()方法的類型作為參數調用該函數,比如Student類型,它會顯示該學生的詳細信息。這就是多態的實現。
完整的面向對象編程在Go中的示例:
package main
import "fmt"
type Shape interface {
Area() float64
}
type Triangle struct {
Base, Height float64
}
func (t Triangle) Area() float64 {
return 0.5 * t.Base * t.Height
}
type Square struct {
Side float64
}
func (s Square) Area() float64 {
return s.Side * s.Side
}
type Rectangle struct {
Length, Breadth float64
}
func (r Rectangle) Area() float64 {
return r.Length * r.Breadth
}
func printArea(s Shape) {
fmt.Println("Area of shape is : ", s.Area())
}
func main() {
t := Triangle{Base: 10, Height: 20}
printArea(t) //Area of shape is : 100
s := Square{Side: 20}
printArea(s) //Area of shape is : 400
r := Rectangle{Length: 20, Breadth: 10}
printArea(r) //Area of shape is : 200
}