ruby 新建对象

by Nishant Mishra

由Nishant Mishra

Ruby面向对象编程简介 (An Introduction to Object-Oriented Programming with Ruby)

As a computer science student, I spend a lot of time learning and playing with new languages. Every new language has something unique to offer. Having said that, most beginners start off their programming journey with either procedural languages like C or with object-oriented languages like JavaScript and C++.

作为计算机科学专业的学生,​​我花了大量时间学习和使用新语言。 每种新语言都有其独特之处。 话虽如此,大多数初学者都是从程序语言(如C)或面向对象的语言(如JavaScript和C ++)开始编程的。

Therefore, it makes sense to go through the basics of object-oriented programming so you can understand the concepts and apply them to the languages you learn easily. We’ll be using the Ruby programming language as an example.

因此,通读面向对象编程的基础知识是有意义的,这样您就可以理解这些概念并将其应用于容易学习的语言。 我们将以Ruby编程语言为例。

You may be asking, why Ruby? Because it is “designed to make programmers happy” and also because almost everything in Ruby is an object.

您可能会问,为什么要使用Ruby? 因为它“旨在使程序员感到高兴”,而且因为Ruby中的几乎所有东西都是对象。

了解面向对象范例(OOP) (Getting a sense of the Object-Oriented Paradigm (OOP))

In OOP, we identify the “things” that our program handles. As humans, we think about things as objects with attributes and behaviors, and we interact with things based on these attributes and behaviors. A thing can be a car, a book, and so on. Such things become classes (the blueprints of objects), and we create objects out of these classes.

在OOP中,我们确定程序处理的“事物”。 作为人类,我们将事物视为具有属性和行为的对象,并基于这些属性和行为与事物进行交互。 事物可以是汽车,书籍等。 这样的东西变成了类(对象的蓝图),我们从这些类中创建了对象。

Each instance (object) contains instance variables which are the state of the object (attributes). Object behaviors are represented by methods.

每个实例(对象)包含实例变量,这些变量是对象(属性)的状态。 对象行为由方法表示。

Let’s take the example of a car. A car is a thing which would make it a class. A specific type of car, say BMW is an object of the class Car. The attributes/properties of a BMW such as the color and model number can be stored in instance variables. And if you want to perform an operation of the object, such as driving, then “drive” describes a behavior which is defined as a method.

让我们以汽车为例。 汽车是一种使它成为阶级的东西。 宝马(BMW)是一种特殊类型的汽车,是Car类的对象 BMW的属性/属性 (例如颜色和型号)可以存储在实例变量中。 并且,如果要执行对象的操作(例如驱动),则“驱动”描述了一种定义为方法的行为。

快速语法课 (A Quick Syntax Lesson)

  • To end a line in a Ruby program, a semicolon(;) is optional (but is generally not used)要在Ruby程序中结束一行,分号(;)是可选的(但通常不使用)
  • 2-space indentation for each nested level is encouraged (not required, like it is in Python)鼓励为每个嵌套级别使用2个空格的缩进(不是必需的,就像在Python中一样)
  • No curly braces {} are used, and the end keyword is used to mark the end of a flow control block

    不使用花括号{} ,并且使用end关键字标记流控制块的结尾

  • To comment, we use the # symbol

    要发表评论,我们使用#符号

The way objects are created in Ruby is by calling a new method on a class, as in the example below:

在Ruby中创建对象的方式是通过在类上调用方法,如以下示例所示:

class Car  def initialize(name, color)    @name = name    @color = color  end
def get_info    "Name: #{@name}, and Color: #{@color}"  endend
my_car = Car.new("Fiat", "Red")puts my_car.get_info

To understand what’s going on in the code above:

要了解上面的代码中发生了什么:

  • We have a class named Car with two methods, initialize and get_info.

    我们有一个名为Car的类,具有两个方法, initializeget_info

  • Instance variables in Ruby begin with @ (For example @name). The interesting part is that the variables are not initially declared. They spring into existence when first used, and after that they are available to all instance methods of the class.

    Ruby中的实例变量以@开头(例如@name )。 有趣的是,变量最初并未声明。 它们在首次使用时就存在,然后可用于该类的所有实例方法。

  • Calling the new method causes the initialize method to invoke. initialize is a special method which is used as a constructor.

    调用new方法将导致initialize方法被调用。 initialize是一种特殊的方法,用作构造函数。

存取资料 (Accessing Data)

Instance variables are private and can’t be accessed from outside the class. In order to access them, we need to create methods. Instance methods have public access by default. We can limit the access to these instance methods as we will see later in this article.

实例变量是私有的,不能从类外部访问。 为了访问它们,我们需要创建方法。 实例方法默认情况下具有公共访问权限。 我们可以限制对这些实例方法的访问,我们将在本文后面看到。

In order to get and modify the data, we need “getter” and “setter” methods, respectively. Let’s look at these methods taking the same example of a car.

为了获取和修改数据,我们分别需要“ getter”和“ setter”方法。 让我们以汽车为例来看看这些方法。

class Car  def initialize(name, color) # "Constructor"    @name = name    @color = color  end
def color    @color  end
def color= (new_color)    @color = new_color  endend
my_car = Car.new("Fiat", "Red")puts my_car.color # Red
my_car.color = "White"puts my_car.color # White

In Ruby, the “getter” and the “setter” are defined with the same name as the instance variable that we are dealing with.

在Ruby中,“ getter”和“ setter”的定义与我们要处理的实例变量的名称相同。

In the example above, when we say my_car.color, it actually calls the color method which in turn returns the name of the color.

在上面的示例中,当我们说my_car.color ,它实际上调用了color方法,该方法又返回颜色的名称。

Note: Pay attention to how Ruby allows a space between the color and equals to sign while using the setter, even though the method name is color=

注意: 使用方法时,即使方法名称为 color= ,也要 注意Ruby如何在 color equals 之间留出一个空格 以进行符号签名

Writing these getter/setter methods allow us to have more control. But most of the time, getting the existing value and setting a new value is simple. So, there should be an easier way instead of actually defining getter/setter methods.

编写这些getter / setter方法可以使我们拥有更多的控制权。 但是在大多数情况下,获取现有值并设置新值很简单。 因此,应该有一种比实际定义getter / setter方法更简单的方法。

更简单的方法 (The easier way)

By using the attr_* form instead, we can get the existing value and set a new value.

通过使用attr_*形式,我们可以获取现有值并设置一个新值。

  • attr_accessor: for getter and setter both

    attr_accessor :用于getter和setter两者

  • attr_reader: for getter only

    attr_reader :仅用于getter

  • attr_writer: for setter only

    attr_writer :仅适用于二传手

Let’s look at this form taking the same example of a car.

让我们以汽车的相同示例来看一下这种形式。

class Car  attr_accessor :name, :colorend
car1 = Car.newputs car1.name # => nil
car1.name = "Suzuki"car1.color = "Gray"puts car1.color # => Gray
car1.name = "Fiat"puts car1.name # => Fiat

This way we can skip the getter/setter definitions altogether.

这样,我们可以完全跳过getter / setter定义。

谈论最佳做法 (Talking about best practices)

In the example above, we didn’t initialize the values for the @name and @color instance variables, which is not a good practice. Also, as the instance variables are set to nil, the object car1 doesn’t make any sense. It’s always a good practice to set instance variables using a constructor as in the example below.

在上面的示例中,我们没有初始化@name@color实例变量的值,这不是一个好习惯。 另外,由于实例变量设置为nil,所以对象car1没有任何意义。 最好使用构造函数设置实例变量,如下例所示。

class Car  attr_accessor :name, :color    def initialize(name, color)    @name = name    @color = color  endend
car1 = Car.new("Suzuki", "Gray")puts car1.color # => Gray
car1.name = "Fiat"puts car1.name # => Fiat

类方法和类变量 (Class Methods and Class Variables)

So class methods are invoked on a class, not on an instance of a class. These are similar to static methods in Java.

因此,类方法是在类上而不是在类的实例上调用的。 这些类似于Java中的静态方法。

Note: self outside of the method definition refers to the class object. Class variables begin with @@

注意:方法定义之外的self引用类对象。 类变量以@@开头

Now, there are actually three ways to define class methods in Ruby:

现在,实际上有三种方法可以在Ruby中定义类方法:

在类定义内 (Inside the class definition)

  1. Using the keyword self with the name of the method:将关键字self与方法名称一起使用:
class MathFunctions  def self.two_times(num)    num * 2  endend
# No instance createdputs MathFunctions.two_times(10) # => 20

2. Using <<; self

2.使用<< ; 自

class MathFunctions  class << self    def two_times(num)      num * 2    end  endend
# No instance createdputs MathFunctions.two_times(10) # =&gt; 20

课外定义 (Outside the class definition)

3. Using class name with the method name

3.使用类名和方法名

class MathFunctionsend
def MathFunctions.two_times(num)  num * 2end
# No instance createdputs MathFunctions.two_times(10) # =&gt; 20

类继承 (Class Inheritance)

In Ruby, every class implicitly inherits from the Object class. Let’s look at an example.

在Ruby中,每个类都隐式继承自Object类。 让我们来看一个例子。

class Car  def to_s    "Car"  end
def speed    "Top speed 100"  endend
class SuperCar < Car  def speed # Override    "Top speed 200"  endend
car = Car.newfast_car = SuperCar.new
puts "#{car}1 #{car.speed}" # =&gt; Car1 Top speed 100puts "#{fast_car}2 #{fast_car.speed}" # => Car2 Top speed 200

In the above example, the SuperCar class overrides the speed method which is inherited from the Car class. The symbol &lt; denotes inheritance.

在上面的示例中, SuperCar类覆盖了从Car类继承的speed方法。 符号& lt; 表示继承。

Note: Ruby doesn’t support multiple inheritance, and so mix-ins are used instead. We will discuss them later in this article.

注意:Ruby不支持多重继承,因此使用混入。 我们将在本文后面讨论它们。

Ruby中的模块 (Modules in Ruby)

A Ruby module is an important part of the Ruby programming language. It’s a major object-oriented feature of the language and supports multiple inheritance indirectly.

Ruby模块是Ruby编程语言的重要组成部分。 它是该语言的主要面向对象功能,并间接支持多重继承。

A module is a container for classes, methods, constants, or even other modules. Like a class, a module cannot be instantiated, but serves two main purposes:

模块是类,方法,常量甚至其他模块的容器。 像类一样,模块无法实例化,但是有两个主要目的:

  • Namespace命名空间
  • Mix-in混入

模块作为命名空间 (Modules as Namespace)

A lot of languages like Java have the idea of the package structure, just to avoid collision between two classes. Let’s look into an example to understand how it works.

许多语言(例如Java)都具有包结构的思想,只是为了避免两个类之间的冲突。 让我们看一个例子来了解它是如何工作的。

module Patterns  class Match    attr_accessor :matched  endend
module Sports  class Match    attr_accessor :score  endend
match1 = Patterns::Match.newmatch1.matched = "true"
match2 = Sports::Match.newmatch2.score = 210

In the example above, as we have two classes named Match, we can differentiate between them and prevent collision by simply encapsulating them into different modules.

在上面的示例中,由于我们有两个名为Match类,我们可以通过将它们封装到不同的模块中来区分它们并防止冲突。

模块作为混入 (Modules as Mix-in)

In the object-oriented paradigm, we have the concept of Interfaces. Mix-in provides a way to share code between multiple classes. Not only that, we can also include the built-in modules like Enumerable and make our task much easier. Let’s see an example.

在面向对象的范例中,我们有接口的概念。 混合提供了一种在多个类之间共享代码的方法。 不仅如此,我们还可以包括诸如Enumerable类的内置模块,使我们的工作更加轻松。 让我们来看一个例子。

module PrintName  attr_accessor :name  def print_it    puts "Name: #{@name}"  endend
class Person  include PrintNameend
class Organization  include PrintNameend
person = Person.newperson.name = "Nishant"puts person.print_it # =&gt; Name: Nishant
organization = Organization.neworganization.name = "freeCodeCamp"puts organization.print_it # =&gt; Name: freeCodeCamp

Mix-ins are extremely powerful, as we only write the code once and can then include them anywhere as required.

混合功能非常强大,因为我们只编写一次代码,然后可以根据需要在任何地方包含它们。

Ruby中的范围 (Scope in Ruby)

We will see how scope works for:

我们将看到范围如何工作:

  • variables变数
  • constants常数
  • blocks块

变量范围 (Scope of variables)

Methods and classes define a new scope for variables, and outer scope variables are not carried over to the inner scope. Let’s see what this means.

方法和类为变量定义了新的作用域,并且外部作用域变量不会继承到内部作用域。 让我们看看这意味着什么。

name = "Nishant"
class MyClass  def my_fun    name = "John"    puts name # =&gt; John  end
puts name # =&gt; Nishant

The outer name variable and the inner name variable are not the same. The outer name variable doesn’t get carried over to the inner scope. That means if you try to print it in the inner scope without again defining it, an exception would be thrown — no such variable exists

外部name变量和内部name变量不同。 外部name变量不会继承到内部范围。 这意味着,如果您尝试在内部范围中打印它而不再次定义它,则将引发异常- 不存在此类变量

常数范围 (Scope of constants)

An inner scope can see constants defined in the outer scope and can also override the outer constants. But it’s important to remember that even after overriding the constant value in the inner scope, the value in the outer scope remains unchanged. Let’s see it in action.

内部作用域可以看到在外部作用域中定义的常量,也可以覆盖外部常量。 但重要的是要记住,即使在覆盖内部作用域中的常量值之后,外部作用域中的值仍保持不变。 让我们来看看它的作用。

module MyModule  PI = 3.14  class MyClass    def value_of_pi      puts PI # =&gt; 3.14      PI = "3.144444"      puts PI # => 3.144444    end  end  puts PI # =&gt; 3.14end

块的范围 (Scope of blocks)

Blocks inherit the outer scope. Let’s understand it using a fantastic example I found on the internet.

块继承外部范围。 让我们用我在互联网上找到的一个很棒的例子来理解它。

class BankAccount  attr_accessor :id, :amount  def initialize(id, amount)    @id = id    @amount = amount  endend
acct1 = BankAccount.new(213, 300)acct2 = BankAccount.new(22, 100)acct3 = BankAccount.new(222, 500)
accts = [acct1, acct2, acct3]
total_sum = 0accts.each do |eachAcct|  total_sum = total_sum + eachAcct.amountend
puts total_sum # =&gt; 900

In the above example, if we use a method to calculate the total_sum, the total_sum variable would be a totally different variable inside the method. That’s why sometimes using blocks can save us a lot of time.

在上面的示例中,如果我们使用一种方法来计算total_sum ,则total_sum变量将是该方法内部的完全不同的变量。 这就是为什么有时使用块可以节省大量时间的原因。

Having said that, a variable created inside the block is only available to the block.

话虽如此,在块内部创建的变量仅对块可用。

访问控制 (Access Control)

When designing a class, it is important to think about how much of it you’ll be exposing to the world. This is known as Encapsulation, and typically means hiding the internal representation of the object.

设计课程时,重要的是要考虑要向世界展示多少课程。 这就是所谓的封装,通常意味着隐藏对象的内部表示。

There are three levels of access control in Ruby:

Ruby中的访问控制分为三个级别:

  • Public - no access control is enforced. Anybody can call these methods.

    公开 -不执行访问控制。 任何人都可以调用这些方法。

  • Protected - can be invoked by objects of the defining classes or its sub classes.

    受保护的 -可以由定义类或其子类的对象调用。

  • Private - cannot be invoked except with an explicit receiver.

    专用 -除非使用显式接收者,否则不能调用。

Let’s see an example of Encapsulation in action:

让我们看一个封装实际的例子:

class Car  def initialize(speed, fuel_eco)    @rating = speed * comfort  end
def rating    @rating  endend
puts Car.new(100, 5).rating # =&gt; 500

Now, as the details of how the rating is calculated are kept inside the class, we can change it at any point in time without any other change. Also, we cannot set the rating from outside.

现在,由于如何计算评分的详细信息保留在班级内部,因此我们可以随时更改它,而无需进行其他任何更改。 另外,我们不能从外部设置等级。

Talking about the ways to specify access control, there are two of them:

谈到指定访问控制的方法,有两种:

  1. Specifying public, protected, or private and everything until the next access control keyword will have that access control level.指定public,protected或private以及所有内容,直到下一个访问控制关键字将具有该访问控制级别。
  2. Define the method regularly, and then specify public, private, and protected access levels and list the comma(,) separated methods under those levels using method symbols.定期定义方法,然后指定公共,私有和受保护的访问级别,并使用方法符号在这些级别下列出逗号分隔的方法。

第一种方式的示例: (Example of the first way:)

class MyClass  private    def func1      "private"    end  protected    def func2      "protected"    end  public    def func3      "Public"    endend

第二种方式的示例: (Example of the second way:)

class MyClass  def func1    "private"  end  def func2    "protected"  end  def func3    "Public"  end  private :func1  protected :func2  public :func3end

Note: The public and private access controls are used the most.

注意:最常使用公共和私人访问控制。

结论 (Conclusion)

These are the very basics of Object Oriented Programming in Ruby. Now, knowing these concepts you can go deeper and learn them by building cool stuff.

这些是Ruby中面向对象编程的基础知识。 现在,了解了这些概念后,您可以通过构建有趣的东西来更深入地学习它们。

Don’t forget to clap and follow if you enjoyed! Keep up with me here.

如果您喜欢的话,别忘了拍手并跟随! 在这里跟上我。

翻译自: https://www.freecodecamp.org/news/an-introduction-to-object-oriented-programming-with-ruby-73531e2b8ddc/

ruby 新建对象

ruby 新建对象_Ruby面向对象编程简介相关推荐

  1. ruby 新建对象_Ruby面向对象编程的简介

    ruby 新建对象 by Saul Costa 由Saul Costa Object-oriented programming (OOP) is a programming paradigm orga ...

  2. ruby 新建对象_Ruby中的面向对象编程

    ruby 新建对象 Before getting into understanding how Object-oriented programming is implemented in Ruby, ...

  3. 基于对象和面向对象编程范式辨析和主流编程语言中的应用

    基于对象和面向对象编程范式辨析和主流编程语言中的应用 前言 本文的目的是想告诉大家,为什么C++的模板这么强大.为什么Ruby的Duck Typing(像鸭子那样编程)这么强大! 基于对象和面向对象编 ...

  4. 允许使用抽象类类型 isearchboxinfo 的对象_Java面向对象编程三大特征 - 多态

    Java面向对象编程三大特征 - 多态 本文关键字:Java.面向对象.三大特征.多态 多态是面向对象编程的三大特征之一,是面向对象思想的终极体现之一.在理解多态之前需要先掌握继承.重写.父类引用指向 ...

  5. python学习之路-第七天-python面向对象编程简介

    面向对象编程 在python中,同样是类和对象作为重要的组成部分. 而且在python中基本数据类型如int都是有封装类的,都有自己的方法,应该是和java里面的Integer类似吧 类包括域和方法: ...

  6. [Python]小甲鱼Python视频第037课(类和对象:面向对象编程 )课后题及参考解答

    # -*- coding: utf-8 -*- """ Created on Mon Mar 11 20:09:54 2019@author: Administrator ...

  7. MATLAB面向对象编程简介

    Object-oriented programming(面向对象编程)应用于软件开发过程中,它是建立在对事物科 学分类和描述基础上的编程方法.采用面向对象方法可以使系统各部分各司其职.各尽所能.为编程 ...

  8. 课时37:类与对象:面向对象编程

    目录: 一.self是什么 二.Python的魔法方法 三.公有和私有 四.课时37课后习题及答案 ***************** 一.self是什么 ***************** 对象的方 ...

  9. 8.2.2继承 第8章 面向对象编程简介

    继承是OOP最重要的特性之一.  OOP--面向对象 任何类都可以从另一个类中继承,这就是说,这个类拥有它继承的类的所有成员.在OOP中,被继承(继承也称为派生)的类称为父类(也称为基类).注意,C# ...

最新文章

  1. U3D 通过预置对象实现手动创建精灵
  2. 使用LiveNVR实现将RTSP转RTMP、FLV、HLS,实现监控摄像头无插件直播
  3. 小企业文件打印服务器,小企业云服务器方案
  4. 别人要访问我的电脑上部署的tomcat,必须关闭防火墙吗?
  5. POS机刷卡机招商加盟企业网站源码
  6. CentOS7安装 MySQL主从集群
  7. BZOJ 1734: [Usaco2005 feb]Aggressive cows 愤怒的牛( 二分答案 )
  8. C语言为运算表达式添加括号,读书笔记-c语言-运算符与表达式
  9. 【持续更新】Java序列化对象释疑
  10. 数据库查询-模糊查询
  11. nexus-3.37.3 报INSTALL4J_JAVA_HOME to point to a suitable JVM
  12. Spring Security的工作原理
  13. 安卓手机使用VNET抓包京东wskey
  14. To Kill a Mockingbird(杀死一只反舌鸟)简记
  15. 本地php开发环境出现 cURL error 60
  16. SQL INSERT INTO的用法
  17. ionic3生产打包javascript内存溢出的解决方法
  18. 唐骏解禁回IT:十年之内不跳槽
  19. 朋友.心情父子.亲情
  20. 案桌 常见 弹框 学习笔记

热门文章

  1. TreeView节点的演练 c# 1614840318
  2. Scanner的用法强化
  3. 数据结构与算法-时间复杂度
  4. python-演练-数据排除-从学生得分中去除题目源中并不存在的题
  5. jquery-绑定事件与解除事件的绑定
  6. 企业级 SpringCloud 教程 (七) 高可用的分布式配置中心(Spring Cloud Config)
  7. IP和网段及子网掩码基础知识
  8. [转]双线性插值(Bilinear interpolation)
  9. Mysql的那些事儿(部分涉及数据库知识总结)
  10. Vantage公司增资3亿美元加强数据中心建设