On the knowledge of inheritance and message in Ruby _ruby special topic

Source: Internet
Author: User
Tags class definition inheritance instance method

Inheritance allows you to create a class that is refined (refinement) and special (specialization) for another class. For example, in our jukebox system, the concept of "song" is encapsulated in the song class, and then, as the market grows, we need to provide karaoke support. A karaoke song is no different from any other song (it just doesn't have a vocal track, so we don't have to care about that). However, it also includes a set of lyrics and time information. When our jukebox is playing a karaoke song, the lyrics should be scrolling along with the music on the screen in front of the jukebox.

One way to solve this problem is to define a new class Karaokesong, which is song plus the lyrics.

Class Karaokesong <song

  def initialize (name,artist,duration,lyrics)

    super (name,artist,duration)

    @ Lyrics = Lyrics

  end



The "< Song" in the class definition line tells Ruby that Karaokesong is a subclass of Song (subclass). Therefore, it also means that song is Karaokesong Super Class (superclass)

Song = Karaokesong.new ("My Way", "Sinatra", 255, "and now,the ...") song.to_s-> *song:my Way--sinatra          ( 225) *

Call to_s method does not show lyrics

This is related to the mechanism by which Ruby determines which method to invoke when sending a message to an object. During the initial parsing (parse) of the program code, when Ruby encounters a method call song.to_s, it does not know where to find the to_s method, but instead will decide to defer until the program starts running. At that point, Ruby looked at the class the song belonged to. If the class implements the same method as the message name, run this method. Otherwise, Ruby looks at the methods in its parent class, and then the grandparent, where the entire ancestor chain was previously traced. If eventually it does not find the right method in the Ancestor class, Ruby produces a special behavior that usually causes an error to be raised.

Let's solve this problem by implementing karaokesong#to_s, there are many ways you can do it. Let's start with the most to_s method, and we'll copy the method from the song class and add lyrics information.

Class Karaokesong

 #

 ... def to_s

   "KS: # @name--# @artist (# @duration) {# @lyrics} ' end end

song = Karaokesong.new (' My Way '," Sinatra ", Now,the," and

song.to_s     -> "Ks:my Way--sinatra () {and now,the ...}"

We have correctly shown the value of the instance variable @lyrics. However, using this method, subclasses need to directly access the instance variables of their ancestors. So why is this a bad way to achieve to_s?

The answer is related to a good programming style (sometimes called decoupling). The direct stamp into the inner structure of the parent class, and the display of its instance variables, makes us tightly bound to the implementation of the parent class.

We solve this problem by having each class handle its own implementation details. When calling karaokesong#to_s, we call the To_s method of its parent class to get the details of the song. Then, add the lyrics to the message and return the results. The technique used here is Ruby's keyword super. When you call super instead of using arguments, Ruby sends a message to the parent class of the current object asking it to invoke the same method in the child class. Ruby passes the parameters of the method we originally called to the parent class. Now, we can implement the new to_s method after improvement.

Class Karaokesong <song

  #Format ourselves as a string by the

  appending #our lyrics to our parent ' s to_s value.

  def to_s

    super+ "{# @lyrics}"

  end

song = Karaokesong.new ("My Way", "Sinatra", "a", "and now,the ...")

song.to_s      -> "Song:my Way--sinatra () {and now,the ...}"

We explicitly tell Ruby,karaokesong to be a subclass of song, but we do not specify what the parent class of the song class itself is. If you define a class without specifying its parent class, Ruby defaults to the object class as its parent class. This means that the ancestor of all classes is object, and the instance method of object is available to all of Ruby's objects.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.