如何在ruby中正确实例化一个子类

时间:2017-06-09 14:13:25

标签: ruby-on-rails ruby

如果我有Book型号:

class Book < ApplicationRecord
  def calculate_page
    .
    .
  end
end

我创建了一个自定义子类ExtendedBook

class ExtendedBook < Book
end

如何实例化一个继承书籍实例的扩展书籍对象及其实例方法。有点像:

@book = Book.first
@extended_book = ExtendedBook.new (@book, @attributes_for_extended_book)

这样我最终可以直接在@book对象中使用@extended_book的实例方法,如:

@extended_book.calculate_page

,无需在calculate_page子类中为ExtendedBook手动定义attr_getter。

2 个答案:

答案 0 :(得分:2)

子类自动获取父类的方法。

所以,你需要做的就是:

@extended_book = ExtendedBook.new
@extended_book.calculate_page # This will work.

现在,您可能希望扩展程序能够使用现有的@book对象。在这种情况下,您根本不需要子类,更可能是装饰器。

class Book
  def initialize(total_pages)
    @total_pages = total_pages
  end
end

class ExtendedBook
  def initialize(book)
    @book = book
  end

  def pages_in_half
    return @book.total_pages / 2
  end
end

book = Book.new(10)
ExtendedBook.new(book).pages_in_half # Returns 5.

这样,您的ExtendedBook可以与已经实例化的Book对象进行交互。

另一种选择是允许ExtendedBook子类化Book,但将必要的实例变量复制到自身。您可能更喜欢这种方法。

class ExtendedBook < Book
  def initialize(book)
    @total_pages = book.total_pages
  end

  def pages_in_half
    return @total_pages / 2
  end
end

book = Book.new(10)
ExtendedBook.new(book).pages_in_half # Returns 5.

每个都有利有弊,所以取决于你想要的东西。

答案 1 :(得分:1)

使用Forwardable

require 'forwardable'

class ExtendedBook
  extend Forwardable

  attr_accessor :book

  def_delegators :@book ,:total_pages,:my_other_method:,whatever

  def initialize(book)
     @book = book
  end

end

并确保为您要委托的attr_reader中的每个实例变量设置attr_accessorBook