Menu
CoddyTech

Nesneleri Genişletme

Coddy'nin Ruby Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 28 / 57.

extend, bir modülün yöntemlerini tüm örnekler yerine tek bir nesneye ekler. Bir sınıfı genişletmek, bu yöntemleri sınıf nesnesine ekler; böylece bunlar sınıf yöntemleri olur:

module Describable
  def describe
    "#{name} has #{instance_methods(false).size} methods"
  end
end

class Dog
  extend Describable

  def bark
    "Woof"
  end

  def sit
    "sits"
  end
end

puts Dog.describe

Çıktı:

Dog has 2 methods

extend ile kullanılan bir modül, sınıfın örnek değişkenlerinde durum tutabilir. Bu modülü genişleten her sınıf, sınıf örnek değişkenleri olarak kendi kopyasını alır:

module Counted
  def created
    @created ||= 0
  end

  def record
    @created = created + 1
  end
end

class Order
  extend Counted
end

class Invoice
  extend Counted
end

Order.record
Order.record
Invoice.record
puts "#{Order.created} #{Invoice.created}"

Çıktı:

2 1

extend tek bir nesne üzerinde de çalışır. Yöntemleri yalnızca o nesne kazanır; sınıfının diğer örnekleri değişmeden kalır ve is_a? yalnızca genişletilen nesne için true olur:

module Shiny
  def polish
    "#{self} is shining"
  end
end

a = "car"
b = "bike"
a.extend(Shiny)
puts a.polish
puts a.is_a?(Shiny)
puts b.respond_to?(:polish)

Çıktı:

car is shining
true
false

İki anahtar sözcük, aynı modülün yöntemlerini farklı yerlere yerleştirir. include, onları bir sınıfın örnek yöntemleri hâline getirir; extend ise genişletilen tek nesnenin yöntemleri hâline getirir:

class Order
  include Printable    # order.print_me       (her örnek)
  extend Counted       # Order.record         (sınıfın kendisi)
end

item.extend(Shiny)     # item.polish          (yalnızca bu nesne)
challenge icon

Görev

Kolay

Registry modülünü tamamla; sınıflar bu modülü extend ile kullanır. register(name), sınıfın @entries içinde tutulan kendi listesine bir ad ekler (ilk kullanımda oluşturulur) ve Plugin registered x döndürür; ad zaten listedeyse Plugin already has x döndürür. entries listeyi, count ise listenin boyutunu döndürür. Plugin ve Theme sınıflarının ikisi de Registry modülünü genişletir ve ayrı listeler tutar.

Verilen kod, plugin name veya theme name satırlarını okur, eşleşen sınıfta register metodunu çağırır ve yanıtı yazdırır. Son olarak plugins: a, b (2) ve themes: ... yazdırır; liste boşsa none (0) yazdırır.

Kodunu registry.rb, plugin.rb ve theme.rb dosyalarına yaz. main.rb verilen giriş/çıkış kodunu içerir ve düzenlenemez.

Kendin dene

require_relative 'registry'
require_relative 'plugin'
require_relative 'theme'

# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
input = []
while (line = gets)
  input << line.chomp
end
input.each do |line|
  kind, name = line.split
  target = kind == "plugin" ? Plugin : Theme
  puts target.register(name)
end
[["plugins", Plugin], ["themes", Theme]].each do |label, klass|
  list = klass.entries.empty? ? "none" : klass.entries.join(", ")
  puts "#{label}: #{list} (#{klass.count})"
end
quiz iconKendini test et

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

Kendi başına pratik yap: Online Ruby derleyicisi