Go 기초 11. OOP, Interface
Object Oriented Programming
객체 지향 중심 프로그래밍
OOP는 추상적인 개념이 아닌 프로그래밍을 잘 하기 위한 기술이다.
OOP이전의 프로그래밍은 순서를 중요시 하는 절차 지향 프로그래밍이다.
ex) strawberry sandwitch
package main
import "fmt"
type Bread struct {
val string
}
type StrawberryJam struct {
opened bool
}
type SpoonOfStrawberry struct {
}
type Sandwitch struct {
val string
}
func GetBreads(num int) []*Bread {
breads := make([]*Bread, num)
for i := 0; i < num; i++ {
breads[i] = &Bread{val: "bread"}
}
return breads
}
func OpenStrawberryJam(jam *StrawberryJam) {
jam.opened = true
}
func GetOneSpoon(_ *StrawberryJam) *SpoonOfStrawberry {
return &SpoonOfStrawberry{}
}
func PutJamOnBread(bread *Bread, jam *SpoonOfStrawberry) {
bread.val += " + Strawberry Jam"
}
func MakeSandwitch(breads []*Bread) *Sandwitch {
sandwitch := &Sandwitch{}
for i := 0; i < len(breads); i++ {
sandwitch.val += breads[i].val + " + "
}
return sandwitch
}
func main() {
// 1. 빵 두개를 꺼낸다.
breads := GetBreads(2)
jam := &StrawberryJam{}
// 2. 딸기잼 뚜껑을 연다.
OpenStrawberryJam(jam)
// 3. 딸기잼을 한스푼 뜬다.
spoon := GetOneSpoon(jam)
// 4. 딸기잼을 빵에 바른다.
PutJamOnBread(breads[0], spoon)
// 5. 빵을 덮는다.
sandwitch := MakeSandwitch(breads)
// 6. 완성
fmt.Println(sandwitch.val)
}
-----------------------------------
bread + Strawberry Jam + bread +
이상태에서 딸기잼이 아닌 오렌지잼으로 바꾸다고 했을때.
ex) orangejam sandwitch
package main
import "fmt"
type Bread struct {
val string
}
type StrawberryJam struct {
opened bool
}
type SpoonOfStrawberry struct {
}
type SpoonOfOrangeJam struct {
} //새로운 구조체 추가
type Sandwitch struct {
val string
}
type OrangeJam struct {
opened bool
} // 오렌지 잼 추가
func GetBreads(num int) []*Bread {
breads := make([]*Bread, num)
for i := 0; i < num; i++ {
breads[i] = &Bread{val: "bread"}
}
return breads
}
func OpenStrawberryJam(jam *StrawberryJam) {
jam.opened = true
}
func OpenOrangeJam(jam *OrangeJam) {
jam.opened = true
} //오렌지 잼을 추가 했기 때문에 새로운 함수 추가
func GetOneSpoon(_ *StrawberryJam) *SpoonOfStrawberry {
return &SpoonOfStrawberry{}
}
func GetOneOrangeJamSpoon(_ *OrangeJam) *SpoonOfOrangeJam {
return &SpoonOfOrangeJam{}
} //새로운 함수 추가
func PutJamOnBread(bread *Bread, jam *SpoonOfStrawberry) {
bread.val += " + Strawberry Jam"
}
func PutOrangeJamOnBread(bread *Bread, jam *SpoonOfOrangeJam) {
bread.val += " + Orange Jam"
} //새로운 함수 추가
func MakeSandwitch(breads []*Bread) *Sandwitch {
sandwitch := &Sandwitch{}
for i := 0; i < len(breads); i++ {
sandwitch.val += breads[i].val + " + "
}
return sandwitch
}
func main() {
// 1. 빵 두개를 꺼낸다.
breads := GetBreads(2)
//jam := &StrawberryJam{}
jam := &OrangeJam{}
// 2. 오렌지잼 뚜껑을 연다.
//OpenStrawberryJam(jam)
OpenOrangeJam(jam)
// 3. 오렌지잼을 한스푼 뜬다.
//spoon := GetOneSpoon(jam)
spoon := GetOneOrangeJamSpoon(jam)
// 4. 오렌지잼을 빵에 바른다.
//PutJamOnBread(breads[0], spoon)
PutOrangeJamOnBread(breads[0], spoon)
// 5. 빵을 덮는다.
sandwitch := MakeSandwitch(breads)
// 6. 완성
fmt.Println(sandwitch.val)
}
------------------------------------
bread + Orange Jam + bread +
딸기잼을 오렌지잼으로 바꾸었을 뿐인데 8군데가 수정 된것을 알 수 있다.
이것이 현업에서는 수정할때 그 범위가 엄청나게 커서 유지, 보수가 힘들다.
이런것들을 해결하기 위해 OOP라는 기술이 나왔다.
하지만 OOP가 절대적인 해결책은 아니므로 프로그램을 잘 짜는게 제일 중요하다.
object란?
상태 + 기능
상태 = 메모리 상태
기능 = 어떻게
상태를 어떻게 바꿀 것인가?
variable + function = object
package main
import "fmt"
type Bread struct {
val string
}
type Jam struct {
}
func (b *Bread) PutJam(jam *Jam) {
b.val += jam.GetVal()
} // bread의 매소드로 bread에 jam을 바름
func (b *Bread) String() string {
return b.val
} // 만약 string이 있을 경우
func (j *Jam) GetVal() string {
return "+ jam"
} // jam의 매소드로 잼을 바름
func main() {
bread := &Bread{val: "bread"}
jam := &Jam{}
//bread 인스턴스와 jam의 인스턴스를 만든다.
bread.PutJam(jam)
//bread 인스턴스에 속해있는 PutJam을 호출
fmt.Println(bread)
}
--------------------------------------
bread+ jam
위의 프로그램의 객체를 잼, 빵 이라고 한다면
이 잼과 빵이 각자 기능을 가지고 오브젝트를 형성하고 각 각의 오브젝트간에 커뮤니케이션하는 관계를 성립함으로써 프로그램을 완성시킨다.
Interface
객체간의 상호 관계를 정의한 것
객체(object)는 기능(method)를 가지는데 이 기능에는 내부 기능과 외부 기능이 있다. 내부 기능은 내부에서만 호출이 되고, 외부 기능은 외부에서 호출 되어진다. 이 때 외부와 서로 관계를 맺고있는 외부 기능을 interface라고 한다.
interface는 객체와 관계를 유지한 상태로 때어내서 종속성을 끊어내고 독립 시키게 되면 확장을 하는데 용이하다.
interface 선언 방법
type 인터페이스명 interface {
메소드명 타입
메소드명 타입
}
ex)
package main
import (
"fmt"
"strconv"
)
type InterfaceA interface {
AAA(int) int
BBB(int) string
}
type StructA struct {
}
func (a *StructA) AAA(x int) int {
return x * x
}
func (a *StructA) BBB(x int) string {
return "X=" + strconv.Itoa(x)
}
func main() {
var c InterfaceA //inteface 타입 c
c = &StructA{}
// c가 StructA의 주소값을 가짐
// StructA는 AAA와 BBB의 메소드를 가지고 있음
fmt.Println(c.BBB(3))
}
-------------------------------------
X=3
Author And Source
이 문제에 관하여(Go 기초 11. OOP, Interface), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jinzza456/Go-기초-11.-OOP저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)