Çok Biçimlilik
Coddy'nin Ruby Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 32 / 57.
Polimorfizm, bir yöntem çağrısının farklı sınıflardaki nesneler üzerinde çalışması ve her nesnenin kendi biçiminde yanıt vermesi anlamına gelir. Şekiller üzerinde döngü oluşturan kod, ne tür bir şekle sahip olduğunu sormadan her biri üzerinde area çağrısı yapar:
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))Çıktı:
circle 3.14
square 9.00
total 12.14Polimorfizm olmadan, çağıran taraf her nesnenin türünü kontrol etmek ve farkın önemli olduğu her yerde bu kontrolü tekrarlamak zorundadır. Polimorfizm ile fark her sınıfın içinde yaşar:
# polimorfizm olmadan
case shape.kind
when "circle" then 3.14159 * shape.r ** 2
when "square" then shape.side ** 2
end
# polimorfizm ile
shape.areaYeni bir nesne türü eklemek, çağıran kodda herhangi bir değişiklik gerektirmez: kendi area metoduna sahip yeni bir alt sınıf, zaten var olan her döngüde çalışır:
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 }Çıktı:
area 4
area 6to_s günlük hayattan bir örnektir: puts bunu herhangi bir nesne üzerinde çağırır ve her sınıf farklı yanıt verir. Kendi to_s yöntemlerini tanımlayarak sınıfların da buna katılmasını sağlayabilirsiniz:
class Coin
def to_s
"a coin"
end
end
[42, "text", nil, [1, 2], Coin.new].each { |x| puts "[#{x}]" }Çıktı:
[42]
[text]
[]
[[1, 2]]
[a coin]Görev
KolayŞekilleri tamamla. Shape#to_s, sınıf adını küçük harfle ve alanı iki ondalık basamakla birlikte circle: 3.14 biçiminde döndürür; her alt sınıf da area sağlar: Circle.new(r) (pi için 3.14159 kullan), Rectangle.new(w, h) ve Triangle.new(base, height).
Sağlanan kod circle 1, rectangle 2 3 veya triangle 4 5 satırlarını okur, her şekli yazdırır, ardından total: 22.14 ve largest: rectangle: 6.00 değerlerini yazdırır; yalnızca to_s ve area ile çalışır.
Kodun shape.rb, circle.rb, rectangle.rb ve triangle.rb dosyalarına yazılmalıdır. main.rb, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.
Kendin dene
require_relative 'shape'
require_relative 'circle'
require_relative 'rectangle'
require_relative 'triangle'
# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
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)}"
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Sınıflar ve Nesneler
Dosyalarla ÇalışmaSınıf TanımlamaÖrnek DeğişkenleriMetotlar ve selfto_s ve inspectÖzet - Kütüphane Kartı7Çok Biçimlilik ve Ördek Tiplemesi
Çok BiçimlilikÖrdek TiplemesiSoyut Metotlarcase ve SınıflarTekrar - Ödeme Yöntemleri2Erişimciler ve self
Okuyucular ve YazıcılarÖzel Setter'larMetotlarda selfKimlik ve EşitlikTekrar - Kişi Listesi5Kalıtım
Alt sınıflarMetotları geçersiz kılmasuper çağrısıis_a? ve üst sınıflarTekrar - Personel Maaşları8Özel Metotlar
Eşitlik ve hashOperatör Metotlarıİndeksleme ve EklemeÖzel KoleksiyonlarTekrar - Kesirler11Proje: Kütüphane Yönetimi
Kitaplar ve ÜyelerKitap Ödünç Alma3Sınıf Metotları ve Değişkenleri
Sınıf MetotlarıSınıf Örnek DeğişkenleriSabitlerFabrika MetotlarıTekrar - Kupon KodlarıKendi başına pratik yap: Online Ruby derleyicisi