开发手册 欢迎您!
软件开发者资料库

Ruby - 面向对象

面向Ruby面向对象 - 从简单和简单的步骤学习Ruby从基本到高级概念,包括概述,环境设置,语法,类,变量,运算符,注释,If ... else,case,除非,循环,文件,I / O,函数,对象,TK,范围,迭代器,数组,字符串,方法,块,异常,面向对象,正则表达式,DBI,多线程,哈希,日期和时间,模块,LDAP,Web服务,Web编程,发送电子邮件,套接字编程,脚本语言,预定义常量,关联工具。

Ruby是一种纯粹的面向对象语言,Ruby作为一个对象. Ruby中的每个值都是一个对象,甚至是最原始的东西:字符串,数字甚至是真和假.甚至类本身也是对象,它是 Class 类的一个实例.本章将向您介绍与面向对象Ruby相关的所有主要功能.

一个类用于指定对象的形式,它将数据表示和操作数据的方法结合到一起一个整洁的包.类中的数据和方法称为类的成员.

Ruby类定义

定义类时,可以为其定义蓝图数据类型.这实际上并没有定义任何数据,但它确实定义了类名的含义,即类的对象将包含什么以及可以对这样的对象执行什么操作.

类定义以关键字开头,后跟类名,并以结尾分隔.例如,我们使用关键字class定义Box类,如下所示 :

class Box   codeend

名称必须以大写字母开头,按惯例,包含多个单词的名称与每个单词大写并且没有分隔字符(CamelCase)一起运行.

定义Ruby对象

一个类提供了对象的蓝图,所以基本上是从一个类创建一个对象.我们使用 new 关键字声明类的对象.以下语句声明了Box&minus类的两个对象;

box1 = Box.newbox2 = Box.new

初始化方法

初始化方法是一种标准的Ruby类方法,其工作方式与 constructor 适用于其他面向对象的编程语言.当您想要在创建对象时初始化某些类变量时,initialize方法很有用.这个方法可能需要一个参数列表,就像任何其他ruby方法一样,它前面有 def 关键字,如下所示 :

class Box   def initialize(w,h)      @width, @height = w, h   endend

实例变量

实例变量是一种类属性,一旦使用对象创建对象,它们就成为对象的属性班级.每个对象的属性都是单独分配的,与其他对象不共享任何值.可以使用@访问它们.类中的运算符,但要在类之外访问它们,我们使用 public 方法,这些方法称为访问方法.如果我们采用上面定义的类 Box ,那么@ width和@ height是类Box的实例变量.

class Box   def initialize(w,h)      # assign instance variables      @width, @height = w, h   endend

访问者& setter方法

要使变量从类外部可用,它们必须在访问器方法中定义,这些访问器方法也称为getter方法.以下示例显示了访问器方法的使用 :

#!/usr/bin/ruby -w# define a classclass Box   # constructor method   def initialize(w,h)      @width, @height = w, h   end   # accessor methods   def printWidth      @width   end   def printHeight      @height   endend# create an objectbox = Box.new(10, 20)# use accessor methodsx = box.printWidth()y = box.printHeight()puts "Width of the box is : #{x}"puts "Height of the box is : #{y}"

执行上述代码时,会产生以下结果 :

Width of the box is : 10Height of the box is : 20

类似于用于访问变量值的访问器方法,Ruby提供了一种设置值的方法使用 setter方法从类外部的变量,其定义如下 :

#!/usr/bin/ruby -w# define a classclass Box   # constructor method   def initialize(w,h)      @width, @height = w, h   end   # accessor methods   def getWidth      @width   end   def getHeight      @height   end   # setter methods   def setWidth=(value)      @width = value   end   def setHeight=(value)      @height = value   endend# create an objectbox = Box.new(10, 20)# use setter methodsbox.setWidth = 30box.setHeight = 50# use accessor methodsx = box.getWidth()y = box.getHeight()puts "Width of the box is : #{x}"puts "Height of the box is : #{y}"

执行上述代码时,它会产生以下结果 :

Width of the box is : 30Height of the box is : 50

实例方法

实例方法的定义方式与我们使用 def 关键字定义任何其他方法的方式相同,只能使用类实例,如下所示.它们的功能不仅限于访问实例变量,而且它们可以根据您的要求执行更多操作.

#!/usr/bin/ruby -w# define a classclass Box   # constructor method   def initialize(w,h)      @width, @height = w, h   end   # instance method   def getArea      @width * @height   endend# create an objectbox = Box.new(10, 20)# call instance methodsa = box.getArea()puts "Area of the box is : #{a}"

执行上述代码时,会产生以下结果 :

Area of the box is : 200

类方法和变量

类变量es 是一个变量,它在类的所有实例之间共享.换句话说,有一个变量实例,它由对象实例访问.类变量前缀为两个& com;字符(@@).必须在类定义中初始化类变量,如下所示.

使用 def self.methodname()定义类方法,该方法以结束分隔符结束并将使用类名称作为 classname.methodname 进行调用,如以下示例所示 :

#!/usr/bin/ruby -wclass Box   # Initialize our class variables   @@count = 0   def initialize(w,h)      # assign instance avriables      @width, @height = w, h      @@count += 1   end   def self.printCount()      puts "Box count is : #@@count"   endend# create two objectbox1 = Box.new(10, 20)box2 = Box.new(30, 100)# call class method to print box countBox.printCount()

执行上述代码时,会产生以下结果&mi nus;

Box count is : 2

to_s方法

您定义的任何类都应该有一个 to_s 实例方法来返回对象的字符串表示形式.下面是一个简单的例子来表示Box对象的宽度和高度 :

#!/usr/bin/ruby -wclass Box   # constructor method   def initialize(w,h)      @width, @height = w, h   end   # define to_s method   def to_s      "(w:#@width,h:#@height)"  # string formatting of the object.   endend# create an objectbox = Box.new(10, 20)# to_s method will be called in reference of string automatically.puts "String representation of box is : #{box}"

执行上述代码时,它会产生以下结果 :

String representation of box is : (w:10,h:20)

访问控制

Ruby在实例方法级别为您提供三个级别的保护,可以是公共,私有或受保护. Ruby不对实例和类变量应用任何访问控制.

  • 公共方法 : 任何人都可以调用公共方法.默认情况下,方法是公共的,除了initialize,它始终是私有的.

  • 私有方法 : 私有方法无法访问,甚至无法从课外查看.只有类方法才能访问私有成员.

  • 受保护的方法 : 受保护的方法只能由定义类及其子类的对象调用.访问权归家庭所有.

以下是显示所有三种访问修饰符的语法的简单示例 :

#!/usr/bin/ruby -w# define a classclass Box   # constructor method   def initialize(w,h)      @width, @height = w, h   end   # instance method by default it is public   def getArea      getWidth() * getHeight   end   # define private accessor methods   def getWidth      @width   end   def getHeight      @height   end   # make them private   private :getWidth, :getHeight   # instance method to print area   def printArea      @area = getWidth() * getHeight      puts "Big box area is : #@area"   end   # make it protected   protected :printAreaend# create an objectbox = Box.new(10, 20)# call instance methodsa = box.getArea()puts "Area of the box is : #{a}"# try to call protected or methodsbox.printArea()

执行上述代码时,产生以下结果.这里,第一个方法被成功调用,但第二个方法产生了问题.

Area of the box is : 200test.rb:42: protected method `printArea' called for # (NoMethodError)

类继承

面向对象编程中最重要的概念之一是继承.继承允许我们根据另一个类定义一个类,这样可以更容易地创建和维护一个应用程序.

继承还提供了重用代码功能和快速实现时间的机会,但是遗憾的是Ruby不支持多级继承,但Ruby支持 mixins . mixin就像是多继承的专用实现,其中只继承了接口部分.

创建类时,程序员可以指定,而不是编写全新的数据成员和成员函数.新类应该继承现有类的成员.此现有类称为基类或超类,新类称为派生类或子类.

在创建类时,程序员可以指定新类应该继承现有类的成员,而不是编写全新的数据成员和成员函数。 此现有类称为基类或超类,新类称为派生类或子类。


Ruby也支持子类化的概念,即继承,下面的例子解释了这个概念。 扩展类的语法很简单。 只需在类声明中添加<字符和超类的名称即可。 例如,下面将类BigBox定义为Box的子类 :

#!/usr/bin/ruby -w# define a classclass Box   # constructor method   def initialize(w,h)      @width, @height = w, h   end   # instance method   def getArea      @width * @height   endend# define a subclassclass BigBox < Box   # add a new instance method   def printArea      @area = @width * @height      puts "Big box area is : #@area"   endend# create an objectbox = BigBox.new(10, 20)# print the areabox.printArea()

执行上述代码时,会产生以下结果:

Big box area is : 200

方法覆盖

虽然您可以在派生类中添加新功能,但有时您希望更改父类中已定义方法的行为。 您可以通过保持方法名称相同并覆盖方法的功能来实现,如下例所示:

#!/usr/bin/ruby -w# define a classclass Box   # constructor method   def initialize(w,h)      @width, @height = w, h   end   # instance method   def getArea      @width * @height   endend# define a subclassclass BigBox < Box   # change existing getArea method as follows   def getArea      @area = @width * @height      puts "Big box area is : #@area"   endend# create an objectbox = BigBox.new(10, 20)# print the area using overriden method.box.getArea()

运算符重载

我们喜欢&plus; 运算符使用&plus;执行向量添加两个Box对象,*运算符将Box宽度和高度乘以标量,并使用一元运算符来取消Box的宽度和高度。 这是Box类的一个版本,定义了数学运算符:

class Box   def initialize(w,h)     # Initialize the width and height      @width,@height = w, h   end   def +(other)       # Define + to do vector addition      Box.new(@width + other.width, @height + other.height)   end   def -@           # Define unary minus to negate width and height      Box.new(-@width, -@height)   end   def *(scalar)           # To perform scalar multiplication      Box.new(@width*scalar, @height*scalar)   endend

Freezing对象

有时,希望防止对象被更改。 Object中的freeze方法允许我们这样做,有效地将对象转换为常量。 可以通过调用Object.freeze来冻结任何对象。 可能无法修改冻结对象:您无法更改其实例变量。

您可以使用Object.frozen检查给定对象是否已经冻结? 方法,如果对象被冻结则返回true,否则返回false值。 下面的例子清除了这个概念:

#!/usr/bin/ruby -w# define a classclass Box   # constructor method   def initialize(w,h)      @width, @height = w, h   end   # accessor methods   def getWidth      @width   end   def getHeight      @height   end   # setter methods   def setWidth=(value)      @width = value   end   def setHeight=(value)      @height = value   endend# create an objectbox = Box.new(10, 20)# let us freez this objectbox.freezeif( box.frozen? )   puts "Box object is frozen object"else   puts "Box object is normal object"end# now try using setter methodsbox.setWidth = 30box.setHeight = 50# use accessor methodsx = box.getWidth()y = box.getHeight()puts "Width of the box is : #{x}"puts "Height of the box is : #{y}"

执行上述代码时,会产生以下结果:

Box object is frozen objecttest.rb:20:in `setWidth=': can't modify frozen object (TypeError)   from test.rb:39

类常量

您可以通过为变量分配直接数字或字符串值来定义类中的常量,该变量是在不使用任何&amp; com的情况下定义的。 或者&commat;&commat;。 按照惯例,我们保持常量名称大写。

一旦定义了一个常量,你就不能改变它的值,但是你可以直接在类中访问一个常量,就像一个变量一样,但是如果你想在类之外访问一个常量,那么就必须使classname :: constant,如 下面的例子.

#!/usr/bin/ruby -w# define a classclass Box   BOX_COMPANY = "TATA Inc"   BOXWEIGHT = 10   # constructor method   def initialize(w,h)      @width, @height = w, h   end   # instance method   def getArea      @width * @height   endend# create an objectbox = Box.new(10, 20)# call instance methodsa = box.getArea()puts "Area of the box is : #{a}"puts Box::BOX_COMPANYputs "Box weight is: #{Box::BOXWEIGHT}"

执行上述代码时,会产生以下结果:

Area of the box is : 200TATA IncBox weight is: 10

类常量是继承的,可以像实例方法一样被覆盖.

使用分配创建对象

可能存在这样的情况:当您想要创建对象而不调用其构造函数初始化时,即使用新方法,在这种情况下,您可以调用allocate,这将为您创建未初始化的对象,如下例所示:

#!/usr/bin/ruby -w# define a classclass Box   attr_accessor :width, :height   # constructor method   def initialize(w,h)      @width, @height = w, h   end   # instance method   def getArea      @width * @height   endend# create an object using newbox1 = Box.new(10, 20)# create another object using allocatebox2 = Box.allocate# call instance method using box1a = box1.getArea()puts "Area of the box is : #{a}"# call instance method using box2a = box2.getArea()puts "Area of the box is : #{a}"

执行上述代码时,会产生以下结果:

Area of the box is : 200test.rb:14: warning: instance variable @width not initializedtest.rb:14: warning: instance variable @height not initializedtest.rb:14:in `getArea': undefined method `*'    for nil:NilClass (NoMethodError) from test.rb:29

类信息

如果类定义是可执行代码,这意味着它们在某个对象的上下文中执行:self必须引用某些东西。 让我们看看它是什么.

#!/usr/bin/ruby -wclass Box   # print class information   puts "Type of self = #{self.type}"   puts "Name of self = #{self.name}"end

执行上述代码时,会产生以下结果:

Type of self = ClassName of self = Box

这意味着使用该类作为当前对象执行类定义。 这意味着在执行方法定义期间,元类及其超类中的方法将可用。