Simulating Multiple Inheritance with Mixins
You want to create a class that derives from two or more sources, but Ruby doesn't support multiple inheritance in such cases you can use mixins
A Ruby class can only have one superclass, but it can include any number of modules. These modules are called mixins. If you write a chunk of code that can add functionality to classes in general, it should go into a mixin module instead of a class.
The only objects that need to be defined as classes are the ones that get instantiated and used on their own (modules can't be instantiated).
When a class includes a module with the include keyword, all of the module's methods and constants are made available from within that class. They're not copied, the way a method is when you alias it.
Rather, the class becomes aware of the methods of the module. If a module's methods are changed later (even during runtime), so are the methods of all the classes that include that module.
Below is the simple example.
Suppose you created a class called Taggable that lets you associate tags (short strings of informative metadata) with objects. Every class whose objects should be taggable could derive from Taggable.
This would work if you made Taggable the top-level class in your class structure, but that won't work in every situation. Eventually you might want to do something like make a string taggable. One class can't subclass both Taggable and String, so you'd have a problem
Here's a taggable string class: it subclasses String, but it also includes the functionality of Taggable.
A Ruby class can only have one superclass, but it can include any number of modules. These modules are called mixins. If you write a chunk of code that can add functionality to classes in general, it should go into a mixin module instead of a class.
The only objects that need to be defined as classes are the ones that get instantiated and used on their own (modules can't be instantiated).
When a class includes a module with the include keyword, all of the module's methods and constants are made available from within that class. They're not copied, the way a method is when you alias it.
Rather, the class becomes aware of the methods of the module. If a module's methods are changed later (even during runtime), so are the methods of all the classes that include that module.
Below is the simple example.
Suppose you created a class called Taggable that lets you associate tags (short strings of informative metadata) with objects. Every class whose objects should be taggable could derive from Taggable.
This would work if you made Taggable the top-level class in your class structure, but that won't work in every situation. Eventually you might want to do something like make a string taggable. One class can't subclass both Taggable and String, so you'd have a problem
module Taggable
attr_accessor :tags
def taggable_setup
@tags = Set.new
end
def add_tag(tag)
@tags << tag
end
def remove_tag(tag)
@tags.delete(tag)
end
end
Here's a taggable string class: it subclasses String, but it also includes the functionality of Taggable.
class TaggableString < String
include Taggable
def initialize(*args)
super
taggable_setup
end
end
s = TaggableString.new('It was the best of times, it was the worst of times.')
s.add_tag 'dickens'
s.add_tag 'quotation'
s.tags # => #
Comments
Post a Comment