Tính kế thừa

Chúng ta khai báo class Piano như sau:

// 1
class Piano: Instrument {
  let hasPedals: Bool
  // 2
  static let whiteKeys = 52
  static let blackKeys = 36
  
  // 3
  init(brand: String, hasPedals: Bool = false) {
    self.hasPedals = hasPedals
    // 4
    super.init(brand: brand)
  }
  
  // 5
  override func tune() -> String {
    return "Piano standard tuning for \(brand)."
  }
  
  override func play(_ music: Music) -> String {
    // 6 
    let preparedNotes = super.play(music)
    return "Piano playing \(preparedNotes)"
  }
}

Here’s what’s going on, step by step:

  1. Đầu tiên chúng ta khai báo class Piano là subclass của Instrument. Tất cả những stored property và các method của class cha là Instrument  đều được kế thừa và sử dụng bởi class  Piano .
  2. Mọi chiếc piano đều có số lượng phím trắng và phím đen giống nhau và bất biến bất kể chúng thuộc hãng nào. Do vậy chúng ta thêm từ khóa  static ở trước những property này.
  3. Hàm khởi tạo cung cấp giá trị mặc định cho tham số hasPedals và bạn có thể tùy chỉnh có thuộc tính này hay không.
  4. Sau đó chúng ta dùng từ khóa super để gọi hàm khởi tạo từ class cha sau khi thiết lập xong property hasPedals. Hàm khởi tạo ở class cha sẽ có nhiệm vụ khởi tạo property đã được kế thừa, ở đây là brand.
  5. Tiếp đến chúng ta override method tune() với từ khóa override. Method này sẽ được implement lại, không phải là gọi fatalError(), mà là những logic có liên quan đến class Piano.
  6. Cuối cùng chúng ta override method play(_:). Và bên trong method này, bạn sẽ sử dụng từ khóa  super để gọi đến method này ở trên class Instrument  để chuẩn bị các bài hát và chơi trên chiếc piano này.

Bởi vì Piano kế thừa từ Instrument, thế nên nó có thể có brand, có thể tùy chỉnh (tuned), chơi nhạc. Và đồng thời piano cũng có thể chơi nhạc theo nhiều cách khác nhau, do vậy chúng ta cần chỉnh sửa lại method play một chút.

Method Overloading

Chúng ta thêm method sau ngay dưới method  play(_:)

func play(_ music: Music, usingPedals: Bool) -> String {
  let preparedNotes = super.play(music)
  if hasPedals && usingPedals {
    return "Play piano notes \(preparedNotes) with pedals."
  }
  else {
    return "Play piano notes \(preparedNotes) without pedals."
  }
}

Ở đây chúng ta đã overloads method play(_:) để sử dụng pedals nếu giá trị property usingPedals là true, tức là chiếc đàn này thêm cả bàn pedal ở dưới. Chúng ta không sử dụng  override bởi vì method này có kiểu parameter. Chúng ta cần phải overload method một cách cẩn thận vì nó có thể dẫn đến sự nhầm lẫn. Ví dụng method perform(_:) sẽ luông gọi đến method  play(_:), và không bao giờ sử dụng đến play(_:usingPedals:).

override func play(_ music: Music) -> String {
  return play(music, usingPedals: hasPedals)
}

Như vậy là đã xong việc định hình class Piano việc tiếp theo là tạo một thể hiện (instance) của class này và tận hưởng âm nhạc thôi.

Instances

Chúng ta thêm đoạn code sau tiếp theo phần khởi tạo class Piano:

// 1
let piano = Piano(brand: "Yamaha", hasPedals: true)
piano.tune()
// 2
let music = Music(notes: ["C", "G", "F"])
piano.play(music, usingPedals: false)
// 3
piano.play(music)

 

  1. Đầu tiên chúng ta khởi tạo piano là một instance của class Piano và điều chỉnh âm thanh (tune). Lưu ý rằng với class, chúng ta viết hoa chữ cái đầu tiên và instance thì viết chữ thường nhé.
  2. Tiếp đến chúng ta khai báo một instance music dùng để làm tham số cho method play của piano. Giống như việc nhạc cụ thì cần phải có input là bản nhạc thì mới chơi được ra giai điệu.
  3. Hoặc là bạn cũng có thể đánh đàn với pedal hỗ trợ bằng cách gọi method play(_:).

Vậy là chúng ta đã có một chiếc đàn piano rồi, tiếp đến là một vài chiếc đàn guitar solo.

Guitars

Loại guitar đầu tiên mà chúng ta tạo ra là guitar acoustic.

class AcousticGuitar: Guitar {
  static let numberOfStrings = 6
  static let fretCount = 20
  
  override func tune() -> String {
    return "Tune \(brand) acoustic with E A D G B E"
  }
  
  override func play(_ music: Music) -> String {
    let preparedNotes = super.play(music)
    return "Play folk tune on frets \(preparedNotes)."
  }
}

Tất cả các đàn guitar acoutics đều có 6 dây và 20 phím, vì vậy bạn sẽ mô hinh các property tương ứng là kiểu static bởi vì chúng liên quan đến tất cả các loại guitar acoustic và là kiểu constants vì giá trị của chúng là bất biến. Class này không cần thêm thêm các stored property nào nữa, do vậy chúng ta không cần viết hàm khởi tạo mà chúng sẽ tự động được kế thừa từ class cha Guitar. Ở bài tiếp theo, chúng ta sẽ tiếp tục tạo một bộ amplifier để chỉnh nhạc.

Hết phần 2.

Nguồn bài viết: https://www.raywenderlich.com/160728/object-oriented-programming-swift