Menu
CoddyTech

Polimorfisme

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Ruby di Coddy. Pelajaran 32 dari 57.

Polimorfisme berarti satu pemanggilan method dapat bekerja pada object dari class yang berbeda, dan setiap object merespons dengan caranya sendiri. Kode yang melakukan perulangan pada berbagai bentuk memanggil area pada setiap bentuk tanpa menanyakan jenis bentuknya:

class Shape
  def to_s
    format("%s %.2f", self.class.name.downcase, area)
  end
end

class Circle < Shape
  def initialize(r)
    @r = r
  end

  def area
    3.14159 * @r * @r
  end
end

class Square < Shape
  def initialize(side)
    @side = side
  end

  def area
    @side * @side
  end
end

shapes = [Circle.new(1), Square.new(3)]
shapes.each { |s| puts s }
puts format("total %.2f", shapes.sum(&:area))

Output:

circle 3.14
square 9.00
total 12.14

Tanpa polimorfisme, pemanggil harus memeriksa jenis setiap object dan mengulangi pemeriksaan itu di mana pun perbedaannya berpengaruh. Dengan polimorfisme, perbedaan itu berada di dalam setiap class:

# tanpa polimorfisme
case shape.kind
when "circle" then 3.14159 * shape.r ** 2
when "square" then shape.side ** 2
end

# dengan polimorfisme
shape.area

Penambahan jenis object baru tidak memerlukan perubahan pada kode pemanggil: subclass baru dengan area miliknya sendiri dapat digunakan dalam setiap perulangan yang sudah ada:

class Shape
  def describe
    "area #{area}"
  end
end

class Square < Shape
  def area
    4
  end
end

class Triangle < Shape
  def area
    6
  end
end

[Square.new, Triangle.new].each { |s| puts s.describe }

Output:

area 4
area 6

to_s adalah contoh yang sering ditemui: puts memanggilnya pada objek apa pun, dan setiap class memberikan jawaban yang berbeda. Class buatanmu juga ikut serta dengan mendefinisikan to_s sendiri:

class Coin
  def to_s
    "a coin"
  end
end

[42, "text", nil, [1, 2], Coin.new].each { |x| puts "[#{x}]" }

Output:

[42]
[text]
[]
[[1, 2]]
[a coin]
challenge icon

Tantangan

Mudah

Lengkapi shape. Shape#to_s mengembalikan circle: 3.14, nama class dalam huruf kecil dan luas dengan dua angka desimal, dan setiap subclass menyediakan area: Circle.new(r) (gunakan 3.14159 untuk pi), Rectangle.new(w, h) dan Triangle.new(base, height).

Kode yang disediakan membaca baris circle 1, rectangle 2 3 atau triangle 4 5, mencetak setiap shape, lalu total: 22.14 dan largest: rectangle: 6.00, hanya dengan menggunakan to_s dan area.

Kodemu ditulis di shape.rb, circle.rb, rectangle.rb dan triangle.rb. main.rb berisi kode input/output yang disediakan dan tidak boleh diedit.

Coba sendiri

require_relative 'shape'
require_relative 'circle'
require_relative 'rectangle'
require_relative 'triangle'

# Kode input/output yang disediakan: biarkan apa adanya
input = []
while (line = gets)
  input << line.chomp
end
kinds = { "circle" => Circle, "rectangle" => Rectangle, "triangle" => Triangle }
shapes = input.map do |line|
  kind, *numbers = line.split
  kinds[kind].new(*numbers.map(&:to_f))
end
shapes.each { |s| puts s }
puts format("total: %.2f", shapes.sum(&:area))
puts "largest: #{shapes.max_by(&:area)}"
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler Ruby online