Go
객체 지향 프로그래밍
수색…
비고
때문에 인터페이스 포인터 수신기로 구현 될 수없는 *User
없는 User
구조물
Go는 구조체 및 형식 별칭 형식으로 사용자 정의 형식을 지원합니다. struct는 복합 유형이고, struct 유형을 구성하는 구성 요소는 필드 라고 합니다 . 필드는 유형이어야하며 이름은 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
}
행동 양식
이동 중에는 메소드가 있습니다.
수신자라고 불리는 특정 유형의 변수에 작용하는 함수
수신기는 아무것도 아니라 될 수 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에 변수가 포함될 수 있습니다.
다형성 (Polymorphism)은 객체 지향 프로그래밍의 본질입니다. 동일한 인터페이스를 준수하는 한 다른 유형의 객체를 균일하게 처리 할 수있는 기능입니다. 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)
}