📜  Ruby 中的面向对象编程|设置 1

📅  最后修改于: 2022-05-13 01:55:09.715000             🧑  作者: Mango

Ruby 中的面向对象编程|设置 1

当我们说面向对象编程时,我们的意思是我们的代码以对象为中心。对象是分类为各种类型的现实生活中的实例。

让我们举一个例子来更好地理解这一点。如果我们将玫瑰视为一个对象,那么玫瑰的类别将是花。类就像对象的蓝图,描述了对象的属性和行为。花的属性可以是颜色、香味,甚至是它是否有刺。这些特性是类的一部分,并且类的每个实例,即类的每个对象都将共享这些属性。尽管属性的值可能因不同的对象而异。举个例子——百合。因此,如果玫瑰对象的花瓣颜色是红色,那么对于百合来说,它可能是白色的。这是面向对象编程的基础,我们可以利用现实生活中的情况并从中制作不同的实例。

现在让我们看看如何在 Ruby 中定义一个类

类的语法:

class classname
end

用 Ruby 实现 OOP 概念

Ruby 通过允许创建类及其对象来支持 OOP 范式。就像我们之前说的,对象是类的实例,类就像对象的蓝图。一个类列出属性并定义对象的行为,而对象是现实世界的表示。

一个类有两个部分——数据和方法
所以现在我们有了一个类 Language 让我们将属性定义为
1) 语言名称
2) 主题名称

现在我们有了数据,但我们需要一种访问它们的方法。这就是我们的方法的用武之地。类方法是在类中定义的方法,用于访问我们类中的各种数据。为了实现到代码中,我们使用构造函数,它接收属性的值并将它们分配给为特定对象存储的空间。

构造函数的语法:

def initialize(x, y)
    @x = x
    @y = y
end

初始化函数在类中定义,其语法与普通函数一样。它可以接受任意数量的参数。 @符号代表对象的实际属性。

例子:

class Language
    def initialize(language_name, topic_name)
        @language_name = language_name
        @topic_name = topic_name
    end
end

为了创建一个类的实例,我们使用一个熟悉的函数,我们之前可能用它来制作散列或数组。我们使用新函数。

句法 :

object_name  = Class_name.new()

如果我们有任何参数,它通常在 new 的括号中传递,就像在普通方法中一样。

例子:

class Language
    def initialize(language_name, topic_name)
        @language_name = language_name
        @topic_name = topic_name
    end
end
  
object1 = Language.new('Ruby','method')

所以我们有一个名为 object1 的对象。我们使用 Language.new() 创建一个新实例,这调用了初始化函数。所以 object1.language_name 是 Ruby。而 object1.topic_name 是方法

让我们也创建第二个对象

例子:

class Language
    def initialize(language_name, topic_name)
        @language_name = language_name
        @topic_name = topic_name
    end
end
  
object1 = Language.new('Ruby','method')
object2 = Language.new('Scala','string')

所以 object2.language_name 是 Scala 而 object2.topic_name 是字符串。

访问方法

现在我们已经定义了类并创建了对象,我们需要能够更改或查看对象的属性。这就是我们课程的第二部分 - 方法。类方法很像我们在类中定义的常规方法。
我们使用方法来更改某些属性的值并查看这些值。要为特定方法调用方法,我们必须提及object_name.method_name 。通过一个例子可以更好地理解这一点。

例子:

# Ruby program to understand the concept of 
# Access Method
class Language
    def initialize(language_name, topic_name)
        @language_name = language_name
        @topic_name = topic_name
    end
     
    # Defining Methods
    def return_name
        return @language_name
    end
    def return_topic
        return @topic_name
    end
end
  
# Creating objects
object1 = Language.new('Ruby','method')
object2 = Language.new('Scala','string')
puts 'Language name for object1: ' + object1.return_name
puts 'Topic Name for object1: ' + object1.return_topic
  
puts 'Language name for object2: ' + object2.return_name
puts 'Topic Name for object2: ' + object2.return_topic

输出 :

Language name for object1: Ruby
Topic Name for object1: method
Language name for object2: Scala
Topic Name for object2: string

我们在上面的例子中创建了两个对象。 object1.return_name 为 object1 调用方法 return_name,这将返回结果“Ruby”。如果我们调用 object2.return_topic,它会调用 object2 的方法 return_topic 这会将结果“方法”返回到 puts 语句。

通常在 ruby 中,方法返回该方法的最后一个计算机结果,因此我们不必显式编写 return。
所以不要写下面的代码

def return_name
    return @vehicle_name
end

我们可以编写如下代码。

def return_name
    @vehicle_name
end

变量范围

当我们说变量范围时,我们的意思是在哪些领域可以使用某个变量。范围可以是全局的或局部的 当我们说全局时,我们的意思是在整个代码中,我们可以在任何地方使用全局变量来定义全局变量,我们使用“$”符号。

例子:

# Ruby program to understand the concept of 
# Variable Scope
class Language
  
    # Creating global variable
    $reader = 'ABCD'
    def initialize(language_name, topic_name)
        @language_name = language_name
        @topic_name = topic_name
    end
     
    # Defining Methods
    def return_name
        return @language_name
    end
    def return_topic
        return @topic_name
    end
end
  
# Creating objects
object1 = Language.new('Ruby','method')
object2 = Language.new('Scala','string')
puts 'Language name for object1: ' + object1.return_name
puts 'Topic Name for object1: ' + object1.return_topic
  
puts 'Language name for object2: ' + object2.return_name
puts 'Topic Name for object2: ' + object2.return_topic
  
# Printing global variable
puts 'The reader is '+ $reader

输出 :

Language name for object1: Ruby
Topic Name for object1: method
Language name for object2: Scala
Topic Name for object2: string
The reader is ABCD

在上面的例子中,我们声明了一个全局变量,因为这个变量是全局的,我们可以在程序的任何地方使用它。 $reader负责ABCD 。让我们用其中一个实例变量object1.language_name来尝试一下。这会产生错误,因为这个变量是局部范围的,即只在类内。所以我们需要使用访问方法或使用下面解释的 attr_reader。

修改属性

让我们用例子来理解它。

例子:

# Ruby program to understand the concept of 
# Modifying attributes
class Language
  def initialize(language_name, topic_name)
        @language_name = language_name
        @topic_name = topic_name
    end
  
  # Defining Method
    def return_name
        return @language_name
    end
    def return_topic
        return @topic_name
    end
    def modify_topic(value)
        @topic_name = value
    end
end
  
# Creating object
object = Language.new('Ruby','method') 
puts 'Language name for object: '+object.return_name
puts 'Topic name is '+object.return_topic
  
# Modifying attribute
object.modify_topic('string')
puts 'New Topic Name is '+object.return_topic

输出 :

Language name for object: Ruby
Topic name is method
New Topic Name is string

在上面的例子中,我们看到了一个新的方法 modify_topic。此方法用于更改属性 topic_name 的值。由于无法在函数外部直接访问属性,因此我们求助于使用方法来访问它们。正如我们在示例中看到的,我们将新主题作为参数传递给 modify_topic 方法。在该方法中,对象的主题属性被重置为新主题。

类变量

类变量与实例变量的不同之处在于它们属于类而不是对象。对于语言名称和主题名称等实例变量,每个对象都有一份副本,但对于类变量,通常在所有对象之间共享一份副本,变量属于类,而不是类的实例,但仍然可以通过以下方式访问类的实例。类变量通常使用'@@'来标识。语法是@@class_variable = 0 。它可以有一个默认值,可以是从字符串到整数的任何值。

例子 :

# Ruby program to understand the concept of 
# Class Variables
class Language
    $reader = 'ABCD'
  
    # Creating class variable
    @@count = 0
    def initialize(language_name, topic_name)
        @language_name = language_name
        @topic_name = topic_name
        @@count  += 1
    end
  
    # Defining method
    def return_name
        @language_name
    end
    def return_topic
        @topic_name
    end
      
    # Returning class variable
    def  return_count
        @@count
    end
end
  
# Creating object
object1 = Language.new('Ruby', 'method') 
object2 = Language.new('Scala', 'string')
puts 'Language name for object1: '+object1.return_name
puts 'Topic name for object1: '+object1.return_topic
  
puts 'Language name for object2: '+object2.return_name
puts 'Topic name for object2: '+object2.return_topic
  
puts 'The reader is '+ $reader 
  
puts 'The number of objects created is ' + object1.return_count.to_s
puts 'The number of objects created is ' + object2.return_count.to_s

输出 :

Language name for object1: Ruby
Topic name for object1: method
Language name for object2: Scala
Topic name for object2: string
The reader is ABCD
The number of objects created is 2
The number of objects created is 2

在上面的例子中,我们使用了一个类变量 count 来跟踪正在创建的对象的数量,这是上面例子中类变量最常见的用法之一,我们将 count 初始化为 0。我们还添加了一个函数在调用时返回值。每次创建对象时,每次调用initialize函数时都会调用initialize方法,无论我们使用object1还是object2调用return_count方法,count都会增加1,即@@count += 1 ,它会打印出同样的结果。和实例变量一样,它的作用域只在类内,不能在类外直接访问,我们使用.to_s将数字转换为字符串。

而不是访问方法
在前面的示例中,我们介绍了返回属性的方法。我们有一个更简单的解决方法。这就是 attr_reader、attr_writer、attr_accessor 发挥作用的地方,请考虑下一段代码。

例子 :

# Ruby program to understand the concept of 
# Modifying attributes
class Language
        attr_reader :language_name
        attr_writer :topic_name
        attr_reader :topic_name
  
    def initialize(language_name, topic_name)
            @language_name = language_name
            @topic_name = topic_name
    end
      
end
      
object = Language.new('Ruby', 'method') 
puts 'The name of the language is ' + object.language_name
puts 'The topic of the language is ' + object.topic_name
  
# changing the topic name
object.topic_name = 'array'
puts 'The new topic of the language is ' + object.topic_name

输出 :

The name of the language is Ruby
The topic of the language is method
The new topic of the language is array