Go
Объектно-ориентированное программирование
Поиск…
замечания
Интерфейс не может быть реализован с помощью приемников указателей, потому что *User
не является User
Структуры
Go поддерживает определенные пользователем типы в виде структур и псевдонимов типов. structs являются составными типами, компоненты частей данных, которые составляют тип структуры, называются полями . поле имеет тип и имя, которое должно быть unqiue.
package main
type User struct {
ID uint64
FullName string
Email string
}
func main() {
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
}
fmt.Println(user) // {1 Zelalem Mekonen [email protected]}
}
это также юридический синтаксис для определения структур
type User struct {
ID uint64
FullName, Email string
}
user := new(User)
user.ID = 1
user.FullName = "Zelalem Mekonen"
user.Email = "[email protected]"
Встроенные структуры
потому что структура также является типом данных, она может использоваться как анонимное поле, внешняя структура может напрямую обращаться к полям встроенной структуры, даже если структура получена из разного пакета. это поведение обеспечивает способ получения некоторой или всей вашей реализации из другого типа или набора типов.
package main
type Admin struct {
Username, Password string
}
type User struct {
ID uint64
FullName, Email string
Admin // embedded struct
}
func main() {
admin := Admin{
"zola",
"supersecretpassword",
}
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
admin,
}
fmt.Println(admin) // {zola supersecretpassword}
fmt.Println(user) // {1 Zelalem Mekonen [email protected] {zola supersecretpassword}}
fmt.Println(user.Username) // zola
fmt.Println(user.Password) // supersecretpassword
}
методы
В методе Go метод
функция, действующая на переменную определенного типа, называемую приемником
приемник может быть чем угодно, не только structs
но даже function
, типы псевдонимов для встроенных типов, такие как int
, string
, bool
могут иметь метод, исключение из этого правила заключается в том, что interfaces
(обсужденные позже) не могут иметь методы, интерфейс - это абстрактное определение, а метод - реализация, которая пытается сгенерировать ошибку компиляции.
комбинируя structs
и methods
вы можете получить близкий эквивалент class
в объектно-ориентированном программировании.
метод в Go имеет следующую подпись
func (name receiverType) methodName(paramterList) (returnList) {}
package main
type Admin struct {
Username, Password string
}
func (admin Admin) Delete() {
fmt.Println("Admin Deleted")
}
type User struct {
ID uint64
FullName, Email string
Admin
}
func (user User) SendEmail(email string) {
fmt.Printf("Email sent to: %s\n", user.Email)
}
func main() {
admin := Admin{
"zola",
"supersecretpassword",
}
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
admin,
}
user.SendEmail("Hello") // Email sent to: [email protected]
admin.Delete() // Admin Deleted
}
Указатель Vs Приемник значения
приемник метода обычно является указателем на производительность, потому что мы не будем копировать экземпляр, как это было бы в случае приемника значений, это особенно верно, если тип приемника является структурой. причина анотера, чтобы сделать тип приемника указателем, чтобы мы могли изменить данные, на которые указывает приемник.
приемник значений используется, чтобы избежать изменения данных, содержащихся в приемнике, приемник ваулей может привести к потере производительности, если приемник является большой структурой.
package main
type User struct {
ID uint64
FullName, Email string
}
// We do no require any special syntax to access field because receiver is a pointer
func (user *User) SendEmail(email string) {
fmt.Printf("Sent email to: %s\n", user.Email)
}
// ChangeMail will modify the users email because the receiver type is a ponter
func (user *User) ChangeEmail(email string) {
user.Email = email;
}
func main() {
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
}
user.SendEmail("Hello") // Sent email to: [email protected]
user.ChangeEmail("[email protected]")
fmt.Println(user.Email) // [email protected]
}
Интерфейс и полиморфизм
Интерфейсы обеспечивают способ указания поведения объекта, если что-то может это сделать, тогда он может быть использован здесь. интерфейс определяет набор методов, но эти методы не содержат кода, поскольку они являются абстрактными или имплементация предоставляется пользователю интерфейса. в отличие от большинства интерфейсов с объектно-ориентированными языками могут содержать переменные в Go.
Полиморфизм - это суть объектно-ориентированного программирования: способность равномерно обрабатывать объекты разных типов, если они придерживаются одного и того же интерфейса. Интерфейсы Go обеспечивают эту возможность очень простым и интуитивно понятным способом
package main
type Runner interface {
Run()
}
type Admin struct {
Username, Password string
}
func (admin Admin) Run() {
fmt.Println("Admin ==> Run()");
}
type User struct {
ID uint64
FullName, Email string
}
func (user User) Run() {
fmt.Println("User ==> Run()")
}
// RunnerExample takes any type that fullfils the Runner interface
func RunnerExample(r Runner) {
r.Run()
}
func main() {
admin := Admin{
"zola",
"supersecretpassword",
}
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
}
RunnerExample(admin)
RunnerExample(user)
}