如何了解 ruby 的类和对象

Python0207

如何了解 ruby 的类和对象,第1张

Ruby是一个完美的面向对象编程语言。拥有面向对象的编程语言的功能,包括:

1、数据封装

2、数据抽象

3、多态性

4、继承

这些功能已在讨论面向对象Ruby

面向对象的程序涉及类和对象。 一个类是蓝本,从个别对象被创建。在面向对象的术语,我们说小明的自行车是被称为自行车类的对象实例。

任何车辆的例子。它包括轮子,马力,燃油或燃气罐容量。这些特点形成的类车辆的数据成员。可以从其他车辆区分这些特征。

车辆也有一定的功能,如停止,驾驶,超速驾驶。即使这些功能形成的类车辆的数据成员。因此,可以定义一个类作为一个组合的特点和功能。

车辆类可以被定义为:

Class Vehicle

{

Number no_of_wheels

Number horsepower

Characters type_of_tank

Number Capacity

Function speeding

{

}

Function driving

{

}

Function halting

{

}

}

通过这些数据成员分配不同的值,可以形成类车辆的几个实例。例如,飞机的有三个轮子,1,000马力,不同的燃料罐及容量为100升。同样的方式,一辆汽车有四个轮子,200马力,气体作为不同的罐及容量25升。

Ruby中定义一个类:

要通过使用Ruby实现面向对象编程,需要先学习如何创建对象和Ruby中的类。

Ruby中一个类总是以关键字class类的名称开头。名称应始终以首字母大写。如以是Customer类可以显示为:

class Customer

end

类定义结束通过使用关键字end结束。在类的所有数据成员是类之间的定义,并以end关键字作为结束符。

Ruby类中的变量:

Ruby提供了四种类型的变量:

局部变量: 局部变量是在一个方法中定义的变量。局部变量是不可用的方法外。更多细节在随后的章节中的方法中会介绍。局部变量一般以小写字母或_开头。

实例变量: 实例变量是可跨越任何特定实例或对象的方法。这意味着,从对象到对象的实例变量改变。实例变量前面加上at符号(@),跟着变量名。

类变量:类变量是可在各种不同的对象。 一个类变量属于类,是类的一个特点。他们前面的符号@@跟着的变量名。

全局变量: 类变量是不能跨类。如果想要一个单一的变量可以跨类,需要定义一个全局变量。全局变量的前面总是用美元符号($)。

例子:

使用类变量@@no_of_customers,能确定创建的对象的数量。这使得导出的客户数量。

class Customer

@@no_of_customers=0

end

Ruby中使用new方法创建对象:

对象是类的实例。现在,将学习如何在Ruby中创建对象一个类对象。Ruby中通过使用new方法创建对象。

new方法是一种独特的方法,这是预定义在Ruby库。new方法属于类的方法。

下面的例子是创建两个对象类客户cust1 和 cust2:

cust1 = Customer. new

cust2 = Customer. new

在这里,cust1和cust2是两个对象的名字。在等于号(=)之后,类名称将按照对象名称。然后,点运算符和关键字new在后面。

自定义方法来创建Ruby对象 :

可以通过new方法的参数,这些参数可以用来初始化类变量。

当打算声明的new方法具有参数,需要声明的方法在创建类的时候初始化。

initialize方法是一种特殊类型的方法,该方法时将执行new方法的类被称为参数。

下面的例子是创建initialize方法:

class Customer

@@no_of_customers=0

def initialize(id, name, addr)

@cust_id=id

@cust_name=name

@cust_addr=addr

end

end

在这个例子中,可以声明局部变量的初始化方法id, name和addr。这里def 结束被用来定义一个Ruby的方法初始化。这些将在有关后续章节中了解更多。

在initialize方法中,对这些局部变量的值传递到实例变量@cust_id,@cust_name和@cust_addr。这里的局部变量持有的值由new方法一同传递。

现在可以创建对象,如下所示:

cust1=Customer.new("1", "John", "Wisdom Apartments, Ludhiya")

cust2=Customer.new("2", "Poul", "New Empire road, Khandala")

Ruby中类的成员函数:

在Ruby中,函数被调用的方法。在一个类中的每个方法的方法名用关键字def开始。

方法名总是以小写字母最好。你最终的方法Ruby中通过使用关键字end表示结束。

下面的例子是定义一个Ruby的方法:

class Sample

def function

statement 1

statement 2

end

end

这里statement1和statement2为函数体的一部分。这些statments可以是任何有效的Ruby语句。例如,我们可以在方法中打印Hello Ruby如下:

class Sample

def hello

puts "Hello Ruby!"

end

end

现在,在下面的例子Sample类创建一个对象,并调用hello方法,看到的结果:

#!/usr/bin/ruby

class Sample

def hello

puts "Hello Ruby!"

end

end

# Now using above class to create objects

object = Sample. new

object.hello

这将产生以下结果:

Hello Ruby!

在Ruby中,有多种方法可以实现方法的动态调用。

1.

使用send方法

第一种实现动态方法调用是使用send方法,send方法在Object类中定义,方法的第一个参数是一个符号用来表示所要调用的方法,后面则是所调用方法需要的参数。

“This

is

a

dog1″.send(:length)

=>

14

上面的代码中通过send方法去对一个字符串执行length操作,返回字符串的长度。

class

TestClass

def

hello(*args)

”Hello

+

args.join(‘

‘)

end

end

a

=

TestClass.new

puts

a.send

:hello,

“This”,

“is”,

“a”,

“dog!”

执行结果为:

Hello

This

is

a

dog!

2.

使用Method类和UnboundMethod类

另一种实现动态方法调用是使用Object类的method方法,这个方法返回一个Method类的对象。我们可以使用call方法来执行方法调用。

test1

=

“This

is

a

dog1″.method(:length)

test1.call

=>

14

class

Test

def

initialize(var)

@var

=

var

end

def

hello()

”Hello,

@var

=

#{@var}”

end

end

k

=

Test.new(10)

m

=

k.method(:hello)

m.call

#=>

“Hello,

@iv

=

99″

l

=

Test.new(‘Grant’)

m

=

l.method(“hello”)

m.call

#=>

“Hello,

@iv

=

Fred”

可以在使用对象的任何地方使用method对象,当调用call方法时,参数所指明的方法会被执行,这种行为有些像C语言中的函数指针。你也可以把method对象作为一个迭代器使用。

def

square(a)

a*a

end

mObj

=

method(:square)

[1,

2,

3,

4].collect(&mObj)

=>

[1

4

9

16]

Method对象都是和某一特定对象绑定的,也就是说你需要通过某一对象使用Method对象。你也可以通过UnboundMethod类创建对象,然后再把它绑定到某个具体的对象中。如果UnboundMethod对象调用时尚未绑定,则会引发异常。

class

Double

def

get_value

2

*

@side

end

def

initialize(side)

@side

=

side

end

end

a

=

Double.instance_method(:get_value)

#返回一个UnboundMethod对象

s

=

Double.new(50)

b

=

a.bind(s)

puts

b.call

执行结果为:

100

看下面一个更具体的例子:

class

CommandInterpreter

def

do_2()

print

“This

is

2

end

def

do_1()

print

“This

is

1

end

def

do_4()

print

“This

is

4

end

def

do_3()

print

“This

is

3

end

Dispatcher

=

{

?2

=>

instance_method(:do_2),

?1

=>

instance_method(:do_1),

?4

=>

instance_method(:do_4),

?3

=>

instance_method(:do_3)

}

def

interpret(string)

string.each_byte

{|i|

Dispatcher[i].bind(self).call

}

end

end

interpreter

=

CommandInterpreter.new

interpreter.interpret(’1234′)

执行结果为:

This

is

1

This

is

2

This

is

3

This

is

4

3.

使用eval方法

我们还可以使用eval方法实现方法动态调用。eval方法在Kernel模块中定义,有多种变体如class_eval,module_eval,instance_eval等。Eval方法将分析其后的字符串参数并把这个字符串参数作为Ruby代码执行。

str

=

“Hello”

eval

“str

+

World!’”

=>

Hello

World!

sentence

=

%q{“This

is

a

test!”.length}

eval

sentence

=>

15

当我们在使用eval方法时,我们可以通过eval方法的第二个参数指明eval所运行代码的上下文环境,这个参数可以是Binding类对象或Proc类对象。Binding类封装了代码在某一环境运行的上下文,可以供以后使用。

class

BindingTest

def

initialize(n)

@value

=

n

end

def

getBinding

return

binding()

#使用Kernel#binding方法返回一个Binding对象

end

end

obj1

=

BindingTest.new(10)

binding1

=

obj1.getBinding

obj2

=

BindingTest.new(“Binding

Test”)

binding2

=

obj2.getBinding

puts

eval(“@value”,

binding1)

#=>

10

puts

eval(“@value”,

binding2)

#=>

Binding

Test

puts

eval(“@value”)

#=>

nil

可以看到上述代码中,@value在binding1所指明的上下文环境中值为10,在binding2所指明的上下文环境中值为Binding

Test。当eval方法不提供binding参数时,在当前上下文环境中@value并未定义,值为nil。