本来想把输入输出讲得更明白一些,但是发现I/O这个东西实在是太多了,一时半会也讲不清楚,就只好先搁下来了。绕一下,先来看看Ruby的面向对象的特征吧。先来建立一个简单的类。这个类的定义中只含有一个函数:initialize

class Song

def initialize(name, artist, duration)

@name = name

@artist = artist

@duration = duration

end

end

InitializeRuby中是一个特殊的方法。当你在用Song.new来新建一个类实例的时候,Initialize就会被调用,可以把他看做是一种特殊的构造函数。一个类实例就代表一首歌,因此名字,艺术家等属性在类实例的存活期就会一直存在,我们可以使用实例变量来存储这些值。在Ruby中,实例变量是以(@)”at”符号开头的。

Ruby中,类是不会被关闭的,也就是说我们可以动态地改变类的定义。动态语言的特征正是表现在这个地方。

看我们前面写过一个Hello World的程序,我们来做一个小实验。把代码改成以下的样子:

class Hello

  def sayHello(name)

    yield

    puts "Hello #{name}"

    yield

  end

end

 

myHello = Hello.new()

name = gets

myHello. sayHello(name){ puts "in the block" }

 

class Hello

  def to_s

    "Hello world!"

  end

end

 

myHello.sayHello(name)

puts myHello.to_s

不要担心我们把一个Hello类定义了两次,实际的情况是在第一次定义完成之后,类并没有关闭,当我们第二次再定义Hello类的时候,只是重写了to_s方法而已。

 

方法被重写?这显然已经涉及到了继承的问题了,那就再来看一下Ruby的继承机制吧。再拿我们的Song来举例子吧。如果现在你需要歌词,那么不必重写这个Song类,只要一个简单的继承就可以了。

       `class KaraokeSong < Song

def initialize(name, artist, duration, lyrics)

super(name, artist, duration)

@lyrics = lyrics

end

end

类定义中的“< Song“就是告诉Ruby KaraokeSongSong的一个子类。下一节,我们讨论一下类继承时方法的调用控制问题。