首页 > 编程语言 >无涯教程-Ruby - 面向对象

无涯教程-Ruby - 面向对象

时间:2023-11-20 15:31:48浏览次数:37  
标签:Box box end width 无涯 height 面向对象 Ruby def

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

相关文章

  • 掌握Java面向对象OOP篇(一)
    掌握面向对象OOP篇(一)边学边记--OOP(ObjectOrientatedPrograming)1.为什么要引入面向对象?原因:封装、继承、多态举个例子理解面向对象代码的好处:比如:我们有一个实际问题,假设现在一个宠物店有两只小狗,第一只叫做小白,年龄2岁,白色;第二只叫做小红,年龄3岁,红色;现在我们的宠物......
  • 无涯教程-Ruby - 文件IO
    Ruby提供了在Kernel模块中实现的与I/O相关的整套方法。所有I/O方法都是从IO类派生的。IO提供了所有基本方法,如read,write,gets,puts,readline,getc,和printf 。本章将介绍Ruby中可用的所有基本I/O函数。有关更多函数,请参阅RubyClassIO。Puts语句在前面的章节中,您已经为变量......
  • 无涯教程-Ruby - 迭代器
    迭代器不过是collections 集合支持的方法。存储一组数据成员的对象称为集合。在Ruby中,数组和哈希可以称为集合。迭代器一个接一个地返回集合的所有元素。无涯教程将在这里讨论两个迭代器,分别是each和collect。Each迭代器每个迭代器返回数组或哈希的所有元素。collecti......
  • JS如何做到面向对象
    JS本省没有面向对象,它是如何来做类,和类的实例的呢?。1:函数对象的prototype   每个函数对象都有一个prototype成员,指向一个表, functiona(){};  a.prototype指向一个表对象2:表的__proto__  每个js表(Object)对象,都会有一个成员__proto__, 指向一个表(Object)......
  • 无涯教程-Ruby - 模块语句
    Module语法moduleIdentifierstatement1statement2...........end模块常量的命名与类常量一样,并带有大写字母开头。方法定义也看起来相似:模块方法的定义就像类方法一样。与类方法一样,您可以通过在模块名称前加上模块名称和句点来调用模块方法,并使用模块名称和......
  • 无涯教程-Ruby - 变量声明
    变量是存储位置,用于保存任何程序要使用的任何数据,Ruby支持五种类型的变量,本章介绍了这五种变量。Ruby全局变量全局变量以"$"开头。未初始化的全局变量的值为nil并使用-w选项生成警告。分配给全局变量会更改全局状态,不建议使用全局变量,它们使程序变得很难维护,下面是全局变量......
  • 无涯教程-Ruby - Blocks块
    您已经了解了Ruby是如何定义方法的,可以在其中放置大量语句,然后调用该方法。同样,Ruby也具有Block的概念。Block语法block_name{statement1statement2..........}在这里,您将学习使用简单的yield语句来调用块。您还将学习使用带参数的yield语句来调用块。Yie......
  • 无涯教程-Ruby - 方法声明
    Ruby方法与任何其他编程语言中的函数都非常相似。 方法名称应以小写字母开头,如果您以大写字母开头的方法名称,Ruby可能会认为它是一个常量,因此可能会错误地解析该调用。方法应该在调用它们之前定义,否则Ruby将为未定义的方法调用引发异常。语法defmethod_name[([arg[=def......
  • 无涯教程-Ruby - 注释符
    注释是Ruby代码中的注释行,在运行时会被忽略。一行注释以#字符开头,它们从#延伸到该行的末尾,如下所示-#!/usr/bin/ruby-w#Thisisasinglelinecomment.puts"Hello,Ruby!"执行后,上述程序会产生以下输出-Hello,Ruby!Ruby多行注释您可以使用=begin和=end语法注释多......
  • 无涯教程-Ruby - 类和对象
    面向对象的程序涉及类(Class)和对象(Object)。以车辆为例,它包括车轮,马力以及燃油或汽油箱的容量。这些特征构成了Vehicle类的数据成员,车辆还可以具有某些函数,如停止,驾驶和超速行驶,因此,您可以将类定义为特征和函数的组合。车辆类(Vehicle)别可以定义为-ClassVehicle{Numb......