Ruby语言介绍(四)——使用类编程与高级功能

延续Ruby语言介绍(三)——Ruby流程控制语句与实用数据处理

http://t.csdn.cn/wgR6E

主题:模板

阐述:关于模板的一些设定

主题:x

阐述:y

目录

主题:模板

主题:使用类编程

主题:理解面向对象概念

主题:类

主题:构造函数

主题:方法

主题:作用域修饰符

主题:继承类

主题:Ruby高级功能

主题:模块

主题:线程

主题:其他动态语言特性


主题:使用类编程

阐述:面向对象是一种程序设计方法,以“数据控制访问代码“”为主要原则,围绕数据来组织程序。而类时面向对象编程的核心,它不仅可以包括自己的成员,还可以通过继承关系来实现代码的重用。

之后介绍面向对象的概念,然后重点讲解在Ruby中如何定义类、实例化类、类的构造函数、类的方法、类的变量、属性等。最后介绍类之间的继承使用,以及继承时访问基类的构造函数和方法。

主题:理解面向对象概念

阐述:所谓面向对象是来解决问题的技术。将对象看做实体,将对象的特性和行为封装到一个类,方便其他的程序在执行相同的功能时调用,达到代码重用的目的。

面向堆场的思想有三大机制,也可以说是类的三大机制,即封装、继承和多态。

什么是对象

面向对象编程是以疏于对象来模拟现实世界。对象是现实世界中的任何事物。对象还可以表示抽象的规则、计划和事件。

一个对象所包含的所有数据和代码可以通过类来构成一个用户定义的数据类型,事实上,对象就是类类型变量。类就是具有相同或者相似的对象的抽象。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象。一旦定义了一个类,就可以创建这个类的多个对象。每个对象与一组数据有关,而这组数据的类型在类中定义。因此,一个类就是具有相同类型的对象的抽象。

面向对象设计思想 的精要在于一切都是对象。软件开发与设计都围绕着开发的目标进行,即围绕对象开发设计。一般而言一个对象应具有属性和行为。

在面向对象编程中,可以使用一组数据值描述对象的状态。对象还具有行为,即对象及其操作就是对象的行为。对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中。

封装

封装是累的基础,是指把类的相关实现细节隐藏起来,在类中将数据和实现操作的代码集中起来放在对象内部。在调用这些累的时候,直接使用类预留的接口就可以了。

继承

继承提供了子类自动拥有父类的数据结构和方法的机制。它表示类之间的一种关系,继承关系可以用树形关系来表示。

多态

多态是面向对象编程中的一个重要概念,它是指使一个对象被看成另一个对象的技术。

多态性增强了软件的灵活性和重用性。

主题:类

阐述:类表示要在应用程序中处理的实际对象,是具有相同行为和特点的多个对象的集合。

定义类

使用面向对象编程第一步就是定义类,在定义类时可以封装多个方法、属性和变量,从而使用类快速生成具有相同性质的对象。

class ClassName
    #类体
end

在Ruby中类的名称可以是任何被允许的 关键词。

在Ruby中定义类时可以执行类中定义的表达式,而不像其他语言仅能在类成员中使用。这样,当执行到类定义时,将直接执行类中定义的表达式。另外,类体中还可以使用self关键字表示默认对象或说是当前对象。

Ruby允许为定义的类追加类体,并对其进行添加和修改。使用类时,会将原来的类和追加类合并。

追加类的好处在于将类分散开,并保存到多个文件中,但是不能随意追加类,这是因为在加载类时,会将多个文件中的同一个类合并。因此除非有一个设计上的原因要求在一个地方定义类的一部分,在另一个地方定义类的另一部分。否则不推荐使用。

实例化类

在面向对象的编程中,对象时类实例化后的结果。在定义好嘞之后,便可以调用new关键字实例化一个对象。

主题:构造函数

阐述:在类实例化时默认会包含一个构造函数。构造函数是一种特殊的方法,主要用来在实例化对象时初始化对象,即为对象成员变量赋初始值。构造函数具有以下特点:

构造函数的名称必须是initialize;

构造函数没有任何返回值;

构造函数不能被直接调用,必须通过new运算符在实例化对象时才会自动调用;

不能对构造韩式使用任何其他访问控制修饰符;

可以接受0个或者多个参数,参数值在实例化时通过new运算符指定;

如果类中没有定义构造函数,Ruby会自动创建一个空的构造函数。

注:如果类中包含两个相同名的方法,后一个方法会完全覆盖前一个方法。

内部类

在使用Ruby语言定义类时,还可以在类的内部再定义一个类,形成类的嵌套。在实例化嵌套类时,需要使用“外部类::内部类.new”的格式实例化内部类。

在Ruby中还可以使用“class 外部类名::内部类名”的格式,在外部类的外部创建内部类。

特殊类

Ruby允许为某个特定的对象追加方法和变量。要为特定对象添加类成员,需要创建特定对象的类,也可以说是特殊类。其语法格式如下:

class<<obj
    #特殊类类体
end

这里的obj是实例化后的名称,表示将该实例创建为特殊类。特殊类中可以添加任何类成员。

注:类的其他对象不能访问特殊类的成员,只有特定对象才可以访问特殊类的成员。

主题:方法

阐述:

定义方法

方法是类的重要成员之一,主要用于执行计算和业务逻辑的处理,定义方法的语法格式如下:

def methodName arg1,arg2...argN
    #方法类
end

由上述语法格式可知,使用def关键字声明方法,然后是方法名称methodName,之后是可选的参数列表(多个之间使用逗号分隔)。

在Ruby中可以使用“()”为方法传递参数。

def methodName(arg1,...argN)
    #方法体
end

注:在我爱方法传递参数时,一定要注意传递参数的数据类型。如果传递参数的数据类型和方法体中使用参数的数据类型不同,将会出错。

为方法使用可变参数

在Ruby中,还可以使用一种简写的方式指定方法的参数数量是可变的。其具体方法是在参数名称后加一个星号“*”。

为方法指定参数默认值

当定义方法时,有时需要为参数设定默认值。设定默认值的方法非常简单,仅需要使用=运算符为参数赋值即可。

注:在定义方法时,一旦为方法参数设定了默认值,那么在调用方法时,就可以不为方法传递参数,而直接使用默认值。

使用方法的返回值

Ruby的每一个表达式都有一个返回值。调用方法的语句其实也是一个表达式,因此调用后也会返回一个结果,该结果就是方法的返回值。

要定义方法的返回值,最简单的方法就是使用return关键字显式指定返回值,当然也可以不用return关键字隐式返回表达式的值。

定义类方法

Ruby还支持使用类名称直接访问的方法,即类方法。类方法的定义和实例方法的定义不同,定义类方法时,要在方法名前增加类名称。这和定义特殊方法相同,这是因为此时把类作为对象。

技:在Ruby中还可以通过“self.类方法名”形式声明类方法。

定义特殊方法

除了实例方法和类方法外,Ruby中还可以为类定义特殊方法。馊味特殊方法就是为特定对象追加的方法,同样追加的方法只对待定对象有效。

定义类成员

方法、变量和属性共同构成了类的基本组成部分。

变量

根据使用位置不同,Ruby中的变量可以分为实例变量和变量。

实例变量

实例变量常用于存储类中的数据,可以声明在程序的以下位置:

顶层;

顶层方法;

类;

方法;

模块;

模块的方法。

在顶层和顶层方法定义的实例变量对整个程序有效,这是因为这种实例变量属于顶层Object对象。但是要注意,在顶层方法中定义的实例变量,只有在方法调用后才有效。@game。实例变量也可以定义在类中,此时该实例变量将属于实例化后的变量。。因此,在类的方法中并不能访问类范围的实例变量。而在类的方法范围内定义的实例变量,才属于类实例的实例变量。

class Car
    def go
        puts "汽车正在行驶";
        @speed = 120;
    end
    def  Acceleration
        puts "速度:  #{@speed}  千米/小时";
    end 
end

car = Car.new;
car.go;
car.Acceleration;


######程序执行结果如下
汽车正在行驶
速度: 120 千米/小时

上述代码在Car类的go方法中定义了类实例变量@speed,所以它可以在类的其他方法中访问。

类变量

在Ruby中可以定义类变量的地方和定义实例变量的地方相同。类变量的变量名都需要以“@@”开头,并且类变量属于某个类。所以在类的某个实例改变变量时,所有实例调用的类变量都发生改变。

属性

在Ruby中可以设置或获取的对象特定称为属性。在类中声明的实例变量为私有属性,即在声明类变量时,默认的修饰符为private,在类外部不能被访问。如果要访问类中的私有程艳,需要创建读写属性的方法。

#例:创建只读属性
class Car
    def  initialize name,color
      @name = name;
      @color = color;
    end
    def  name
      return @name;
    end
    def  color
      @xolor;
    end
end
car = Car.new "宝马","银白色"
puts "这是一辆#{car.color}的#{car.name}车";

上述代码在构造函数中的定义了两个实例变量,并且折回来给你个实例变量分别用name方法和color方法返回。这样通过访问name和color方法,就可以在类外部访问类中的实例变量。这样,name和color就可以称为类中的只读属性。

在类外部如果要设置类中的实例变量,还需要创建设置实例变量的方法。设置实例变量的方法比较特殊,命名时需要加上“=”,即“属性名称=”。

Ruby中还有一些内置的方法用于在类中创建属性。这些方法主要有以下几个:

attr_reader方法:创建只读属性;

attr_write方法:创建只写属性;

attr_accessor方法:创建读写属性;

attr方法:产生读属性和可选写属性。

其中,attr方法第二参数值为true将定义读写属性,如果没有设置或者设置为false,将创建只读属性。

主题:作用域修饰符

阐述:

在面向对象编程中,类是用来对数据及对数据操作进行封装的,使类外部看不到累的 的实现细节。在Ruby总,通过使用作用域修饰符来控制器成员的影藏和显示。Ruby共提供了以下三种作用域修饰符关键字:

public关键字:修饰的类成员表示公共成员,在任何地方都可以访问这些类成员;

private关键字:修饰的类成员为保护成员,这些成员只能被其他方法调用,不能通过类对象显式调用;

protected关键字:声明的类成员为保护成员,一般情况下与private修饰的类成员的含义相同,但是protected修饰符修饰的方法可以被调用者显式调用。

在Ruby中,一旦在类中声明了一个作用域修饰关键字,那么关键字后面的所有方法都采用该作用域,知道定义了另一个作用域。如果没有声明作用域修饰符,那么除initialize方法外其他方法默认为public作用域。

还可以使用publicMethod类似的方法。

public修饰符修饰的方法可以在任何地方显式访问。

主题:继承类

阐述:继承是面向对象程序设计的一个重要概念。通过继承可以使得开发人员快速基于一个已有的类编写一个新类。通常把被继承的类称作父类。

继承语法

class ParentClass
    #类体
end
class  SubClass < ParentCLass
    #类体
end

注:在Ruby中一个派生类只允许继承自一个类,不允许从两个或者多个类中派生。但是基类可以派生多个类。

使用"<"语法指定继承类。

访问基类构造函数

在Ruby中实例化派生类时,派生类可以直接访问基类的构造函数。如果基类没有定义构造函数,派生类也可以不定义构造函数,全部采用默认的构造函数,即调用基类的initialize方法。

继承基类的方法

当派生类的成员与基类的成员具有相同的名称时,这种情况下就会覆盖某类的方法,同样,可以认为派生类从基类继承的方法为定义的方法,而后面新定义的方法会覆盖从基类继承的方法。

Ruby不支持像Java和C++语言中的中的重载。(方法名相同,参数列表不同的两个方法)。因此,只要派生类中的方法名和基类中的方法名相同,即使在派生类中新定义的方法的参数列表和基类的参数列表和基类方法不同,也会覆盖基类中的方法。

在Ruby中用super关键字可以调用基类的方法。当在派生类方法里使用super关键字时,Ruby会自动把它转换成调用基类中的同名方法。也可以说,在派生类定义域基类同名方法时,使用super关键字保留基类的原有方法。

主题:Ruby高级功能

阐述:有一些高级的Ruby开发技术,如BEGIN和END块、定义模块、定义模块、线程的使用以及如何处理异常等。还有一些Ruby特有的动态语言特性。

BEGIN和END块

在Java中有“前置通知”和“后置通知”的概念,所谓的“前置通知”就是在加载前就执行的模块,而“后置通知”就是主体代码执行后的代码块。

Ruby语言中使用BEGIN和END块实现“前置通知”和”后置通知"的操作。BEGIN是注册初始化,而END是注册结束,在解释器释放文件的时候执行。

BEGIN{

#初始化代码

}

END{

#释放代码

}

主题:模块

阐述:模块和类相似,也是一组方法和常量的组合。与类不同的是,模块没有实例,但是可以将模块的动能添加到知道类或指定的对象。

定义模块

使用module关键字

module    moduleName

    #模块体

end

在模块中可以像类一样定义实例变量、实例方法、类变量、类方法和属性等,并且在模块中还可以定义类和模块。同样在类中也可以定义模块。

提示:如果在模块中定义了内部模块,访问嵌套模块和访问内部类的格式相同,即采用“外部模块::内部模块”的形式访问。

命名空间

在Ruby中使用模块就可以实现 命名空间的功能,以防止出现命名冲突。

使用“模块名::类名”的形式实例化模块内部的类,然后调用类的实例方法。

虽然Ruby中可以使用内部类来实现命名空间的功能,但是在应用程序中很少这样使用,而是使用模块作为命名空间来使用。

加载外部文件

在大型的应用程序中,往往把不同的类或者模块存放在不同的文件中。此时,在使用时就要将这些文件加载到一起。Ruby提供了4个方法实现加载外部文件,分别是load、require、include和extend。

load方法

load方法用来加载扩展名为".rb"的源文件,在加载时需要使用完整的文件名。load方法的作用其实就是复制和粘贴。一旦使用load方法加载Ruby源文件,在程序中就可以直接使用源文件中的Ruby编写的代码。如下:

load “system.rb”;

require方法

与load方法一样,使用require方法也可以加载源文件。require方法的用法更为强大,它不仅可以加载Ruby源文件,还可以加载其他语言编写的源文件。

require   "common/console.c";

include方法

include方法主要用来将一个模块插入()额可以说是包含)到一个类或者其他模块中。include方法的使用情况:

1>在类定义中引入模块,使模块中的方法成为类的实例方法

2>在类定义中引入模块,既希望引入实例方法,又希望引入类方法,这个时候需要使用include方法。但是在模块中对类方法的定义不同,定义出现在方法def self.include(c)...end中。

extend方法

extend方法用来在一个对象中引入一个模块,这个类从而也具备了这个模块的方法。通常情况下,在类定义中引入模块,要使模块中的方法成为类方法时需要使用extend方法。

主题:线程

阐述:线程是程序运行的最小单元,用于完成一个单一的顺序控制流程。在每个程序中同时运行多个线程完成不同的工作,成为多线程,其优点是可移植性高、可并发执行以及共享内存空间。缺点是其执行效率低于进程。

创建线程

Ruby中用户级线程依赖于操作系统。他们会完成一定的任务,也会随操作系统变化。在使用线程之前必须先进行创建,方法很简单,只要创建Thread类的实例即可。语法格式如下:

thread = Thread.new do

    #作为线程执行的块

End

注:还可以使用Thread.new的别名Thread.start创建线程,两者在语法效果上完全一致。

在创建线程时,还可以为线程传递参数,然后在线程块中获取参数并作相应的处理。

注:当在一个Ruby程序中有多个线程存在时,他们将交替执行,也可以说是并发执行。

返回当前线程

在Ruby中通过调用Thread类的current方法可以返回当前运行的线程。

挂起当前线程

在Ruby中通过调用Thread类的join方法可以挂起当前线程,直至执行完指定线程,然后再执行挂起的线程。

注:如果线程在没有挂起之前就执行完成,那么再挂起线程将会出错。

还可以通过thread的value方法挂起当前线程。value方法与join方法最大的不同在于,value方法可以获取线程的值。

暂停线程

使用THread类的pass方法可以暂停线程,并执行其他线程。与前面介绍的Thread方法不同,pass方法时Thread类的类方法,所以需要使用Thread.pass形式调用。

停止线程

要停止一个线程可以使用Thread类中的exit方法或者kill方法,这两个方法在停止线程时会将线程完全退出。

提:在线程中,如果使用exit方法或kill方法停止主线程,那么就会退出程序。

休眠线程

使用sleep方法可以休眠当前线程一段时间。一旦时间结束,线程会自动洞休眠状态变为可执行状态。Ruby语言还可以使用stop方法将一个线程设置成休眠状态,使用wakeup方法唤醒指定线程。

获取线程状态

在Ruby中线程一旦被创建,在执行过程中可具有多种状态。要获取线程当前的状态可以使用Thread中的status方法。

sleep        线程处于一个sleep状态,或者正在等待IO

run        线程正在运行

aborting        线程被取消

false        线程正常终止

nil        线程被非正常终止

在Thread类中还包含一个用于判断某条线程是否可以被执行的alive?方法。还可以使用priority查看和修改线程的优先级。

异常处理

Ruby语言也能处理程序运行时的各种异常情况。当应用程序遇到异常情况时,它将“抛”出一个异常,并终止当前方法,直到发现一个异常处理,那个堆栈才会清空。

常见异常

异常名                             常见原因                                     抛出情况

RuntimeError                  由raise方法抛出的默认异常        raise

NoMehodError                调用一个不存的方法抛出的

                                        异常信息                                     stu=Object.new

NameError                      解释器碰到一个不能解析

                                        为变量或方法名的标识符           stu.UnknownMethodName

                                         时抛出的异常消息                     a=some_random_identifier

IOError                             当读取关闭的流,写入只读              

                                         或者类似操作时抛出的异常

                                         消息                                             STDN.puts("不能写入的流") 

Errorno:error                    与文件IO相关的一组错误              File.Open(-l)

TypeError                         为方法传递不能处理的参数时

                                         抛出的异常信息                            a=10+"string"

ArgunmentError              传递参数的数量出错时抛出的        def  foo

                                        异常消息                                          方法体

                                                                                                end

                                                                                              foo(1,2,3)

捕获异常

在Ruby中使用rescue语句和ensure语句来捕获异常。rescue语句用于将程序从异常中跳出,前提是程序需要包含在BEGIN和END块中;ensure语句用于处理产生异常之后的处理工作,像系统资源的回收。

手动抛出异常

rescue语句捕获并进行处理异常。raise语句的语法格式如下:

raise    异常类的名称,异常消息字符串

手动抛出的异常同样可以用rescue捕获

自定义异常类

除了Ruby内置的几种异常外,还允许开发人员自定义异常类。要创建自定义异常类,需要从Exception类继承。

主题:其他动态语言特性

阐述:Ruby不仅具有像C#和Java等面向对象语言的安全性和强类型特性,又具有像JavaScript和Perl等脚本语言的灵活性。如调用未定义的方法时自动调用错误处理的回调方法。

method_missing方法

Ruby中如果调用一个类或者一个实例的某个方法时,如果系统没有搜索到方法,那么会调用method_missing方法。

Proc方法

Proc(过程)对象用于将一组局部变量绑定到一个代码块。一旦绑定,代码可以在不同的上线爱问环境中被调用。

动态执行代码

所谓动态执行代码,就是预先不知道要执行什么语句或预料不到所有可能的情况下,使用参数或某些代码从其他地方传递过来,执行要完成的任务。

使用eval动态执行代码速度略慢于正常执行,因此使用eval时要谨慎。不能过于频繁使用。

垃圾收集器

垃圾收集器是现代软件虚拟机技术的重要组成部分,Java、Python、C#和Ruby等解释器语言都是采用垃圾收集的方式进行内存管理的。Ruby提供了GC类和ObjectSpace类以提供垃圾收集功能。

GC类只有disable、enable、start和garbage_collect4个方法,其中前两个的功能是关闭和启动垃圾收集器,start方法和garbage_collect方法意义相同,都是实现垃圾收集功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王辞夜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值