package main
// Test for a practical usage of interface
// different type use same method to implement inherit
import (
"fmt"
)
type SalaryCalculator interface {
CalculateSalary() int
}
type Permanent struct {
empId string
basicpay int
pf int
}
type Contract struct {
empId string
basicpay int
}
//salary of permanent employee is sum of basic pay and pf
func (p Permanent) CalculateSalary() int {
return p.basicpay + p.pf
}
// salary of contract is basic pay
func (c Contract) CalculateSalary() int {
return c.basicpay
}
// calculate total employees' salary
func TotalSalary(emps []SalaryCalculator) int{
expense := 0
for _, v := range emps {
expense += v.CalculateSalary()
}
return expense
}
func main() {
p1 := Permanent {
empId : "Td011",
basicpay: 12000,
pf: 2000,
}
c1 := Contract {
empId: "Ts110",
basicpay: 5000,
}
c2 := Contract {
empId: "Ts111",
basicpay: 6000,
}
var emps []SalaryCalculator = []SalaryCalculator{p1, c1, c2}
expense := TotalSalary(emps)
fmt.Println("All the employees")
fmt.Println(emps)
fmt.Println("Total salary:", expense)
}
package main
import (
"fmt"
"reflect"
)
type Tester interface {
Test()
}
type double float64
func (i double) Test() {
fmt.Printf("Interface type:%T %s, value %v\n", i, reflect.TypeOf(i), i)
}
func main() {
i := double(12.90)
var t Tester
fmt.Printf("Tester: %T %v\n", t, t)
t = i
t.Test()
}
//
func describe(i interface{}) {
fmt.Printf("Type = %T, value = %v\n", i, i)
}
// use empty interface to assert int type
func assert(i interface{}) {
v, ok := i.(int)
if ok {
fmt.Println(v, reflect.TypeOf(v))
} else {
panic("The type is not int!")
}
}
// type switch
func findType(i interface{}) {
// 如果需要调用Tester接口的方法,必须进行显式的类型转换,也就是获取Tester
// 类型的值
switch v := i.(type) {
case string:
fmt.Println("It is a string")
case int:
fmt.Println("It is an int")
case Tester:
v.Test()
default:
fmt.Println("Unknown")
}
}
/* Pointer receiver and value receiver*/
type Person struct {
name string
age int
}
type Address struct {
city, state string
}
func (p Person) Test() {
fmt.Println("Value receiver person", p.name, "age:", p.age)
}
func (a *Address) Test() {
fmt.Println("Pointer recevier address:", a.city, a.state)
}
fmt.Println("\nTest for value reciver and pointer receiver")
var d1 Tester
p1 := Person {"Jack", 35}
p2 := Person {"Jordan", 66}
d1 = p1
d1.Test()
d1 = &p2
d1.Test()
a1 := Address {"LosAngle", "California"}
d1 = &a1
d1.Test()
// d1 = a1 // 不可以使用该赋值,因为实现了该接口的是指针类型
a1.Test() // 对于方法而言,不管接收器类型是指针还是值都可以
// 使用任何一种形式调用,编译器会自动进行编译
(&a1).Test()
/*Test for value reciver and pointer receiver
Value receiver person Jack age: 35
Value receiver person Jordan age: 66
Pointer recevier address: LosAngle California
Pointer recevier address: LosAngle California
Pointer recevier address: LosAngle California
*/
package main
// Test for a practical usage of interface
// different type use same method to implement inherit
import (
"fmt"
)
type SalaryCalculator interface {
CalculateSalary() int
Display()
}
type SalaryChanger interface {
IncreaseBaisc(ins int)
DescreaseBasic(des int)
}
// 实现了多个接口,为了可以调用所有接口中的方法,需要定义一个总的接口
type SalaryOptions interface {
SalaryCalculator
SalaryChanger
}
type Permanent struct {
empId string
basicpay int
pf int
}
type Contract struct {
empId string
basicpay int
}
//salary of permanent employee is sum of basic pay and pf
func (p Permanent) CalculateSalary() int {
return p.basicpay + p.pf
}
func (p Permanent) Display() {
fmt.Printf("Permanent:%s salary:%d\n", p.empId, p.basicpay + p.pf)
}
func (p *Permanent) IncreaseBaisc(ins int) {
fmt.Printf("Now increase %s salry %d\n", p.empId, ins)
p.basicpay += ins
}
func (p *Permanent) DescreaseBasic(des int) {
fmt.Printf("Now descrease %s salry %d\n", p.empId, des)
p.basicpay -= des
}
// salary of contract is basic pay
func (c Contract) CalculateSalary() int {
return c.basicpay
}
func (c Contract) Display() {
fmt.Println("Contract:%s salary:%d\n", c.empId, c.basicpay)
}
func (c *Contract) IncreaseBaisc(ins int) {
fmt.Printf("Now increase %s salry %d\n", c.empId, ins)
c.basicpay += ins
}
func (c *Contract) DescreaseBasic(des int) {
fmt.Printf("Now descrease %s salry %d\n", c.empId, des)
c.basicpay -= des
}
// calculate total employees' salary
func TotalSalary(emps []SalaryCalculator) int{
expense := 0
for _, v := range emps {
expense += v.CalculateSalary()
}
return expense
}
func main() {
p1 := Permanent {
empId : "Td011",
basicpay: 12000,
pf: 2000,
}
c1 := Contract {
empId: "Ts110",
basicpay: 5000,
}
c2 := Contract {
empId: "Ts111",
basicpay: 6000,
}
var emps []SalaryCalculator = []SalaryCalculator{p1, c1, c2}
expense := TotalSalary(emps)
fmt.Println("All the employees")
fmt.Println(emps)
fmt.Println("Total salary:", expense)
var emp SalaryOptions = &p1 // 此处必须使用地址进行赋值
// 因为需要更改对于调用者可见,所以method只可以使用指针接收器
// 而实现该接口时使用指针接收器,所以实现该接口的是指针类型
// 只有指针类型才可以进行赋值,然后再调用其他操作
emp.DescreaseBasic(100)
emp.Display() // 接收器为value,可以使用指针类型的接口进行调用,编译器自动解引用
emp.IncreaseBaisc(1000)
emp.Display()
}
All the employees
[{Td011 12000 2000} {Ts110 5000} {Ts111 6000}]
Total salary: 25000
Now descrease Td011 salry 100
Permanent:Td011 salary:13900
Now increase Td011 salry 1000
Permanent:Td011 salary:14900