欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2023-12-26 17:29:27
...

ruby 新建对象

by Saul Costa

由Saul Costa

Object-oriented programming (OOP) is a programming paradigm organized around objects. At a high level, OOP is all about being able to structure code so that its functionality can be shared throughout the application. If done properly, OOP can lead to very elegantly written programs that have minimal code duplication.

面向对象编程 ( OOP )是围绕对象组织的编程范例。 总体而言,OOP就是能够构造代码,以便其功能可以在整个应用程序*享。 如果操作正确,OOP可以导致编写的程序非常优美,代码重复最少。

This is opposed to procedural programming (PP), in which you build programs in sequential order and call methods when you want shared behavior between pages in the application. Common procedural programming languages include C and Go.

这与过程编程(PP)相反,在过程编程中,您要按顺序构建程序并在需要应用程序页面之间的共享行为时调用方法。 常见的过程编程语言包括CGo

In this tutorial, you’ll learn the fundamental concepts of OOP for Ruby, an object-oriented programming language wherein everything is an object. We will be using Ruby since one of its defining attributes — in addition to its elegant syntax and readability — is how it implements OOP techniques. This makes it a great language to start learning OOP with.

在本教程中,您将学习面向Ruby的OOP的基本概念, Ruby是一种面向对象的编程语言,其中的一切都是对象。 我们将使用Ruby,因为它的定义属性之一-除了其优雅的语法和可读性-还是实现OOP技术的方式。 这使它成为开始学习OOP的绝佳语言。

We will cover:

我们将介绍:

  • Creating classes

    建立课程
  • Instantiating objects

    实例化对象
  • Initializing arguments

    初始化参数
  • Working with inheritance, and

    处理继承,以及
  • Private and public methods.

    私人和公共方法。

In learning these concepts, we will build out our own application: an API connector that communicates dynamically with an application that sends a text message. This will include walking through how to leverage concepts such as inheritance and object instantiation to make our code more scalable and reusable!

在学习这些概念时,我们将构建自己的应用程序:与发送文本消息的应用程序动态通信的API连接器。 这将包括逐步讲解如何利用诸如继承和对象实例化之类的概念来使我们的代码更具可伸缩性和可重用性!

This brief tutorial is adapted from Next Tech’s Introduction to Ruby course, which includes an in-browser sandboxed environment and auto-checked interactive tasks to complete.

本简短的教程改编自Next Tech的Ruby入门课程 ,其中包括一个浏览器内的沙盒环境和自动检查要完成的交互式任务。

You can follow along with the code snippets in this tutorial using Next Tech’s sandbox which already has Ruby pre-installed. If you chose to use your own IDE, make sure Ruby is installed by following the instructions on the installation page.

您可以使用已经预先安装了Ruby的Next Tech的沙箱来跟随本教程中的代码段。 如果您选择使用自己的IDE,请按照安装页面上的说明确保已安装Ruby。

创建课程 (Creating Classes)

Before we begin, let’s define what an object is. At its core, an object is a self-contained piece of code that contains data (“attributes”) and behavior (“methods”) and can communicate with other objects. Objects of the same type are created from classes, which act as blueprints that define properties and behavior.

在开始之前,让我们定义一个对象是什么。 对象的核心是一个独立的代码段,其中包含数据(“属性”)和行为(“方法”),并且可以与其他对象进行通信。 相同类型的对象是从创建的,这些充当定义属性和行为的蓝图。

Creating a class in Ruby is fairly easy. To define a class, simply type the class word followed by the name of the class, and end it with the end word. Anything contained between class and end belongs to this class.

在Ruby中创建类非常容易。 要定义一个类,只需键入class词,然后输入class名,然后以endendclassend之间包含的所有内容都属于该类。

Class names in Ruby have a very specific style requirement. They need to start with a letter and if they represent multiple words, each new word needs also to be an uppercase letter — i.e. “CamelCase”.

Ruby中的类名称具有非常特定的样式要求。 他们需要以一个字母开头,如果它们代表多个单词,则每个新单词也必须是一个大写字母,即“ CamelCase”。

We’ll start by creating a class called ApiConnector:

我们将从创建一个名为ApiConnector的类ApiConnector

Classes in Ruby can store both data and methods. In many traditional OOP languages such as Java, you need to create two methods for each data element you want to be included in the class. One method, the setter, sets the value in the class. The other method, the getter, allows you to retrieve the value.

Ruby中的类可以存储数据和方法。 在许多传统的OOP语言(例如Java)中,您需要为要包含在类中的每个数据元素创建两个方法。 一种方法是setter ,它在类中设置值。 另一个方法getter允许您检索值。

The process of creating setter and getter methods for every data attribute can be tiresome and leads to incredibly long class definitions. Thankfully Ruby has a set of tools called attribute accessors.

为每个数据属性创建setter和getter方法的过程可能很麻烦,并且会导致难以置信的长类定义。 幸运的是,Ruby有一套称为属性访问器的工具。

Let’s implement some setters and getters for some new data elements for our class. Since it’s an API connector, it would make sense to have data elements such as title, description, and url. We can add these elements with the following code:

让我们为类中的一些新数据元素实现一些setter和getter。 由于它是API连接器,因此具有诸如titledescriptionurl类的数据元素会很有意义。 我们可以使用以下代码添加这些元素:

When you merely create a class, it doesn’t do anything — it is simply a definition. In order to work with the class, we need to create an instance of it…we’ll cover that next!

当您仅创建一个类时,它什么也没做-只是一个定义。 为了使用该类,我们需要创建它的一个实例……我们将在接下来的内容中介绍!

实例化 (Instantiation)

To understand what instantiation is, let’s consider a real-world analogy. Let’s imagine that you’re building a house. The first task is to build a blueprint for the house. This blueprint would contain attributes and features of the house, such as the dimensions for each room, how the plumbing will flow, and so on.

要了解什么是实例化 ,让我们考虑一个现实世界的类比。 假设您正在盖房子。 第一项任务是为房屋建造蓝图。 该蓝图将包含房屋的属性和特征,例如每个房间的尺寸,管道的流动方式等等。

Is the blueprint of the house the actual house? Of course not, it simply lists out the attributes and design elements for how the home will be created. So after the blueprint is completed, the actual home can be built — or, “instantiated”.

房子的蓝图是真实的房子吗? 当然不是,它只是列出了如何创建房屋的属性和设计元素。 因此,在完成蓝图之后,便可以建造实际房屋或“实例化”。

As explained in the previous section, in OOP, a class is the blueprint for an object. It simply describes what an object will look like and how it will behave. Therefore, instantiation is the process of taking a class definition and creating an object that you can use in a program.

如上一节所述,在OOP中,类是对象的蓝图。 它仅描述对象的外观以及其行为。 因此,实例化是获取类定义并创建可以在程序中使用的对象的过程。

Let’s create a new instance of our ApiConnector class and store it in a variable called api:

让我们为ApiConnector类创建一个新实例,并将其存储在一个名为api的变量中:

Now that we have an object created, we can use the api variable to work with the class attributes. For example, we can run the code:

现在我们已经创建了一个对象,我们可以使用api变量来处理类属性。 例如,我们可以运行代码:

[Out:]https://next.tech

In addition to creating attributes, you can also create methods within a class:

除了创建属性,您还可以在类中创建方法:

To access this method, we can use the same syntax that we utilized with the attribute accessors:

要访问此方法,我们可以使用与属性访问器相同的语法:

Putting this all together, running the full class code below will result in the url and the test_method message to be printed:

将所有内容放在一起,运行下面的完整类代码,将显示urltest_method消息:

[Out:]"https://next.tech""testing class call"

初始化方法 (Initializer Method)

One thing you may find handy in Ruby development is the ability to create an initializer method. This is simply a method called initialize that will run every time when you create an instance of your class. In this method, you can give values to your variables, call other methods, and do just about anything that you think should happen when a new instance of that class is created.

在Ruby开发中,您可能会发现方便的一件事是创建初始化方法的能力。 这只是一个名为initialize的方法,它将在您创建类的实例时每次运行。 在此方法中,您可以为变量赋值,调用其他方法,并执行创建该类的新实例时可能发生的几乎所有事情。

Let’s update our ApiConnector to utilize an initializer method:

让我们更新我们的ApiConnector以利用初始化方法:

Within the initialize method, we created an instance variable for each of the parameters so that we can use these variables in other parts of the application as well.

initialize方法中,我们为每个参数创建了一个实例变量,以便我们也可以在应用程序的其他部分中使用这些变量。

We also removed the attr_accessor method since the new initialize method will take care of this for us. If you need the ability to call the data elements outside of the class, then you would still need to have the attr_accessor call in place.

我们还删除了attr_accessor方法,因为新的initialize方法将为我们解决此问题。 如果需要在类之外调用数据元素的能力,则仍然需要对attr_accessor调用。

To test if the initialize method is working, let’s create another method within the class that prints these values out:

为了测试initialize方法是否正常工作,让我们在类中创建另一个方法来打印这些值:

Finally, we’ll instantiate the class and test the initialize method:

最后,我们将实例化该类并测试initialize方法:

[Out:]"My title""My cool description""https://next.tech"

使用可选值 (Working with optional values)

Now, what happens when we want to make one of these values optional? For example, what if we want to give a default value to the URL? To do that, we can update our initialize method with the following syntax:

现在,当我们要使这些值之一成为可选值时会发生什么? 例如,如果我们要为URL提供默认值怎么办? 为此,我们可以使用以下语法更新我们的initialize方法:

Now our program will have the same output even if we don’t pass the url value while creating a new instance of the class:

现在,即使在创建类的新实例时不传递url值,我们的程序也将具有相同的输出:

使用命名参数 (Using named arguments)

Though this looks simple, passing arguments can get complex in real-world Ruby applications because some methods may take a large number of arguments. In such cases, it becomes difficult to know the order of arguments and what values to assign to them.

尽管这看起来很简单,但是在实际的Ruby应用程序中传递参数可能会变得复杂,因为某些方法可能会使用大量参数。 在这种情况下,很难知道参数的顺序以及要分配给它们的值。

To avoid this confusion, you can utilize named arguments, like this:

为了避免这种混乱,可以使用命名参数,如下所示:

You can enter the arguments without having to look at the order in the initialize method, and even change the order of the arguments without causing an error:

您可以输入参数而不必查看initialize方法的顺序,甚至可以更改参数的顺序而不会引起错误:

覆盖默认值 (Overriding default values)

What happens if we want to override a default value? We simply update our instantiation call like this:

如果我们要覆盖默认值会怎样? 我们只需像这样更新实例化调用:

This update will override our default value of https://next.tech, and calling api.testing_initializer will now print https://next.xyz as the URL.

此更新将覆盖我们的默认值https://next.tech ,并且调用api.testing_initializer现在将打印https://next.xyz作为URL。

遗产 (Inheritance)

Now, we are going to learn about an important object-oriented principle called inheritance. Before going into how it is executed in Ruby, let’s see why it’s important for building applications.

现在,我们将学习一种重要的面向对象的原理,即继承 。 在探讨如何在Ruby中执行它之前,让我们看一下为什么它对于构建应用程序很重要。

To start with, inheritance means your classes can have a hierarchy. It is best used when different classes have some shared responsibilities, since it would be a poor practice to duplicate code in each class for identical or even similar behavior.

首先,继承意味着您的类可以具有层次结构。 最好在不同的类都有共同的责任时使用,因为在每个类中为相同甚至相似的行为复制代码是一种不良做法。

Take our ApiConnector class. Let's say we have different API classes for various platforms, but each class shares a number of common data or processes. Instead of duplicating code in each of the API connector classes, we can have one parent class with the shared data and methods. From there, we can create child classes from this parent class. With the way that inheritance works, each of the child classes will have access to the components provided from the parent class.

参加我们的ApiConnector类。 假设我们为各种平台使用不同的API类,但是每个类共享许多公共数据或流程。 可以在共享的数据和方法中使用一个父类 ,而不是在每个API连接器类中复制代码。 从那里,我们可以从该父类创建类。 通过继承的工作方式,每个子类都可以访问父类提供的组件。

For example, say we have three APIs: SmsConnector, PhoneConnector, and MailerConnector. If we wrote code individually for each of these classes, it would look like this:

例如,假设我们有三个API: SmsConnectorPhoneConnectorMailerConnector 。 如果我们为每个这些类分别编写代码,则看起来像这样:

As you can see, we are simply repeating the same code across different classes. This is considered a poor programming practice that violates the DRY (Don’t Repeat Yourself) principle of development. Instead, we can make an ApiConnector parent class, and each of the other classes can inherit the common functionality from this class:

如您所见,我们只是在不同的类之间重复相同的代码。 这被认为是不良的编程习惯,违反了DRY (请勿重做)开发原则。 相反,我们可以使ApiConnector父类,其他每个类都可以从此类继承通用功能:

By leveraging inheritance, we were able to cut all of the duplicate code throughout our classes.

通过利用继承,我们能够在整个类中剪切所有重复的代码。

The syntax for using inheritance is to define the child class name, followed by the < symbol, then the parent class name — i.e. our SmsConnector, MailerConnector, and PhoneConnector classes inherit from the ApiConnector class .

使用继承的语法是定义子类名称,后跟& lt; 符号,然后是父类的名称- ur SmsConnec r, MailerConnec ur SmsConnecr, MailerConnec tor,以及nd PhoneConnec tor类都继承自he ApiConnec tor类。

Each of these child classes now has access to the full set of elements provided in the parent ApiConnector class. For example, if we create a new instance of SmsConnector with the following parameters, we can call the send_sms method:

这些子类中的每一个现在都可以访问父ApiConnector类中提供的全套元素。 例如,如果我们使用以下参数创建SmsConnector的新实例,则可以调用send_sms方法:

[Out:]Sending SMS message with the title 'Hi there!' and description 'I'm an SMS message'.

A rule of thumb in OOP is to ensure that a class performs a single responsibility. For example, the ApiConnector class should not send SMS messages, make phone calls, or send emails since that would be three core responsibilities.

OOP中的经验法则是确保班级履行单一职责。 例如, ApiConnector类不应发送SMS消息,拨打电话或发送电子邮件,因为这是三个核心职责。

私人和公共方法 (Private and Public Methods)

Before we dive into private and public methods, let’s first go back to our original ApiConnector class and create a SmsConnector class that inherits from ApiConnector. In this class, we will create a method called send_sms that will run a script that contacts an API:

在深入探讨私有和公共方法之前,让我们首先回到原始的ApiConnector类,并创建一个继承自ApiConnectorSmsConnector类。 在此类中,我们将创建一个名为send_sms的方法,该方法将运行与API联系的脚本:

This method will send a title and url to an API, which will in turn send an SMS message. Now we can instantiate the SmsConnector class and call the send_sms message:

此方法将titleurl发送到API,API随后将发送SMS消息。 现在,我们可以实例化SmsConnector类并调用send_sms消息:

Running this code will contact the SMS API and send the message. You can go to the bottom of this page to see your message!

运行此代码将联系SMS API并发送消息。 您可以转到此页面的底部查看您的消息!

Now, using this example, let’s discuss the types of methods provided by classes.

现在,使用此示例,让我们讨论类提供的方法的类型。

The send_sms method is a public method. This means that anyone working on our class can communicate with this method. This may not seem like a big deal if you are working on an application that no one else is working on. However, if you build an API or code library that is open sourced for others to use, it's vital that your public methods represent elements of functionality that you actually want other developers to use.

send_sms方法是一个公共方法 。 这意味着在我们班上工作的任何人都可以与此方法进行通讯。 如果您正在开发一个其他人都没有从事的应用程序,那么这似乎没什么大不了的。 但是,如果您构建开放给其他人使用的API或代码库,那么公共方法代表您实际上希望其他开发人员使用的功能元素至关重要。

Public methods should rarely, if ever, be altered. This is because other developers may be relying on your public methods to be consistent, and a change to a public method may break components of their programs.

公共方法很少(如果有的话)应该改变。 这是因为其他开发人员可能依赖于您的公共方法来保持一致,并且对公共方法的更改可能会破坏其程序的组件。

So, if you can’t change public methods, how can you work on a production application? That’s where private methods come in. A private method is a method that is only accessed by the class that it is contained in. It should never be called by outside services. This means that you can alter their behavior, assuming that these changes don’t have a domino effect and alter the public methods that they may be called from.

因此,如果您不能更改公共方法,那么如何在生产应用程序上工作? 这就是私有方法的用处。私有方法是只能由其所包含的类访问的方法。永远不要由外部服务调用它。 这意味着您可以更改它们的行为,假设这些更改没有多米诺骨牌效应,并更改可以从中调用它们的公共方法。

Usually private methods are placed at the end of the file after all the public methods. To designate private methods, we use the private word above the list of methods. Let’s add a private method to our ApiConnector class:

通常,私有方法放在所有公共方法之后的文件末尾。 要指定私有方法,我们在方法列表上方使用private词。 让我们向ApiConnector类添加一个私有方法:

Notice how we’re calling this method from the inside of the initialize method of the ApiConnector class? If we run this code, it will give the following output:

请注意,我们如何从ApiConnector类的initialize方法内部调用此方法? 如果我们运行此代码,它将给出以下输出:

[Out:]A secret message from the parent class

Now child classes have access to methods in the parent class, right? Well, not always. Let’s remove the secret_method method from the initialize method in ApiConnector and try to call it from our SmsConnector child class, as shown here:

现在子类可以访问父类中的方法了,对吗? 好吧,并非总是如此。 让我们去掉secret_method从方法initialize的方法ApiConnector并尝试从我们叫它SmsConnector子类,如下所示:

[Out:]Traceback (most recent call last):main.rb:29:in `<main>': private method `secret_method' called for #SmsConnector:0x000056188cfe19b0> (NoMethodError)

This is because the SmsConnector class only has access to the public methods from the parent class. The private methods are, by their nature, private. This means that they can only be accessed by the class that they are defined in.

这是因为SmsConnector类只能从父类访问公共方法。 从本质上说,私有方法是私有的。 这意味着只能由定义它们的类访问它们。

So a good rule of thumb is to create private methods when they should not be used outside the class and public methods when they have to be available throughout the application or used by outside services.

因此,一个好的经验法则是,在不应在类外使用私有方法时创建私有方法,而在整个应用程序中必须使用私有方法或由外部服务使用它们时则创建公共方法。

结语 (Wrapping up)

I hope you enjoyed this quick tutorial on the fundamental concepts of object-oriented programming in Ruby! We covered creating classes, attribute accessors, instantiation, initialization, inheritance, and private and public methods.

我希望您喜欢这个关于Ruby中面向对象编程的基本概念的快速教程! 我们介绍了创建类,属性访问器,实例化,初始化,继承以及私有和公共方法。

Ruby is a powerful object-oriented language used by popular applications, including our own here at Next Tech. With this foundational knowledge of OOP, you’re well on your way to developing your own Ruby apps!

Ruby是一种流行的应用程序使用的强大的面向对象语言,包括我们在Next Tech中使用的语言。 有了OOP的基础知识,您就可以很好地开发自己的Ruby应用程序!

If you’re interested in learning more about programming with Ruby, check out our Introduction to Ruby course here! In this course we cover core programming skills, such as variables, strings, loops, and conditionals, more advanced OOP topics, and error handling.

如果您有兴趣学习有关使用Ruby编程的更多信息,请在此处查看我们的Ruby入门课程! 在本课程中,我们涵盖了核心编程技能,例如变量,字符串,循环和条件,更高级的OOP主题以及错误处理。

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

ruby 新建对象

上一篇:

下一篇: