Ruby是一种纯粹的面向对象的语言,所有事物在Ruby中都是对象,Ruby中的每个值都是一个对象。
本章将带您了解与面向对象的Ruby相关的所有主要函数。
Ruby 类定义
类定义以关键字 class 开头,后跟 class name ,并以 end 分隔。如,无涯教程使用关键字class定义Box类,如下所示:
class Box code end
该名称必须以大写字母开头,并且按照惯例,包含多个单词的名称必须与每个单词大写且没有分隔符一起使用(CamelCase)。
Ruby 对象
对象基本上是从类创建的。使用 new 关键字声明类的对象。以下语句声明Box类的两个对象-
box1=Box.new box2=Box.new
Ruby 初始化
initialize方法是一种标准的Ruby类方法,其工作方式与 constructor 在其他面向对象的编程语言中的工作方式几乎相同。当您要在创建对象时初始化一些类变量时,initialize方法很有用。此方法可能会包含参数列表,并且像其他任何ruby方法一样,它会以 def 关键字开头,如下所示-
class Box def initialize(w,h) @width, @height=w, h end end
Ruby 类变量
变量是类的一种属性,一旦使用该类创建了对象,它们便成为对象的属性。 每个对象的属性都是单独分配的, 使用@可以访问它们。 类中的操作符,但要在类外部访问它们,使用公共方法,这些方法称为访问器方法。 如果无涯教程采用上述定义的Box类,则@width和@height是Box类的变量。
class Box def initialize(w,h) # assign instance variables @width, @height=w, h end end
Accessor & setter 方法
为了使变量可以从类外部使用,必须在 accessor方法中定义它们,这些访问器方法也称为getter方法。
#!/usr/bin/ruby -w # 定义一个类 class Box # 构造方法 def initialize(w,h) @width, @height=w, h end # 访问器方法 def printWidth @width end def printHeight @height end end #创建一个对象 box=Box.new(10, 20) #使用访问器方法 x=box.printWidth() y=box.printHeight() puts "Width of the box is : #{x}" puts "Height of the box is : #{y}"
执行以上代码后,将产生以下输出-
Width of the box is : 10 Height of the box is : 20
类似于用于访问变量值的访问器方法,Ruby提供了一种使用 setter方法从类外部设置这些变量的值的方法,其定义如下-
#!/usr/bin/ruby -w # 定义一个类 class Box # 构造方法 def initialize(w,h) @width, @height=w, h end # 访问器方法 def getWidth @width end def getHeight @height end # 设置方法 def setWidth=(value) @width=value end def setHeight=(value) @height=value end end # 创建一个对象 box=Box.new(10, 20) # 使用 setter 方法 box.setWidth=30 box.setHeight=50 # 使用访问器方法 x=box.getWidth() y=box.getHeight() puts "Width of the box is : #{x}" puts "Height of the box is : #{y}"
执行以上代码后,将产生以下输出-
Width of the box is : 30 Height of the box is : 50
Ruby 类方法
方法的定义方式与无涯教程使用 def 关键字定义任何其他方法的方式相同,并且只能通过类使用它们,如下所示。它们的函数不仅限于访问变量,还可以根据您的要求做更多的事情。
#!/usr/bin/ruby -w # 定义一个类 class Box # 构造方法 def initialize(w,h) @width, @height=w, h end # 实例方法 def getArea @width * @height end end # 创建一个对象 box=Box.new(10, 20) # 调用实例方法 a=box.getArea() puts "Area of the box is : #{a}"
执行以上代码后,将产生以下输出-
Area of the box is : 200
Ruby 类方法和变量
类变量以两个@字符(@@)为前缀。 如下所示,必须在类定义中初始化类变量。
使用 def self.methodname()定义一个类方法,该方法以结束定界符结尾,并且将使用类名 classname.methodname 进行调用,如以下示例所示。 -
#!/usr/bin/ruby -w class Box # 初始化类变量 @@count=0 def initialize(w,h) # 分配实例变量 @width, @height=w, h @@count += 1 end def self.printCount() puts "Box count is : #@@count" end end # 创建两个对象 box1=Box.new(10, 20) box2=Box.new(30, 100) # 调用类方法打印 Box.printCount()
执行以上代码后,将产生以下输出-
Box count is : 2
Ruby to_s 方法
您定义的任何类都应具有 to_s 方法,以返回对象的字符串表示形式。以下是一个简单的示例,用于表示Box对象的宽度和高度-
#!/usr/bin/ruby -w class Box # 构造方法 def initialize(w,h) @width, @height=w, h end # 定义 to_s 方法 def to_s "(w:#@width,h:#@height)" # 对象的字符串格式。 end end # 创建一个对象 box=Box.new(10, 20) # to_s 方法将在引用字符串时自动调用。 puts "String representation of box is : #{box}"
执行以上代码后,将产生以下输出-
String representation of box is : (w:10,h:20)
Ruby 访问修饰符
Ruby在方法级别为您提供了三种保护级别,它们可以是public,private或protected 。
public - 任何人都可以调用公共方法。默认情况下,方法是公共的,但初始化除外。
private - 私有方法无法访问,甚至不能从类外部查看,只有类方法可以访问私有成员。
protected - 保护方法只能由定义类及其子类的对象调用。
以下是一个简单的示例,显示所有三个访问修饰符的语法-
#!/usr/bin/ruby -w # 定义一个类 class Box # 构造方法 def initialize(w,h) @width, @height=w, h end # 实例方法默认是公共的 def getArea getWidth() * getHeight end # 定义私有访问器方法 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 :printArea end # 创建一个对象 box=Box.new(10, 20) # 调用实例方法 a=box.getArea() puts "Area of the box is : #{a}" # 尝试调用 protected 或方法 box.printArea()
执行以上代码后,将产生以下输出。在这里,第一种方法被成功调用,但是第二种方法产生了问题。
Area of the box is : 200 test.rb:42: protected method `printArea' called for # <Box:0xb7f11280 @height=20, @width=10> (NoMethodError)
Ruby 类继承
面向对象编程中最重要的概念之一就是继承。继承可以用另一个类来定义一个类,这使创建和维护应用程序变得更加容易。
不幸的是Ruby不支持多级继承,但是Ruby支持 mixins 。 mixin就像多重继承的特殊实现,其中仅继承接口部分。
Ruby还支持子类化的概念,即继承,下面的示例对此概念进行了说明。 扩展类的语法很简单。 只需在类声明中添加<字符和超类的名称。 如下面将BigBox类定义为Box的子类-
#!/usr/bin/ruby -w #定义一个类 class Box # 构造方法 def initialize(w,h) @width, @height=w, h end # 实例方法 def getArea @width * @height end end # 定义一个子类 class BigBox < Box # 添加一个新的实例方法 def printArea @area=@width * @height puts "Big box area is : #@area" end end # 创建一个对象 box=BigBox.new(10, 20) #打印Area box.printArea()
执行以上代码后,将产生以下输出-
Big box area is : 200
Ruby 方法覆盖
尽管您可以在派生类中添加新函数,但是有时您想更改父类中已定义方法的行为。您可以简单地通过保持方法名称相同并覆盖该方法的函数来做到这一点
#!/usr/bin/ruby -w # 定义一个类 class Box # 构造方法 def initialize(w,h) @width, @height=w, h end # 实例方法 def getArea @width * @height end end # 定义一个子类 class BigBox < Box # 更改现有的 getArea 方法如下 def getArea @area=@width * @height puts "Big box area is : #@area" end end # 创建一个对象 box=BigBox.new(10, 20) # print the area using overriden method. box.getArea()
Ruby 方法重载
无涯教程希望 + 运算符可以使用+对两个Box对象执行矢量加法运算,*运算符可以将Box的宽度和高度乘以标量,而 - 运算符可以对Box的宽度和高度进行求反。 这是Box类的一个版本,其中定义了数学运算符-
class Box def initialize(w,h) # 初始化宽度和高度 @width,@height=w, h end def +(other) # 定义 + 做向量加法 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) # 执行标量乘法 Box.new(@width*scalar, @height*scalar) end end
Ruby frozen对象
有时,无涯教程希望防止更改对象。 Object中的冻结方法使能够执行此操作,从而有效地将对象转换为常量。
您可以使用 Object.frozen?方法检查给定的对象是否已经冻结,如果冻结了该对象,则返回true,否则返回false。
#!/usr/bin/ruby -w # 定义一个类 class Box # 构造方法 def initialize(w,h) @width, @height=w, h end # 访问器方法 def getWidth @width end def getHeight @height end # 设置方法 def setWidth=(value) @width=value end def setHeight=(value) @height=value end end # 创建一个对象 box=Box.new(10, 20) # let us freez this object box.freeze if( box.frozen? ) puts "Box object is frozen object" else puts "Box object is normal object" end # now try using setter methods box.setWidth=30 box.setHeight=50 # use accessor methods x=box.getWidth() y=box.getHeight() puts "Width of the box is : #{x}" puts "Height of the box is : #{y}"
执行以上代码后,将产生以下输出-
Box object is frozen object test.rb:20:in `setWidth=': can't modify frozen object (TypeError) from test.rb:39
Ruby 类常量
您可以通过将直接数字或字符串值分配给变量来定义类中的常量,而无需使用@或@@即可定义该变量。 按照惯例,将常量名称保留为大写。
一旦定义了常量,就不能更改其值,但是可以像在变量中一样直接在类内部访问常量,但是如果要在类外部访问常量,则必须使用 class name::constant 如以下示例所示。
#!/usr/bin/ruby -w # define a class class Box BOX_COMPANY="TATA Inc" BOXWEIGHT=10 # constructor method def initialize(w,h) @width, @height=w, h end # instance method def getArea @width * @height end end # create an object box=Box.new(10, 20) # call instance methods a=box.getArea() puts "Area of the box is : #{a}" puts Box::BOX_COMPANY puts "Box weight is: #{Box::BOXWEIGHT}"
执行以上代码后,将产生以下输出-
Area of the box is : 200 TATA Inc Box weight is: 10
类常量是继承的,可以像方法一样覆盖。
Ruby 创建对象
在某些情况下,您想创建一个对象而不调用其构造函数 initialize ,即使用新方法,在这种情况下,您可以调用 allocate ,这将创建一个未初始化的对象如以下示例中所示-
#!/usr/bin/ruby -w # define a class class Box attr_accessor :width, :height # constructor method def initialize(w,h) @width, @height=w, h end # instance method def getArea @width * @height end end # create an object using new box1=Box.new(10, 20) # create another object using allocate box2=Box.allocate # call instance method using box1 a=box1.getArea() puts "Area of the box is : #{a}" # call instance method using box2 a=box2.getArea() puts "Area of the box is : #{a}"
执行以上代码后,将产生以下输出-
Area of the box is : 200 test.rb:14: warning: instance variable @width not initialized test.rb:14: warning: instance variable @height not initialized test.rb:14:in `getArea': undefined method `*' for nil:NilClass (NoMethodError) from test.rb:29
Ruby 类信息
如果类定义是可执行代码,则意味着它们在某个对象的上下文中执行:self必须引用某些东西。
#!/usr/bin/ruby -w class Box # print class information puts "Type of self=#{self.type}" puts "Name of self=#{self.name}" end
执行以上代码后,将产生以下输出-
Type of self=Class Name of self=Box
这意味着将使用该类作为当前对象来执行类定义。这意味着在执行方法定义期间,元类及其超类中的方法将可用。
参考链接
https://www.learnfk.com/ruby/ruby-object-oriented.html
标签:Box,box,end,width,无涯,height,面向对象,Ruby,def From: https://blog.51cto.com/u_14033984/8489310