Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- window
- range
- Sync
- http
- json
- 리뷰
- install
- windows
- mutex
- write
- tcp
- API
- c++
- package
- Golang
- FOR
- JavaScript
- File
- Linux
- go
- Close
- Callback
- GO 언어
- C
- go언어
- bitcoin
- 책
- 영화
- channel
- Python
Archives
- Today
- Total
Code Habit
Go ) 구조체 임베딩 (상속) 본문
Go언어는 클래스를 제공하지 않으므로 상속 또한 제공하지 않는다. 하지만 구조체에서 임베딩(Embedding)을 사용하면 상속과 같은 효과를 낼 수 있다.
먼저 간단하게 Has-a 관계를 정의해 보겠다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
type Person struct { // 사람 구조체 정의
name string
age int
}
func(p *Person) greeting() { // greeting 함수 Person구조체에 연결
fmt.Println("Hello")
}
type Student struct {
p Person // 학생 구조체 안에 사람 구조체를 필드로 가지고 있음( Has - a )
school string
grade int
}
func main() {
var s Student
s.p.greeting() // Hello
}
|
이번에는 Student 구조체에 Person 구조체를 임베딩해보겠다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
type Person struct { // 사람 구조체 정의
name string
age int
}
func(p *Person) greeting { // greeting 함수 Person구조체에 연결
func.Println("Hello")
}
type Student struct {
Person // 임베딩( Is-a )
school string
grade int
}
func main() {
var s Student
s.Person.greeting() // Hello
s.greeting() // Hello
}
|
Student 구조체에서 Person 필드를 정의할 때 필드명은 사용하지 않고, 구조체 타입만 지정했다. 이렇게 되면 구조체가 해당 타입을 포함하는 (Is-a)관계가 된다. 따라서 greeting 함수를 호출할 때 s.Person.greeting() 처럼 Person 구조체 타입을 통해서 호출하거나 s.greeting() 처럼 바로 호출할 수 있다.
물론 구조체 안에 여러개의 구조체를 임베딩하면 다중 상속도 구현할 수 있다.
※ 구조체 임베딩을 할 때 필드명을 사용하지 않는 필드를 익명 필드(anonymous field)라고 한다.
다음과 같이 Student 구조체도 Person 구조체와 같은 이름의 greeting 메서드를 가지고 있다면 이때는 Student 구조체의 greeting 함수가 오버라이드 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
type Person struct { // 사람 구조체 정의
name string
age int
}
func(p *Person) greeting() { // greeting 함수 Person구조체에 연결
fmt.Println("Hello")
}
type Student struct {
Person // 임베딩( Is-a )
school string
grade int
}
func (p *Student) greeting() { // 이름이 같은 메서드를 정의하면 오버라이딩 됨
fmt.Println("Hello Students~")
}
func main() {
var s Student
s.Person.greeting() // Hello
s.greeting() // Hello Students~
}
|
부모 구조체의 메서드 이름과 중복된다면 상속 과정의 맨 아래 메서드가 호출된다. 즉 자식 구조체의 메서드가 부모 구조체의 메서드를 오버라이드 하게 된다. 부모 구조체의 메서드를 호출하고 싶으면 s.Person.greeting()과 같은 형태로 구조체 타입을 지정하여 호출한다.