Go – Interface

Ngôn ngữ Go cung cấp một kiểu dữ liệu được gọi là Interface được sử dụng để diễn tả tập hợp các phương thức đăng ký. Kiểu dữ liệu Struct implement những phương thức này để giúp cho các phương thức đăng ký bên trong Interface được định nghĩa.

Ví dụ WashingMachine là một interface với các phương thức đăng ký Cleaning()Drying(). Bất cứ kiểu nào mà cung cấp các định nghĩa cho Cleaning()Drying() được hiểu là implement của WashingMachine interface.

Khai báo và thực thi một interface

Để implement một Interface, bạn chỉ cần implement tất cả các phương thức được khai báo trong Interface.

Không giống như các ngôn ngữ khác như là Java, chúng ta không cần chỉ định rõ ràng một kiểu implement cho một Interface sử dụng từ khoá kiểu như là implements.

Đây là 2 kiểu Struct implement cho Shape interface.

type Rectangle struct {
	Length, Width float64
}

func (r Rectangle) Area() float64 {
	return r.Length * r.Width
}

func (r Rectangle) Perimeter() float64 {
	return 2 * (r.Length + r.Width)
}
type Circle struct {
	Radius float64
}

func (c Circle) Area() float64 {
	return math.Pi * c.Radius * c.Radius
}

func (c Circle) Perimeter() float64 {
	return 2 * math.Pi * c.Radius
}

func (c Circle) Diameter() float64 {
	return 2 * c.Radius
}

Sử dụng một kiểu interface với các giá trị cụ thể

Bản thân một Interface là không hữu ích trừ khi chúng ta sử dụng chúng với một kiểu cụ thể implement toàn bộ phương thức của nó.

Chúng ta hãy cùng xem cách một Inteface có thể được sử dụng với giá trị cụ thể

1> Một kiểu Interface có thể nắm giữ bất kỳ giá trị nào implement tất cả phương thức của nó

package main

import (
    "fmt"
    "math"
)

func main() {
    var s Shape = Circle{5.0}
    fmt.Printf("Shape Type = %T, Shape Value = %v\n", s, s)
    fmt.Printf("Area = %f, Perimeter = %f\n\n", s.Area(), s.Perimeter())

    var s1 Shape = Rectangle{4.0, 6.0}
    fmt.Printf("Shape Type = %T, Shape Value = %v\n", s1, s1)
    fmt.Printf("Area = %f, Perimeter = %f\n", s1.Area(), s1.Perimeter())
}

Kết quả

Shape Type = main.Circle, Shape Value = {5}
Area = 78.539816, Perimeter = 31.415927

Shape Type = main.Rectangle, Shape Value = {4 6}
Area = 24.000000, Perimeter = 20.000000

2> Sử dụng kiểu Interface như tham số truyền vào của hàm

import (
    "fmt"
)

// Hàm chung để tính toán tổng area của các kiểu khác nhau của shapes 
func CalculateTotalArea(shapes ...Shape) float64 {
    totalArea := 0.0
    for _, s := range shapes {
        totalArea += s.Area()
    }
    return totalArea
}

func main() {
    totalArea := CalculateTotalArea(Circle{2}, Rectangle{4, 5}, Circle{10})
    fmt.Println("Total area = ", totalArea)
}

Kết quả

Total area =  346.7256359733385

3> Sử dụng kiểu interface như một trường

package main

import (
    "fmt"
)

// Kiểu Interface có thể được sử dụng như một trường
type MyDrawing struct {
    shapes  []Shape
    bgColor string
    fgColor string
}

func (drawing MyDrawing) Area() float64 {
    totalArea := 0.0
    for _, s := range drawing.shapes {
        totalArea += s.Area()
    }
    return totalArea        
}

func main() {
    drawing := MyDrawing{
        shapes: []Shape{
            Circle{2},
            Rectangle{3, 5},
            Rectangle{4, 7},
        },
        bgColor: "red",
        fgColor: "white",
    }

    fmt.Println("Drawing", drawing)
    fmt.Println("Drawing Area = ", drawing.Area())
}

Kết quả

Drawing {[{2} {3 5} {4 7}] red white}
Drawing Area = 55.56637061435917

Các giá trị Interface: Một kiểu Interface làm việc với các giá trị cụ thể như thế nào?

Một gía trị Interface có thể được hiểu như là một Tuple bao gồm một giá trị và một kiểu cụ thể

// interface
(value, type)

Hãy cùng xem ví dụ sau để hiểu hơn

package main

import (
	"fmt"
)

func main() {
	var s Shape

	s = Circle{5}
	fmt.Printf("(%v, %T)\n", s, s)
	fmt.Printf("Shape area = %v\n", s.Area())

	s = Rectangle{4, 7}
	fmt.Printf("(%v, %T)\n", s, s)
	fmt.Printf("Shape area = %v\n", s.Area())
}

Kết quả

({5}, main.Circle)
Shape area = 78.53981633974483
({4 7}, main.Rectangle)
Shape area = 28

Kiểm tra kết quả của chương trình bên trên và chú ý cách biến s chứa các thông tin về giá trị cũng như kiểu của Shape mà nó đang được gán.

 

You May Also Like

About the Author: Nguyen Dinh Thuc

Leave a Reply

Your email address will not be published.