package main
import "fmt"
type Account struct {
number string
balance float64
interest float64
}
func NewAccount(number string, balance float64, interest float64) *Account { //포인터 반환 아닌 경우 값 복사로 사용
return &Account{number, balance, interest} // 구조체 인스턴스를 생성한 뒤 포인터를 리턴
}
func main() {
//구조체 생성자 패턴 예제
//예제1
kim := Account{number: "245-901", balance: 10000000, interest: 0.015}
var lee *Account = new(Account) //new 함수로 초기화와 동시에 구제체 필드 값 할당은 불가능
lee.number = "245-902"
lee.balance = 13000000
lee.interest = 0.025
fmt.Println("ex1 : ", kim)
fmt.Println("ex1 : ", lee)
//예제2
park := NewAccount("245-903", 17000000, 0.04)
fmt.Println("ex2 : ", park)
}
package main
import "fmt"
type Account struct {
number string
balance float64
interest float64
}
func CalculateD(a Account) { //값 복사 전달
a.balance = a.balance + (a.balance * a.interest)
}
func CalculateF(a *Account) { //주소(참조) 전달
a.balance = a.balance + (a.balance * a.interest)
}
func main() {
//구조체 생성자 패턴 예제
//예제1
kim := Account{number: "245-901", balance: 10000000, interest: 0.015}
lee := Account{number: "245-902", balance: 12000000, interest: 0.045}
fmt.Println("ex1 : ", kim)
fmt.Println("ex1 : ", lee)
fmt.Println()
CalculateD(kim)
CalculateF(&lee) //CalculateF(lee) 호출 시 예외 발생
fmt.Println("ex1 : ", int(kim.balance))
fmt.Println("ex1 : ", int(lee.balance))
}
//구조체 심화(3)
package main
import "fmt"
type Account struct {
number string
balance float64
interest float64
}
//리시버 변수 사용안할 경우 func(_ Account) -> 밑줄로 생략 가능
func (a Account) CalculateD(bonus float64) { //값 복사 전달
a.balance = a.balance + (a.balance * a.interest) + bonus
}
func (a *Account) CalculateF(bonus float64) { //주소(참조) 전달
a.balance = a.balance + (a.balance * a.interest) + bonus
}
func main() {
//구조체 생성자 패턴 예제
//정리 : 구조체 인스턴스 값 변경 시 -> 포인터 전달 , 보통의 경우 -> 값 전달
//예제1
kim := Account{number: "245-901", balance: 10000000, interest: 0.015}
lee := Account{number: "245-902", balance: 12000000, interest: 0.045}
fmt.Println("ex1 : ", kim)
fmt.Println("ex1 : ", lee)
fmt.Println()
lee.CalculateD(1000000)
kim.CalculateF(1000000)
fmt.Println("ex1 : ", int(lee.balance))
fmt.Println("ex1 : ", int(kim.balance))
}
package main
import "fmt"
type Employee struct {
name string
salary float64
bonus float64
}
func (e Employee) Calculate() float64 {
return e.salary + e.bonus
}
type Executives struct {
Employee
specialBonus float64
}
func main() {
//구조체 임베디드 패턴
//다른 관점으로 메소드를 재 사용하는 장점 제공
//상속을 허용하지 않는 Go 언어에서 메소드 상속 활용을 위한 패턴
//예제1
//직원
ep1 := Employee{"kim", 2000000, 300000}
ep2 := Employee{"park", 1500000, 200000}
//임원
ex := Executives{
Employee{"lee", 4000000, 1000000},
1000000,
}
fmt.Println("ex1 : ", int(ep1.Calculate()))
fmt.Println("ex1 : ", int(ep2.Calculate()))
//Employee 구조체 통해서 메소드 호출(임베디드)
fmt.Println("ex1 : ", int(ex.Calculate()+ex.specialBonus))
}
package main
import "fmt"
type Employee struct {
name string
salary float64
bonus float64
}
func (e Employee) Calculate() float64 {
return e.salary + e.bonus
}
//이름이 같은 함수 사용 : 오버라이딩
func (e Executives) Calculate() float64 {
return e.Employee.salary + e.Employee.bonus + e.specialBonus
}
type Executives struct {
Employee
specialBonus float64
}
func main() {
//구조체 임베디드 메소드 오버라이딩 패턴
//
//예제1
//직원
ep1 := Employee{"kim", 2000000, 300000}
ep2 := Employee{"park", 1500000, 200000}
//임원
ex := Executives{
Employee{"lee", 4000000, 1000000},
1000000,
}
fmt.Println("ex1 : ", int(ep1.Calculate()))
fmt.Println("ex1 : ", int(ep2.Calculate()))
fmt.Println("ex1 : ", int(ex.Calculate()+ex.specialBonus)) //오버라이딩 : 잘못 된 값 반환
fmt.Println("ex1 : ", int(ex.Calculate())) //오버라이딩 : 정확한 값
fmt.Println("ex1 : ", int(ex.Employee.Calculate()+ex.specialBonus))
}