Menu
CoddyTech

Giới thiệu về interface

Thuộc phần Lập trình hướng đối tượng trong hành trình GO của Coddy. Bài học 25 trên 107.

Interface trong Go định nghĩa một tập hợp các chữ ký phương thức mà không triển khai chúng. Nó mô tả kiểu dữ liệu có thể làm gì, chứ không phải cách kiểu đó thực hiện. Bất kỳ kiểu dữ liệu nào triển khai tất cả phương thức trong một interface đều tự động đáp ứng interface đó.

Đây là cách bạn định nghĩa một giao diện:

type Speaker interface {
    Speak() string
}

Giao diện Speaker này yêu cầu mọi kiểu triển khai giao diện phải có phương thức Speak() trả về một chuỗi. Giờ đây, bạn có thể dùng bất kỳ struct nào có phương thức này ở nơi cần một Speaker.

type Dog struct {
    Name string
}

func (d Dog) Speak() string {
    return d.Name + " says woof!"
}

type Cat struct {
    Name string
}

func (c Cat) Speak() string {
    return c.Name + " says meow!"
}

Cả Dog và Cat đều đáp ứng giao diện Speaker vì chúng đều có phương thức Speak() với chữ ký chính xác. Giờ đây, bạn có thể viết các hàm chấp nhận mọi Speaker:

func MakeSound(s Speaker) {
    fmt.Println(s.Speak())
}

func main() {
    dog := Dog{Name: "Buddy"}
    cat := Cat{Name: "Whiskers"}
    
    MakeSound(dog)  // Buddy kêu gâu gâu!
    MakeSound(cat)  // Whiskers kêu meo meo!
}

Giao diện cho phép bạn viết code linh hoạt, có thể tái sử dụng và hoạt động với mọi kiểu đáp ứng các yêu cầu của giao diện, bất kể cách triển khai bên dưới.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống mô tả phương tiện để minh họa cách giao diện cho phép các kiểu dữ liệu khác nhau có chung hành vi. Bạn sẽ tạo một giao diện mà nhiều kiểu phương tiện có thể đáp ứng, sau đó dùng giao diện này để mô tả mọi phương tiện theo cùng một cách.

Bạn sẽ sắp xếp code trong hai tệp:

  • vehicles.go: Định nghĩa giao diện Describer với một phương thức duy nhất là Describe() string. Sau đó, tạo hai cấu trúc đáp ứng giao diện này:
    • Car có các trường Brand và Model (cả hai đều là chuỗi)
    • Bicycle có các trường Type (chuỗi) và Gears (số nguyên)
    Mỗi cấu trúc cần có một phương thức Describe() trả về chuỗi mô tả phương tiện.
  • main.go: Tạo hàm có tên PrintDescription, nhận vào bất kỳ giá trị nào đáp ứng giao diện Describer và in ra kết quả gọi phương thức Describe() của giá trị đó. Đọc thông tin phương tiện từ đầu vào, tạo cả một chiếc xe hơi và một chiếc xe đạp, rồi dùng hàm của bạn để in ra phần mô tả cho từng phương tiện.

Đầu vào sẽ gồm:

  • Dòng 1: Hãng xe hơi
  • Dòng 2: Mẫu xe hơi
  • Dòng 3: Loại xe đạp
  • Dòng 4: Số bánh răng (số nguyên)

Các phương thức Describe() cần trả về chuỗi theo những định dạng sau:

  • Xe hơi: [Brand] [Model]
  • Xe đạp: [Type] bike with [Gears] gears

Ví dụ, với đầu vào Toyota, Camry, Mountain và 21, đầu ra sẽ là:

Toyota Camry
Mountain bike with 21 gears

Điểm mấu chốt là hàm PrintDescription hoạt động với mọi kiểu dữ liệu có phương thức Describe(). Hàm này không cần biết nó đang xử lý một chiếc xe hơi, xe đạp hay bất kỳ loại phương tiện nào khác mà bạn có thể bổ sung sau này.

Tự làm thử

package main

import (
	"fmt"
)

// TODO: Tạo hàm (function) PrintDescription nhận bất kỳ Describer nào
// và in ra kết quả khi gọi phương thức (method) Describe() của nó

func main() {
	// Đọc đầu vào
	var carBrand string
	var carModel string
	var bicycleType string
	var gears int

	fmt.Scanln(&carBrand)
	fmt.Scanln(&carModel)
	fmt.Scanln(&bicycleType)
	fmt.Scanln(&gears)

	// TODO: Tạo Car với thương hiệu và mẫu xe từ đầu vào

	// TODO: Tạo Bicycle với loại xe và số bánh răng từ đầu vào

	// TODO: Dùng PrintDescription để in ra mô tả của ô tô

	// TODO: Dùng PrintDescription để in ra mô tả của xe đạp
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Go online