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