diff --git a/modules/40-methods-definition/100-method-definition-static/en/EXERCISE.md b/modules/40-methods-definition/100-method-definition-static/en/EXERCISE.md new file mode 100644 index 00000000..69f82445 --- /dev/null +++ b/modules/40-methods-definition/100-method-definition-static/en/EXERCISE.md @@ -0,0 +1,11 @@ + +Implement a static method named `printMotto()` that prints the phrase *Winter is coming* to the screen. + +```java +// The App class is already defined +App.printMotto(); // => Winter is coming +``` + +So that we can call this method from outside, it has to be marked not only with the `static` keyword, but also with `public`. + +In exercises where you need to implement a method, you do not need to call that method. The method will be called by the automated tests that check whether it works. The example with the call above is shown only so that you understand how your method will be used. diff --git a/modules/40-methods-definition/100-method-definition-static/en/README.md b/modules/40-methods-definition/100-method-definition-static/en/README.md new file mode 100644 index 00000000..e0da7bd8 --- /dev/null +++ b/modules/40-methods-definition/100-method-definition-static/en/README.md @@ -0,0 +1,105 @@ +Defining your own methods makes writing and maintaining programs much easier. For example, methods let you combine compound operations into one. + +Sending an email from a site is a complex process that includes interaction with the internet. You can define a method and hide all that complexity behind one short construct: + +```java +// The place the method comes from +import com.example.Mailer; + +var email = "support@hexlet.io"; +var title = "Help"; +var body = "I have written a success story, how can I get a discount?"; + +// Mailer is the name of the class in which the send() method is defined +// One small call — and a lot of logic inside +Mailer.send(email, title, body); +``` + +Inside, a call like this performs quite a lot of logic. It connects to the mail server, forms the correct request based on the subject and the body of the message, and then sends it all, without forgetting to close the connection. + +## How to create methods + +Let's create our first method. Its task is to print the current date to the screen: + +```text +Today is: 2021-10-25 +``` + +```java +import java.time.LocalDate; + +// Defining the method +// The definition does not call or execute the method +// We only say that such a method now exists +public class App { + public static void showCurrentDate() { + // A built-in Java method for getting the current time and date + var currentDate = LocalDate.now(); + var text = "Today is: " + currentDate; + System.out.println(text); + } +} + +// Calling the method +// Specifying the class name is required +App.showCurrentDate(); // => Today is: 2021-10-25 +``` + +Let's look at the method signature part by part: + +```text +public static void showCurrentDate() + │ │ │ │ + │ │ │ the method name and the list of parameters in parentheses + │ │ the type of the returned value + │ static — the method is called directly from the class + the visibility of the method outside the class +``` + +Defining a method in Java includes many things that we will cover step by step. + +They can be divided into two groups: + +* What affects the work of the method itself +* How this method is visible outside the class + +Visibility is handled by the word *public*. It makes it possible to call methods from outside the class, as in the example above. Besides it, there is *private*, which is covered at Hexlet in the [Java OOP](https://ru.hexlet.io/programs/java?utm_source=code-basics&utm_medium=referral&utm_campaign=programs&utm_content=lesson) course. + +The work of the method is handled by: + +* *static* — detaches the method from an object and makes it possible to call it directly from the class +* *void* is used if the method returns nothing. For example, this is the definition of the `System.out.println()` method. If the method returns some data, then the type of the returned data is specified instead of *void* + +Unlike ordinary data, methods perform actions, so their names should almost always be verbs: "build something", "draw something", "open something". + +Everything described inside the curly braces `{}` is called the **method body**. Any code can be written inside the body. Consider it a small independent program, a set of arbitrary instructions. + +The body is executed exactly at the moment the method is launched. Moreover, each call of the method runs the body independently of the other calls. By the way, the body can be empty: + +```java +// The minimal definition of a method +public class App { + public static void noop() { + // There could be code here, but there is none + // Pay attention to the indentation + // For readability, any code inside the body is shifted 4 spaces to the right + } +} +App.noop(); +``` + +The notion of "creating a method" has many synonyms: "implementing", "defining", and even "coding it up". All these terms are found in everyday practice at work. + +## Reuse and readability + +Methods help avoid duplication. Suppose the same set of actions appears several times in a program: + +```java +System.out.println("Hello, Hexlet!"); +System.out.println("Hello, world!"); +System.out.println("Hello, Java!"); +``` + +Such a pattern can be gathered into one method and called in different places. When the text needs to be changed, the fix is made in one place — in the definition of the method. The bigger the project and the more often the logic repeats, the more noticeable the gain. + +The name of the method itself hints at what it does. The `showCurrentDate()` method tells about its task without additional comments. This helps other programmers read the code, and also helps you yourself a month after writing it. diff --git a/modules/40-methods-definition/100-method-definition-static/en/data.yml b/modules/40-methods-definition/100-method-definition-static/en/data.yml new file mode 100644 index 00000000..53a87a19 --- /dev/null +++ b/modules/40-methods-definition/100-method-definition-static/en/data.yml @@ -0,0 +1,6 @@ +--- +name: Creating (defining) a method +tips: + - > + [Naming in + programming](https://ru.hexlet.io/blog/posts/naming-in-programming?utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson) diff --git a/modules/40-methods-definition/100-method-definition-static/es/README.md b/modules/40-methods-definition/100-method-definition-static/es/README.md index 1b3c4796..7d318f54 100644 --- a/modules/40-methods-definition/100-method-definition-static/es/README.md +++ b/modules/40-methods-definition/100-method-definition-static/es/README.md @@ -1,28 +1,28 @@ -La definición de métodos propios simplifica en gran medida la escritura y el mantenimiento de programas. Por ejemplo, los métodos permiten combinar operaciones compuestas en una sola. +La definición de métodos propios simplifica en gran medida la escritura y el mantenimiento de los programas. Por ejemplo, los métodos permiten combinar operaciones compuestas en una sola. -Por ejemplo, enviar un correo electrónico en un sitio web es un proceso bastante complejo que implica interactuar con Internet. Se puede definir un método y ocultar toda la complejidad detrás de una sola construcción simple: +Enviar un correo desde un sitio web es un proceso complejo que incluye la interacción con internet. Se puede definir un método y ocultar toda esa complejidad detrás de una construcción corta: ```java -// Lugar donde se encuentra el método +// El lugar de donde se toma el método import com.example.Mailer; var email = "support@hexlet.io"; var title = "Ayuda"; var body = "He escrito una historia de éxito, ¿cómo puedo obtener un descuento?"; -// Mailer - nombre de la clase en la que se define el método send() -// Una pequeña llamada - y mucha lógica interna +// Mailer es el nombre de la clase en la que está definido el método send() +// Una llamada pequeña, y mucha lógica dentro Mailer.send(email, title, body); ``` -Este tipo de llamada realiza bastante lógica interna. Se conecta al servidor de correo, forma una solicitud correcta basada en el encabezado y el cuerpo del mensaje, y luego lo envía todo, sin olvidar cerrar la conexión. +Por dentro, una llamada como esta ejecuta bastante lógica. Se conecta al servidor de correo, forma la petición correcta a partir del asunto y del cuerpo del mensaje, y luego lo envía todo, sin olvidar cerrar la conexión. ## Cómo crear métodos -Crearemos nuestro primer método. Su tarea es mostrar la fecha actual en la pantalla: +Vamos a crear nuestro primer método. Su tarea es mostrar la fecha actual en la pantalla: ```text -Hoy es: 2021-10-25 +Today is: 2021-10-25 ``` ```java @@ -30,51 +30,76 @@ import java.time.LocalDate; // Definición del método // La definición no llama ni ejecuta el método -// Solo estamos diciendo que ahora existe este método +// Solo decimos que ahora ese método existe public class App { public static void showCurrentDate() { - // Método incorporado en Java para obtener la fecha y hora actual + // Método incorporado en Java para obtener la fecha y la hora actuales var currentDate = LocalDate.now(); - var text = "Hoy es: " + currentDate; + var text = "Today is: " + currentDate; System.out.println(text); } } // Llamada al método -// Es obligatorio especificar el nombre de la clase -App.showCurrentDate(); // => Hoy es: 2021-10-25 +// Es obligatorio indicar el nombre de la clase +App.showCurrentDate(); // => Today is: 2021-10-25 ``` -La definición de un método en Java implica muchas acciones que iremos viendo gradualmente. +Veamos la firma del método por partes: + +```text +public static void showCurrentDate() + │ │ │ │ + │ │ │ nombre del método y lista de parámetros entre paréntesis + │ │ tipo del valor devuelto + │ static — el método se llama directamente desde la clase + visibilidad del método fuera de la clase +``` + +La definición de un método en Java incluye muchas cosas que iremos viendo poco a poco. Se pueden dividir en dos grupos: -* Lo que afecta el funcionamiento del propio método -* Cómo se ve este método fuera de la clase +* Lo que afecta al funcionamiento del propio método +* Cómo se ve ese método fuera de la clase -La visibilidad está determinada por la palabra *public*. Esto permite llamar a los métodos desde fuera de la clase, como en el ejemplo anterior. Además de *public*, existe *private*, que se explica en Hexlet en el curso de [POO en Java](https://codica.la/courses/java-poo-basics). +De la visibilidad se encarga la palabra *public*. Permite llamar a los métodos desde fuera de la clase, como en el ejemplo anterior. Además de ella existe *private*, que se estudia en Hexlet en el curso de [POO en Java](https://codica.la/carreras/java). -El funcionamiento del método está determinado por: +Del funcionamiento del método se encargan: -* *static* - desvincula el método del objeto y permite llamarlo directamente desde la clase -* *void* se utiliza si el método no devuelve nada. Por ejemplo, esta es la definición del método `System.out.println()`. Si el método devuelve algún dato, en lugar de *void* se especifica el tipo de dato devuelto +* *static* — desvincula el método del objeto y hace posible llamarlo directamente desde la clase +* *void* se usa si el método no devuelve nada. Por ejemplo, esa es la definición del método `System.out.println()`. Si el método devuelve algún dato, en lugar de *void* se indica el tipo de los datos devueltos -A diferencia de los datos normales, los métodos realizan acciones, por lo que sus nombres casi siempre deben ser verbos: "construir algo", "dibujar algo", "abrir algo". +A diferencia de los datos normales, los métodos realizan acciones, por eso sus nombres casi siempre deben ser verbos: "construir algo", "dibujar algo", "abrir algo". -Todo lo que se describe dentro de las llaves `{}` se llama **cuerpo del método**. Dentro del cuerpo se puede escribir cualquier código. Considéralo como un pequeño programa independiente, un conjunto de instrucciones arbitrarias. +Todo lo que se describe dentro de las llaves `{}` se llama **cuerpo del método**. Dentro del cuerpo se puede escribir cualquier código. Considéralo un pequeño programa independiente, un conjunto de instrucciones arbitrarias. -El cuerpo se ejecuta exactamente en el momento en que se inicia el método. Además, cada llamada al método ejecuta el cuerpo de forma independiente de otras llamadas. Por cierto, el cuerpo puede estar vacío: +El cuerpo se ejecuta exactamente en el momento en que se lanza el método. Además, cada llamada al método ejecuta el cuerpo de forma independiente de las demás llamadas. Por cierto, el cuerpo puede estar vacío: ```java -// Definición mínima del método +// Definición mínima de un método public class App { public static void noop() { // Aquí podría haber código, pero no lo hay - // Presta atención a la indentación - // Para mayor legibilidad, cualquier código dentro del cuerpo se desplaza a la derecha en 4 espacios + // Fíjate en la indentación + // Para mayor legibilidad, cualquier código dentro del cuerpo se desplaza 4 espacios a la derecha } } App.noop(); ``` -El concepto de "crear un método" tiene muchos sinónimos: "implementar", "definir" e incluso "implementar". Todos estos términos se encuentran en la práctica diaria en el trabajo. +El concepto de "crear un método" tiene muchos sinónimos: "implementar", "definir" e incluso "codificar". Todos estos términos se encuentran en la práctica diaria del trabajo. + +## Reutilización y legibilidad + +Los métodos ayudan a evitar la duplicación. Supongamos que en el programa aparece varias veces el mismo conjunto de acciones: + +```java +System.out.println("Hello, Hexlet!"); +System.out.println("Hello, world!"); +System.out.println("Hello, Java!"); +``` + +Ese patrón se puede reunir en un solo método y llamarlo en distintos lugares. Cuando haya que cambiar el texto, la corrección se hace en un único lugar: en la definición del método. Cuanto más grande es el proyecto y más a menudo se repite la lógica, más notable es la ganancia. + +El nombre del método por sí mismo indica qué hace. El método `showCurrentDate()` habla de su tarea sin comentarios adicionales. Esto ayuda a otros programadores a leer el código, y también a ti mismo un mes después de haberlo escrito. diff --git a/modules/40-methods-definition/150-method-main/en/EXERCISE.md b/modules/40-methods-definition/150-method-main/en/EXERCISE.md new file mode 100644 index 00000000..8b54af47 --- /dev/null +++ b/modules/40-methods-definition/150-method-main/en/EXERCISE.md @@ -0,0 +1,11 @@ + +Implement a class named `App` with two methods: + +1. The method `gogo()`, which prints the string `It works!` to the screen +2. `main()`, as in the definition above, which calls the `gogo()` method + +The result of calling `main()` in that case will be: + +```java +// => "It works!" +``` diff --git a/modules/40-methods-definition/150-method-main/en/README.md b/modules/40-methods-definition/150-method-main/en/README.md new file mode 100644 index 00000000..a0b88c20 --- /dev/null +++ b/modules/40-methods-definition/150-method-main/en/README.md @@ -0,0 +1,96 @@ +You may be surprised, but throughout all the previous lessons we have been creating our own method. The skeleton of the method was written in advance, and you were required to add its body. The practice looked like this: + +```java +public class App { + public static void main(String[] args) { + // BEGIN + // And here you wrote your code + // END + } +} +``` + +Why did we create a method? Java is designed in such a way that it is impossible to execute code outside methods. You cannot just write code at the file level and run it. The compiler will report an error: + +```java +// A file with such code does not compile +System.out.println("Although it would seem so"); +``` + +But this code will already work: + +```java +public class App { + public static void main(String[] args) { + System.out.println("Although it would seem so"); + } +} +``` + +At work you will often see examples outside methods. Why do we and others do that? Purely for convenience. + +If you add a wrapper in the form of a class and a method to every single line, the amount of noise and material grows significantly. Always keep this in mind, because the authors of such materials count on you understanding how Java works. + +When you see code that is called without methods, always add the wrapper as shown above. Then you can easily run that code, for example, locally. + +## The main method + +Why is the method in our examples called `main`? After all, we could have written an example like this: + +```java +public class App { + // run - the name is chosen arbitrarily + // the name can be anything the author of the code wants + public static void run() { + // some code here + } +} +``` + +We could have done that, and everything would work, but there is one point. In this form the `main` method, the way we define it, has a special meaning for Java. + +Java calls it automatically when the program is launched from the console: + +```bash +# The App file contains a class named App +java App.java # compiles and runs for execution +# Inside, the App.main method will be launched, if it is defined +``` + +Any other method is not called automatically. That is exactly why we use `main` everywhere, because this way you can easily move the code from the exercise to your own editor and run it. + +Is it required to define it? No, Java does not impose any restriction on which methods and how many of them you define in a class. +Just as there is no restriction on the number and the names of classes. + +For simplicity we always use the name `App`, but in real code you will come across thousands of different names and classes. Although with the condition that a single file contains exactly one class: + +```java +class MySuperClassName { + public static void oneMethod() { + } + public static void twoMethod() { + } + public static void threeMethod() { + } +} +``` + +We will talk about this in the [Java OOP](https://ru.hexlet.io/programs/java?utm_source=code-basics&utm_medium=referral&utm_campaign=programs&utm_content=lesson) course. + +The main thing to remember now is that any static methods are called through a dot after the class name, and the calls themselves happen inside other methods: + +```java +// Just an example of methods calling each other +class MySuperClassName { + public static void oneMethod() { + MySuperClassName.twoMethod(); + } + + public static void twoMethod() { + MySuperClassName.threeMethod(); + } + + public static void threeMethod() { + } +} +``` diff --git a/modules/40-methods-definition/150-method-main/en/data.yml b/modules/40-methods-definition/150-method-main/en/data.yml new file mode 100644 index 00000000..4c369fa8 --- /dev/null +++ b/modules/40-methods-definition/150-method-main/en/data.yml @@ -0,0 +1,2 @@ +--- +name: The main method diff --git a/modules/40-methods-definition/150-method-main/es/README.md b/modules/40-methods-definition/150-method-main/es/README.md index 9dd0ea02..91879a97 100644 --- a/modules/40-methods-definition/150-method-main/es/README.md +++ b/modules/40-methods-definition/150-method-main/es/README.md @@ -74,7 +74,7 @@ class MySuperClassName { } ``` -Hablaremos de esto en el curso de [POO en Java](https://codica.la/courses/java-poo-basics). +Hablaremos de esto en el curso de [POO en Java](https://codica.la/carreras/java). Lo más importante que debes recordar ahora es que cualquier método estático se llama usando un punto después del nombre de la clase, y las llamadas en sí se realizan dentro de otros métodos: diff --git a/modules/40-methods-definition/200-method-definition-return/en/EXERCISE.md b/modules/40-methods-definition/200-method-definition-return/en/EXERCISE.md new file mode 100644 index 00000000..e79e41a6 --- /dev/null +++ b/modules/40-methods-definition/200-method-definition-return/en/EXERCISE.md @@ -0,0 +1,7 @@ + +Implement a static method named `sayHurrayThreeTimes()` that returns the string 'hurray! hurray! hurray!'. + +```java +var hurray = App.sayHurrayThreeTimes(); +System.out.println(hurray); // => hurray! hurray! hurray! +``` diff --git a/modules/40-methods-definition/200-method-definition-return/en/README.md b/modules/40-methods-definition/200-method-definition-return/en/README.md new file mode 100644 index 00000000..a4b28c18 --- /dev/null +++ b/modules/40-methods-definition/200-method-definition-return/en/README.md @@ -0,0 +1,137 @@ +The methods we defined in the previous lessons finished their work by printing some data to the screen: + +```java +public class App { + public static void greeting() { + System.out.println("Winter is coming"); + } +} +``` + +There is not much use in such methods, because the result of their work cannot be used inside the program. + +Let's look at this with an example. Take the task of processing an email address. When a user registers on some site, they can type the address in any way: + +* Accidentally add spaces at the beginning or at the end `_support@hexlet.io__` +* Use letters in different cases `SUPPORT@hexlet.io` + +If we save the address in this form into the database, the user will not be able to log in to the site when they type the address without spaces and in a different case. + +To prevent that, the address has to be prepared for saving: converted to lower case and trimmed of the spaces at the edges of the string. The whole task is solved in a couple of lines: + +```java +class App { + public static void main(String[] args) { + // We get the address from the form + var email = " SuppORT@hexlet.IO"; + // We trim the whitespace characters + var trimmedEmail = email.trim(); + // We convert it to lower case + var preparedEmail = trimmedEmail.toLowerCase(); + System.out.println(preparedEmail); // => support@hexlet.io + // We save it into the database + } +} +``` + +This code became possible only thanks to returning a value. The `trim()` and `toLowerCase()` methods do not print anything to the screen. They **return** the result of their work, and that is why we can store it in variables. If instead they printed to the screen, we could not assign the result of their work to a variable. Just as we cannot do it with the `greeting()` method defined above: + +```java +// Java will complain that `greeting()` returns nothing +// The code will not work +var message = App.greeting(); +``` + +Let's change the `greeting()` method so that it starts returning data instead of printing it. For this we need to make two edits: + +* Describe the type of the returned data — here it is the string `String` +* Return the value instead of printing it to the screen + +Let's look at the changed code: + +```java +class App { + public static String greeting() { + return "Winter is coming!"; + } +} +``` + +Instead of `void`, now `String` is written, because the method has a return. This way we told Java that the result of the method's work will be a string. + +Also pay attention to `return` — it is a special instruction. It takes the expression on its right and gives it outside, to the code that called the method. As soon as Java runs into `return`, the execution of the method ends there: + +```java +// Now this code works +var message = App.greeting(); +// We can perform some actions on the result +System.out.println(message.toUpperCase()); // => WINTER IS COMING! +``` + +Any code after `return` is not executed: + +```java +class App { + public static String greeting() { + return "Winter is coming!"; + // Any code below will never be executed + // Unreachable code in Java will not even compile + System.out.println("I will never be executed"); + } +} +``` + +Even if a method returns data, that does not limit it in what it prints. Besides returning data, we can print it as well: + +```java +class App { + public static String greeting() { + System.out.println("I will appear in the console"); + return "Winter is coming!"; + } +} + +// Somewhere in another method the program +// will both print the text to the screen and return the value +var value = App.greeting(); +``` + +You can return not only a specific value. Since `return` works with expressions, almost anything can appear on its right. Here you should be guided by the principles of code readability: + +```java +class App { + public static String greeting() { + var message = "Winter is coming!"; + return message; + } +} +``` + +Here we do not return the variable — the value that is inside this variable is always returned. Below is an example with calculations: + +```java +class App { + public static long doubleFive() { + // or return 5 + 5; + var result = 5 + 5; + return result; + } +} +``` + +In this example `long` was used in the method definition, because an integer is returned. + +To check the knowledge from this lesson, try to answer the question. What do you think this code will print? + +```java +// Definition +class App { + public static int run() { + return 5; + return 10; + } +} + +// Usage +App.run(); // => ? +``` diff --git a/modules/40-methods-definition/200-method-definition-return/en/data.yml b/modules/40-methods-definition/200-method-definition-return/en/data.yml new file mode 100644 index 00000000..a0e3b18f --- /dev/null +++ b/modules/40-methods-definition/200-method-definition-return/en/data.yml @@ -0,0 +1,5 @@ +--- +name: Returning values +tips: + - | + [The return keyword in Java](https://www.w3schools.com/java/ref_keyword_return.asp) diff --git a/modules/40-methods-definition/200-method-definition-return/es/EXERCISE.md b/modules/40-methods-definition/200-method-definition-return/es/EXERCISE.md index d1d786e8..2f544898 100644 --- a/modules/40-methods-definition/200-method-definition-return/es/EXERCISE.md +++ b/modules/40-methods-definition/200-method-definition-return/es/EXERCISE.md @@ -2,6 +2,6 @@ Implementa un método estático llamado `sayHurrayThreeTimes()` que devuelva la cadena 'hurray! hurray! hurray!'. ```java -var viva = App.sayHurrayThreeTimes(); -System.out.println(viva); // => hurray! hurray! hurray! +var hurray = App.sayHurrayThreeTimes(); +System.out.println(hurray); // => hurray! hurray! hurray! ``` diff --git a/modules/40-methods-definition/200-method-definition-return/es/README.md b/modules/40-methods-definition/200-method-definition-return/es/README.md index d713af46..71676b9f 100644 --- a/modules/40-methods-definition/200-method-definition-return/es/README.md +++ b/modules/40-methods-definition/200-method-definition-return/es/README.md @@ -1,137 +1,137 @@ -Los métodos que definimos en las lecciones anteriores finalizaban su trabajo imprimiendo algunos datos en la pantalla: +Los métodos que definimos en las lecciones anteriores terminaban su trabajo imprimiendo algunos datos en la pantalla: ```java public class App { - public static void saludo() { - System.out.println("Se acerca el invierno"); + public static void greeting() { + System.out.println("Winter is coming"); } } ``` -No hay mucho beneficio de tales métodos, ya que sus resultados no pueden ser utilizados dentro del programa. +Métodos como estos no son de mucha utilidad, ya que el resultado de su trabajo no se puede aprovechar dentro del programa. -Veamos esto con un ejemplo. Tomemos la tarea de procesar correos electrónicos. Cuando un usuario se registra en un sitio web, puede ingresar su correo electrónico de cualquier manera: +Veámoslo con un ejemplo. Tomemos la tarea de procesar el correo electrónico. Cuando un usuario se registra en un sitio, puede escribir su correo de cualquier manera: -* Agregar espacios aleatorios al principio o al final `_soporte@hexlet.io__` -* Usar letras en diferentes casos `SOPORTE@hexlet.io` +* Añadir espacios por accidente al principio o al final `_support@hexlet.io__` +* Usar letras en distintas mayúsculas y minúsculas `SUPPORT@hexlet.io` -Si guardamos la dirección en esta forma en la base de datos, el usuario no podrá iniciar sesión en el sitio web si ingresa la dirección sin espacios y en un caso diferente. +Si guardamos la dirección así en la base de datos, el usuario no podrá entrar en el sitio cuando escriba la dirección sin espacios y con otras mayúsculas. -Para evitar que esto suceda, la dirección debe prepararse para su almacenamiento en la base de datos, es decir, convertirse a minúsculas y recortarse los espacios al principio y al final de la cadena. La tarea completa se puede resolver en un par de líneas: +Para que eso no ocurra, la dirección hay que prepararla antes de guardarla: convertirla a minúsculas y recortar los espacios de los extremos de la cadena. Toda la tarea se resuelve en un par de líneas: ```java class App { public static void main(String[] args) { - // Obtén la dirección del formulario - var correo = " SoPORTE@hexlet.IO"; - // Recorta los caracteres de espacio en blanco - var correoRecortado = correo.trim(); - // Conviértelo a minúsculas - var correoPreparado = correoRecortado.toLowerCase(); - System.out.println(correoPreparado); // => soporte@hexlet.io - // Guardar en la base de datos + // Obtenemos la dirección del formulario + var email = " SuppORT@hexlet.IO"; + // Recortamos los caracteres de espacio + var trimmedEmail = email.trim(); + // Convertimos a minúsculas + var preparedEmail = trimmedEmail.toLowerCase(); + System.out.println(preparedEmail); // => support@hexlet.io + // Lo guardamos en la base de datos } } ``` -Este código se volvió posible solo gracias al valor de retorno. Los métodos `trim()` y `toLowerCase()` no imprimen nada en la pantalla. Ellos **devuelven** el resultado de su trabajo, por lo que podemos asignarlo a variables. Si en lugar de devolver el resultado, imprimieran en la pantalla, no podríamos asignar el resultado de su trabajo a una variable. Tal como no podemos hacerlo con el método `saludo()` definido arriba: +Este código fue posible solo gracias a la devolución del valor. Los métodos `trim()` y `toLowerCase()` no imprimen nada en la pantalla. Ellos **devuelven** el resultado de su trabajo, y por eso podemos guardarlo en variables. Si en su lugar imprimieran en la pantalla, no podríamos asignar el resultado de su trabajo a una variable. Igual que no podemos hacerlo con el método `greeting()` definido arriba: ```java -// Java se quejará de que `saludo()` no devuelve nada +// Java se quejará de que `greeting()` no devuelve nada // El código no funcionará -var mensaje = App.saludo(); +var message = App.greeting(); ``` -Modifiquemos el método `saludo()` para que comience a devolver datos en lugar de imprimirlos. Para hacerlo, necesitamos hacer dos cambios: +Cambiemos el método `greeting()` para que empiece a devolver datos en lugar de imprimirlos. Para eso tenemos que hacer dos correcciones: -* Especificar el tipo de datos de retorno, en este caso, es una cadena `String` -* Usar la instrucción `return` en lugar de imprimir en la pantalla +* Describir el tipo de los datos devueltos — aquí es la cadena `String` +* Devolver el valor en lugar de imprimirlo en la pantalla Veamos el código modificado: ```java class App { - public static String saludo() { - return "¡Se acerca el invierno!"; + public static String greeting() { + return "Winter is coming!"; } } ``` -En lugar de `void`, ahora tenemos `String` porque el método tiene un valor de retorno. De esta manera, le decimos a Java que el resultado del trabajo del método será una cadena. +En lugar de `void` ahora está escrito `String`, porque el método tiene devolución. Así le indicamos a Java que el resultado del trabajo del método será una cadena. -También presta atención a la instrucción `return`, es una instrucción especial. Toma la expresión a la derecha y la pasa al código que llamó al método. Tan pronto como Java encuentra `return`, la ejecución del método termina: +Fíjate también en `return`: es una instrucción especial. Toma la expresión que está a su derecha y la entrega hacia fuera, al código que llamó al método. En cuanto Java se encuentra con `return`, la ejecución del método termina ahí: ```java // Ahora este código funciona -var mensaje = App.saludo(); -// Podemos realizar algunas acciones en el resultado -System.out.println(mensaje.toUpperCase()); // => ¡SE ACERCA EL INVIERNO! +var message = App.greeting(); +// Podemos realizar algunas acciones con el resultado +System.out.println(message.toUpperCase()); // => WINTER IS COMING! ``` Cualquier código después de `return` no se ejecuta: ```java class App { - public static String saludo() { - return "¡Se acerca el invierno!"; - // Ningún código debajo se ejecutará nunca - // El código inalcanzable en Java ni siquiera compilará - System.out.println("Nunca seré ejecutado"); + public static String greeting() { + return "Winter is coming!"; + // Cualquier código de abajo no se ejecutará nunca + // El código inalcanzable en Java ni siquiera compila + System.out.println("I will never be executed"); } } ``` -Incluso si un método devuelve datos, esto no lo limita para imprimir. Además de devolver datos, también podemos imprimirlos: +Incluso si un método devuelve datos, eso no le impide imprimir. Además de devolver datos, también podemos imprimirlos: ```java class App { - public static String saludo() { - System.out.println("Apareceré en la consola"); - return "¡Se acerca el invierno!"; + public static String greeting() { + System.out.println("I will appear in the console"); + return "Winter is coming!"; } } -// En algún lugar en otro método del programa +// En algún otro método, el programa // imprimirá el texto en la pantalla y devolverá el valor -var valor = App.saludo(); +var value = App.greeting(); ``` -Es posible devolver no solo un valor específico. Dado que `return` funciona con expresiones, casi cualquier cosa puede aparecer a la derecha de él. Aquí debemos seguir los principios de legibilidad del código: +Se puede devolver no solo un valor concreto. Como `return` trabaja con expresiones, a su derecha puede aparecer casi cualquier cosa. Aquí hay que guiarse por los principios de legibilidad del código: ```java class App { - public static String saludo() { - var mensaje = "¡Se acerca el invierno!"; - return mensaje; + public static String greeting() { + var message = "Winter is coming!"; + return message; } } ``` -Aquí, no estamos devolviendo la variable en sí, siempre estamos devolviendo el valor que está almacenado en esta variable. A continuación, hay un ejemplo con cálculos: +Aquí no devolvemos la variable: siempre se devuelve el valor que está dentro de esa variable. A continuación, un ejemplo con cálculos: ```java class App { - public static long dobleCinco() { + public static long doubleFive() { // o return 5 + 5; - var resultado = 5 + 5; - return resultado; + var result = 5 + 5; + return result; } } ``` -En este ejemplo, se utilizó `long` en la definición del método porque se devuelve un entero. +En este ejemplo, en la definición del método se usó `long`, porque se devuelve un número entero. -Para poner a prueba tus conocimientos de esta lección, intenta responder la pregunta. ¿Qué crees que mostrará este código? +Para comprobar los conocimientos de esta lección, intenta responder a la pregunta. ¿Qué crees que mostrará este código? ```java // Definición class App { - public static int ejecutar() { + public static int run() { return 5; return 10; } } // Uso -App.ejecutar(); // => ? +App.run(); // => ? ``` diff --git a/modules/40-methods-definition/200-method-definition-return/es/data.yml b/modules/40-methods-definition/200-method-definition-return/es/data.yml index b43ddf67..0de6ff37 100644 --- a/modules/40-methods-definition/200-method-definition-return/es/data.yml +++ b/modules/40-methods-definition/200-method-definition-return/es/data.yml @@ -1,2 +1,5 @@ --- -name: Valores de Retorno +name: Devolución de valores +tips: + - | + [La instrucción return en Java](https://www.w3schools.com/java/ref_keyword_return.asp) diff --git a/modules/40-methods-definition/300-method-definition-parameters/AppTest.java b/modules/40-methods-definition/300-method-definition-parameters/AppTest.java index 47a0132b..bdf215f8 100644 --- a/modules/40-methods-definition/300-method-definition-parameters/AppTest.java +++ b/modules/40-methods-definition/300-method-definition-parameters/AppTest.java @@ -2,10 +2,10 @@ class AppTest { public static void main(String[] args) { - var actual1 = App.truncate("текст", 3); - assertThat(actual1).isEqualTo("тек..."); + var actual1 = App.truncate("text", 3); + assertThat(actual1).isEqualTo("tex..."); - var actual2 = App.truncate("и пошла вода", 5); - assertThat(actual2).isEqualTo("и пош..."); + var actual2 = App.truncate("and water flowed", 5); + assertThat(actual2).isEqualTo("and w..."); } } diff --git a/modules/40-methods-definition/300-method-definition-parameters/en/EXERCISE.md b/modules/40-methods-definition/300-method-definition-parameters/en/EXERCISE.md new file mode 100644 index 00000000..496bec9f --- /dev/null +++ b/modules/40-methods-definition/300-method-definition-parameters/en/EXERCISE.md @@ -0,0 +1,29 @@ + +Implement the static method `App.truncate()`, which cuts the passed string down to the specified number of characters, adds an ellipsis at the end and returns the resulting string. Similar logic is often used on sites to display a long text in a shortened form. The method accepts two parameters: + +1. The string (`String`) that needs to be cut +2. The number (`int`) of characters that need to be left + +An example of how the method you write should work: + +```java +// We pass the text directly +// We cut the text, leaving 2 characters +App.truncate("hexlet", 2); // he... + +// Through a variable +var text = "it works!" +// We cut the text, leaving 4 characters +App.truncate(text, 4); // it w... +``` + +This method can be implemented in various ways; we will suggest just one of them. To solve it this way you will need to take a substring of the string passed as the first parameter to the `truncate()` method. Use the [substring()](https://ru.hexlet.io/qna/java/questions/kak-izvlech-podstroku-iz-stroki-v-java?utm_source=code-basics&utm_medium=referral&utm_campaign=qna&utm_content=lesson) method for this. Think, based on the task, from which index and up to which one you have to extract the substring. + + ```java + var text = "welcome"; + // Parameters can be passed to a method through variables + var index = 3; + text.substring(0, index); // wel + ``` + +From the point of view of the checking system it does not matter in which way the `truncate()` method is implemented inside — the main thing is that it does the task at hand diff --git a/modules/40-methods-definition/300-method-definition-parameters/en/README.md b/modules/40-methods-definition/300-method-definition-parameters/en/README.md new file mode 100644 index 00000000..fecad981 --- /dev/null +++ b/modules/40-methods-definition/300-method-definition-parameters/en/README.md @@ -0,0 +1,110 @@ +Methods can not only return values, but also accept them in the form of parameters. We have already come across method parameters many times: + +```java +// Accepts one parameter of any type +System.out.println("I am a parameter"); +// Accepts the index by which the character is extracted +"some text".charAt(3); // 'e' +// Accepts two string parameters +// The first — what we are looking for, the second — what we replace it with +"google".replace("go", "mo"); // "moogle" +// Accepts two numeric parameters +// the first — the starting index inclusive, the second — the ending index exclusive +"hexlet".substring(1, 3); // "ex" +``` + +In this lesson we will learn how to create methods that accept parameters. + +Imagine that we have a task — to implement the static method `App.getLastChar()`. It must return the last character of the string passed to it as a parameter. + +This is what using this method looks like: + +```java +// Passing parameters directly without variables +App.getLastChar("Hexlet"); // 't' +App.getLastChar("Goo"); // 'o' +// Passing parameters through variables +var name1 = "Hexlet"; +App.getLastChar(name1); // 't' +var name2 = "Goo"; +App.getLastChar(name2); // 'o' +``` + +From the description and the code examples we can draw the following conclusions: + +* We need to define the static method `getLastChar()` in the `App` class +* The method must accept one parameter of type `String` +* The method must return a value of type `char` + +To begin with, let's define the method: + +```java +class App { + public static char getLastChar(String str) { + // We calculate the index of the last character as the length of the string minus 1 + return str.charAt(str.length() - 1); + } +} +``` + +Let's look at this code in more detail. `char` tells us about the type of the returned value. Then, in parentheses, the type of the parameter `String` and its name `str` are specified. + +Inside the method we do not know which specific value we are working with, so parameters are always described as variables. + +The name of the parameter can be anything — it is not tied to how the method is called. The main thing is that this name reflects the meaning of the value it contains. The specific value of the parameter will depend on the call of this method. + +Parameters in Java are always required. If a method needs parameters and we try to write code without a parameter, the compiler will report an error: + +```sh +App.getLastChar(); // such code makes no sense +method getLastChar in class App cannot be applied to given types; + required: String + found: no arguments + reason: actual and formal argument lists differ in length +``` + +In exactly the same way you can specify two and more parameters. Each parameter is separated with a comma: + +```java +class App { + // A method for finding the average number + // The returned type is double, because + // division can produce a fractional number + public static double average(int x, int y) { + return (x + y) / 2.0; + } +} + +App.average(1, 5); // 3.0 +App.average(1, 2); // 1.5 +``` + +Methods can require as many parameters as they need in order to work: + +```java +// the first parameter — what we are looking for +// the second parameter — what we replace it with +"google".replace("go", "mo"); // "moogle" +``` + +To create such methods you need to specify the required number of parameters separated by commas in the definition, giving them understandable names. Below is an example of the definition of the `replace()` method, which replaces one part of a string in a word with another: + +```java +class App { + public static String replace(String text, String from, String to) { + // Here is the body of the method, but we + // omit it so as not to get distracted + return text.replace(from, to); + } +} + +App.replace("google", "go", "mo"); // "moogle" +``` + +When there are two or more parameters, the order in which these parameters are passed becomes important for almost all methods. Swapping the arguments changes the result of the method: + +```java +// Nothing was replaced, +// because there is no mo inside google +App.replace("google", "mo", "go"); // "google" +``` diff --git a/modules/40-methods-definition/300-method-definition-parameters/en/data.yml b/modules/40-methods-definition/300-method-definition-parameters/en/data.yml new file mode 100644 index 00000000..652835b8 --- /dev/null +++ b/modules/40-methods-definition/300-method-definition-parameters/en/data.yml @@ -0,0 +1,2 @@ +--- +name: Defining methods diff --git a/modules/40-methods-definition/300-method-definition-parameters/es/EXERCISE.md b/modules/40-methods-definition/300-method-definition-parameters/es/EXERCISE.md index 65e843a0..6766b76a 100644 --- a/modules/40-methods-definition/300-method-definition-parameters/es/EXERCISE.md +++ b/modules/40-methods-definition/300-method-definition-parameters/es/EXERCISE.md @@ -1,29 +1,29 @@ -Implementa el método estático `App.truncate()`, que recorta la cadena pasada como parámetro hasta el número de caracteres especificado, agrega puntos suspensivos al final y devuelve la cadena resultante. Esta lógica se utiliza a menudo en sitios web para mostrar texto largo de forma abreviada. El método recibe dos parámetros: +Implementa el método estático `App.truncate()`, que recorta la cadena pasada hasta la cantidad de caracteres indicada, añade puntos suspensivos al final y devuelve la cadena resultante. Una lógica parecida se usa a menudo en los sitios web para mostrar un texto largo de forma abreviada. El método recibe dos parámetros: -1. Una cadena (`String`) que se debe truncar -2. Un número (`int`) de caracteres que se deben conservar +1. La cadena (`String`) que hay que recortar +2. El número (`int`) de caracteres que hay que dejar -Aquí tienes un ejemplo de cómo debería funcionar el método que escribas: +Un ejemplo de cómo debe funcionar el método que escribas: ```java -// Pasando el texto directamente -// Se recorta el texto dejando 2 caracteres +// Pasamos el texto directamente +// Recortamos el texto dejando 2 caracteres App.truncate("hexlet", 2); // he... // A través de una variable -var text = "¡funciona!" -// Se recorta el texto dejando 4 caracteres +var text = "it works!" +// Recortamos el texto dejando 4 caracteres App.truncate(text, 4); // it w... ``` -Puedes implementar este método de diferentes maneras, solo te daremos una pista. Para resolverlo de esta manera, necesitarás tomar una subcadena de la cadena pasada como primer parámetro en el método `truncate()`. Utiliza el método [substring()](https://ru.hexlet.io/qna/java/questions/kak-izvlech-podstroku-iz-stroki-v-java?utm_source=code-basics&utm_medium=referral&utm_campaign=qna&utm_content=lesson) para esto. Piensa, según la tarea, desde qué índice y hasta qué índice debes extraer la subcadena. +Este método se puede implementar de distintas maneras; te sugerimos solo una de ellas. Para resolverlo así necesitarás tomar una subcadena de la cadena que se pasa como primer parámetro al método `truncate()`. Usa para eso el método [substring()](https://ru.hexlet.io/qna/java/questions/kak-izvlech-podstroku-iz-stroki-v-java?utm_source=code-basics&utm_medium=referral&utm_campaign=qna&utm_content=lesson). Piensa, a partir del enunciado, desde qué índice y hasta cuál tienes que extraer la subcadena. ```java - var text = "bienvenido"; - // Puedes pasar parámetros al método a través de variables + var text = "welcome"; + // Los parámetros se pueden pasar al método a través de variables var index = 3; - text.substring(0, index); // bie + text.substring(0, index); // wel ``` -Desde el punto de vista del sistema de evaluación, no importa qué método uses para implementar `truncate()` internamente, lo importante es que cumpla con la tarea planteada. +Desde el punto de vista del sistema de comprobación, no importa de qué manera se implemente por dentro el método `truncate()`; lo importante es que cumpla la tarea planteada diff --git a/modules/40-methods-definition/300-method-definition-parameters/es/README.md b/modules/40-methods-definition/300-method-definition-parameters/es/README.md index c9601960..1f3d8e50 100644 --- a/modules/40-methods-definition/300-method-definition-parameters/es/README.md +++ b/modules/40-methods-definition/300-method-definition-parameters/es/README.md @@ -1,36 +1,36 @@ -Los métodos no solo pueden devolver valores, sino también recibirlos como parámetros. Ya nos hemos encontrado con métodos con parámetros muchas veces: +Los métodos no solo pueden devolver valores, sino también recibirlos en forma de parámetros. Ya nos hemos topado muchas veces con parámetros de métodos: ```java // Recibe un parámetro de cualquier tipo System.out.println("soy un parámetro"); -// Recibe un índice y devuelve el carácter correspondiente -"algún texto".charAt(3); // 'n' +// Recibe el índice por el que se extrae el carácter +"un texto cualquiera".charAt(3); // 't' // Recibe dos parámetros de tipo cadena -// El primero es lo que buscamos, el segundo es por qué lo reemplazamos +// El primero, qué buscamos; el segundo, por qué lo cambiamos "google".replace("go", "mo"); // "moogle" // Recibe dos parámetros numéricos -// el primero es el índice inicial (inclusive), el segundo es el índice final (no inclusivo) +// el primero, el índice inicial inclusive; el segundo, el índice final no inclusive "hexlet".substring(1, 3); // "ex" ``` En esta lección aprenderemos a crear métodos que reciben parámetros. -Supongamos que tenemos la tarea de implementar el método estático `App.getLastChar()`. Debe devolver el último carácter de la cadena que se pasa como parámetro. +Imaginemos que tenemos la tarea de implementar el método estático `App.getLastChar()`. Debe devolver el último carácter de la cadena que se le pasa como parámetro. -Así es como se usaría este método: +Así se vería el uso de este método: ```java -// Pasando parámetros directamente sin variables +// Paso de parámetros directamente, sin variables App.getLastChar("Hexlet"); // 't' App.getLastChar("Goo"); // 'o' -// Pasando parámetros a través de variables +// Paso de parámetros a través de variables var name1 = "Hexlet"; App.getLastChar(name1); // 't' var name2 = "Goo"; App.getLastChar(name2); // 'o' ``` -De la descripción y los ejemplos de código, podemos hacer las siguientes conclusiones: +A partir de la descripción y de los ejemplos de código podemos sacar las siguientes conclusiones: * Necesitamos definir el método estático `getLastChar()` en la clase `App` * El método debe recibir un parámetro de tipo `String` @@ -47,15 +47,15 @@ class App { } ``` -Analicemos este código en detalle. `char` nos indica el tipo de valor que se devuelve. Luego, entre paréntesis, se especifica el tipo del parámetro `String` y su nombre `str`. +Analicemos este código con más detalle. `char` nos indica el tipo del valor devuelto. Después, entre paréntesis, se indica el tipo del parámetro `String` y su nombre `str`. -Dentro del método, no sabemos con qué valor específico estamos trabajando, por lo que los parámetros siempre se describen como variables. +Dentro del método no sabemos con qué valor concreto se está trabajando, por eso los parámetros siempre se describen como variables. -El nombre del parámetro puede ser cualquier cosa, no está relacionado con la forma en que se llama al método. Lo importante es que este nombre refleje el significado del valor que contiene. El valor específico del parámetro dependerá de cómo se llame a este método. +El nombre del parámetro puede ser cualquiera: no está ligado a cómo se llama al método. Lo importante es que ese nombre refleje el sentido del valor que contiene. El valor concreto del parámetro dependerá de la llamada a ese método. -Los parámetros en Java siempre son obligatorios. Si un método requiere parámetros y intentamos escribir código sin ellos, el compilador mostrará un error: +Los parámetros en Java siempre son obligatorios. Si un método necesita parámetros y probamos a escribir código sin parámetro, el compilador mostrará un error: -```bash +```sh App.getLastChar(); // este código no tiene sentido method getLastChar in class App cannot be applied to given types; required: String @@ -63,13 +63,13 @@ method getLastChar in class App cannot be applied to given types; reason: actual and formal argument lists differ in length ``` -De la misma manera, se pueden especificar dos o más parámetros. Cada parámetro se separa por comas: +Exactamente de la misma manera se pueden indicar dos o más parámetros. Cada parámetro se separa con una coma: ```java class App { - // Método para encontrar el número medio - // El tipo de retorno es double porque - // la división puede dar como resultado un número decimal + // Método para hallar el número medio + // El tipo devuelto es double, porque + // al dividir puede salir un número decimal public static double average(int x, int y) { return (x + y) / 2.0; } @@ -79,30 +79,32 @@ App.average(1, 5); // 3.0 App.average(1, 2); // 1.5 ``` -Los métodos pueden requerir cualquier cantidad de parámetros que necesiten para funcionar: +Los métodos pueden exigir en la entrada cualquier cantidad de parámetros que necesiten para funcionar: ```java -// el primer parámetro es lo que buscamos -// el segundo parámetro es por qué lo reemplazamos -'google'.replace('go', 'mo'); // moogle +// el primer parámetro, qué buscamos +// el segundo parámetro, por qué lo cambiamos +"google".replace("go", "mo"); // "moogle" ``` -Para crear tales métodos, debemos especificar la cantidad necesaria de parámetros en la definición, separados por comas, dándoles nombres descriptivos. A continuación se muestra un ejemplo de definición del método `replace()`, que reemplaza una parte de una cadena por otra: +Para crear métodos así hay que indicar en la definición la cantidad necesaria de parámetros separados por comas, dándoles nombres comprensibles. Abajo hay un ejemplo de definición del método `replace()`, que sustituye una parte de la cadena por otra: ```java class App { public static String replace(String text, String from, String to) { - // aquí va el cuerpo del método, pero lo omitimos para no distraernos + // Aquí va el cuerpo del método, pero lo + // omitimos para no distraernos + return text.replace(from, to); } } -App.replace('google', 'go', 'mo'); // moogle +App.replace("google", "go", "mo"); // "moogle" ``` -Cuando hay dos o más parámetros, el orden en que se pasan esos parámetros se vuelve importante para casi todos los métodos. Si se cambia el orden, el método se ejecutará de manera diferente: +Cuando hay dos o más parámetros, para casi todos los métodos pasa a ser importante el orden en que se pasan esos parámetros. Al intercambiar los argumentos de lugar, el resultado del método cambia: ```java -// no se reemplaza nada, -// ya que no hay 'mo' dentro de google -App.replace('google', 'mo', 'go'); // google +// No se sustituyó nada, +// porque dentro de google no hay mo +App.replace("google", "mo", "go"); // "google" ``` diff --git a/modules/40-methods-definition/400-method-definition-default-parameters/en/EXERCISE.md b/modules/40-methods-definition/400-method-definition-default-parameters/en/EXERCISE.md new file mode 100644 index 00000000..e28e9af9 --- /dev/null +++ b/modules/40-methods-definition/400-method-definition-default-parameters/en/EXERCISE.md @@ -0,0 +1,17 @@ + +Implement the method `getHiddenCard()`, which accepts a credit card number (consisting of 16 digits) as a string and returns its hidden version, which can be used on a site for display. If the original card had the number *2034399002125581*, then the hidden version looks like this *\*\*\*\*5581*. In other words, the function replaces the first 12 characters with asterisks. The number of asterisks is controlled by the second, optional parameter. The default value is 4. + +```java +// The credit card is passed inside as a string +App.getHiddenCard("1234567812345678", 2); // "**5678" +App.getHiddenCard("1234567812345678", 3); // "***5678" +App.getHiddenCard("1234567812345678"); // "****5678" +App.getHiddenCard("2034399002121100", 1); // "*1100" +``` + +To complete the task you will need the string method `repeat`, which repeats the string the specified number of times + +```java +"+".repeat(5); // "+++++" +"o".repeat(5); // "ooooo" +``` diff --git a/modules/40-methods-definition/400-method-definition-default-parameters/en/README.md b/modules/40-methods-definition/400-method-definition-default-parameters/en/README.md new file mode 100644 index 00000000..c8db83e1 --- /dev/null +++ b/modules/40-methods-definition/400-method-definition-default-parameters/en/README.md @@ -0,0 +1,73 @@ +In programming, many methods have parameters that rarely change. It is often convenient to give such a parameter one value and substitute it when nothing else was passed in the call. Such a value is called a **default value**. + +In many languages the default value is written right in the definition. For example, in Python the method for raising to a power looks like this: + +```python +# The exponent is the second parameter with the default value 2 +def pow(x, base=2): + return x ** base + +pow(3) # 9, by default we raise to the second power +pow(3, 3) # 27, the exponent is passed explicitly +``` + +In Java parameters have no default values. But the same result is achieved through **method overloading**. + +What is that? Java allows you to create several methods with the same name. Such identical methods must have: + +* Different types of input parameters +* A different number of parameters +* Or all of that at the same time + +Let's look at the example of a method that adds numbers. We will create two versions of `sum()` in one class. The first accepts two numbers, the second accepts only one and adds 10 to it: + +```java +class App { + public static int sum(int x, int y) { + return x + y; + } + + public static int sum(int x) { + return x + 10; + } +} + +App.sum(2, 3); // 5, the version with two parameters worked +App.sum(2); // 12, the version with one parameter worked +``` + +The compiler will create two methods with one name without any problems. How does Java know which one of them to call? + +During compilation the version of the method that matches by the type and the number of parameters is chosen. When there is no suitable method, the compiler reports an error. + +We have already met at least one overloaded method — it is the `substring()` method. By default it extracts the substring up to the end, but a second parameter can be passed to it that will limit the length: + +```java +// Two different methods with one name are called +"hexlet".substring(3); // "let" +"hexlet".substring(3, 5); // "le" +``` + +Method overloading can lead to code duplication, especially when it comes to default values. In such situations the logic is the same, and the difference is only in the initial initialization. + +To reduce duplication it is enough to take two steps: + +* First, define a common method that accepts the most parameters +* Then call it from those methods that have default values + +In code it looks like this: + +```java +class App { + public static int sum(int x, int y) { + return x + y; + } + + public static int sum(int x) { + // We call the already existing summation method + return App.sum(x, 10); + } +} +``` + +In this example we did not shorten the code, but it clearly shows the principle described above. diff --git a/modules/40-methods-definition/400-method-definition-default-parameters/en/data.yml b/modules/40-methods-definition/400-method-definition-default-parameters/en/data.yml new file mode 100644 index 00000000..c3611b23 --- /dev/null +++ b/modules/40-methods-definition/400-method-definition-default-parameters/en/data.yml @@ -0,0 +1,2 @@ +--- +name: Optional method parameters diff --git a/modules/40-methods-definition/400-method-definition-default-parameters/es/README.md b/modules/40-methods-definition/400-method-definition-default-parameters/es/README.md index 1f5d35be..30b36a20 100644 --- a/modules/40-methods-definition/400-method-definition-default-parameters/es/README.md +++ b/modules/40-methods-definition/400-method-definition-default-parameters/es/README.md @@ -1,78 +1,61 @@ - +En programación, muchos métodos tienen parámetros que cambian muy pocas veces. A menudo a un parámetro así conviene asignarle un único valor y usarlo cuando en la llamada no se pasa nada distinto. Ese valor se llama **valor predeterminado**. -En programación, muchas funciones y métodos tienen parámetros que rara vez cambian. +En muchos lenguajes el valor predeterminado se escribe directamente en la definición. Por ejemplo, en Python el método de elevar a una potencia se ve así: -En estos casos, se les asignan **valores predeterminados** a estos parámetros, que se pueden cambiar según sea necesario. Esto reduce un poco la cantidad de código repetitivo. +```python +# El exponente es el segundo parámetro con el valor predeterminado 2 +def pow(x, base=2): + return x ** base -Esto se puede ver claramente en el siguiente ejemplo: - -```java -class App { - // Función de potenciación - // El exponente es el segundo parámetro con un valor predeterminado de 2 - function pow(x, base = 2) { - return x ** base; - } -} - -App.pow(3); // Resultado: 9, ya que se eleva al cuadrado de forma predeterminada -// Elevar al cubo -App.pow(3, 3); // 27 +pow(3) # 9, por defecto elevamos al cuadrado +pow(3, 3) # 27, el exponente se pasa de forma explícita ``` -A diferencia de otros lenguajes, en Java no es posible asignar un valor predeterminado, pero se puede simular utilizando la **sobrecarga de métodos**. +En Java los parámetros no tienen valores predeterminados. Sin embargo, el mismo resultado se consigue con la **sobrecarga de métodos**. -¿Qué es la sobrecarga de métodos? Java permite crear varios métodos con el mismo nombre. Estos métodos deben tener: +¿Qué es eso? Java permite crear varios métodos con el mismo nombre. Esos métodos iguales deben tener: -* Diferentes tipos de parámetros de entrada -* Diferente cantidad de parámetros -* O ambas cosas a la vez +* Distintos tipos de parámetros de entrada +* Distinta cantidad de parámetros +* O todo eso a la vez -Veamos un ejemplo de un método que suma dos números: +Veámoslo con el ejemplo de un método que suma números. Crearemos dos versiones de `sum()` en una misma clase. La primera recibe dos números; la segunda recibe solo uno y le suma 10: ```java class App { public static int sum(int x, int y) { return x + y; } -} - -App.sum(2, 3); // 5 -``` -Ahora escribamos otro método `sum()` que solo recibe un parámetro y lo suma con el número 10: - -```java -class App { public static int sum(int x) { return x + 10; } } -App.sum(2); // 12 -App.sum(2, 1); // 3 +App.sum(2, 3); // 5, funcionó la versión con dos parámetros +App.sum(2); // 12, funcionó la versión con un parámetro ``` -El compilador ejecutará este código sin problemas y creará dos métodos con el mismo nombre. ¿Cómo sabe Java qué método utilizar? +El compilador creará sin problemas dos métodos con un mismo nombre. ¿Cómo sabe Java a cuál de ellos llamar? -Es muy simple: durante la compilación, se elige la versión del método que coincide en tipo y cantidad de parámetros. Si no se encuentra dicho método, se producirá un error. +Durante la compilación se elige la versión del método que coincide en el tipo y la cantidad de parámetros. Cuando no hay un método adecuado, el compilador informa de un error. -Ya hemos visto al menos un método sobrecargado: `substring()`. Por defecto, extrae una subcadena hasta el final, pero se le puede pasar un segundo parámetro que limite la longitud: +Con al menos un método sobrecargado ya nos hemos encontrado: es el método `substring()`. Por defecto extrae la subcadena hasta el final, pero se le puede pasar un segundo parámetro que limite la longitud: ```java -// Se llaman a dos métodos diferentes con el mismo nombre +// Se llaman dos métodos distintos con un mismo nombre "hexlet".substring(3); // "let" "hexlet".substring(3, 5); // "le" ``` -La sobrecarga de métodos puede llevar a la duplicación de código, especialmente cuando se trata de valores predeterminados. En tales situaciones, la lógica es la misma, solo difiere en la inicialización inicial. +La sobrecarga de métodos puede llevar a la duplicación de código, sobre todo cuando se trata de valores predeterminados. En esas situaciones la lógica es la misma, y la diferencia está solo en la inicialización inicial. -Para reducir la duplicación, basta con seguir estos dos pasos: +Para reducir la duplicación basta con dar dos pasos: -* Primero, definir un método común que acepte la mayor cantidad de parámetros -* Luego, llamar a ese método desde los métodos que tienen valores predeterminados +* Primero, definir un método común que reciba la mayor cantidad de parámetros +* Después, llamarlo desde aquellos métodos que tienen valores predeterminados -En el código, se vería así: +En el código se ve así: ```java class App { @@ -81,10 +64,10 @@ class App { } public static int sum(int x) { - // Llamamos al método de suma ya existente + // Llamamos al método de suma que ya está listo return App.sum(x, 10); } } ``` -En este ejemplo, no hemos reducido el código, pero muestra claramente el principio descrito anteriormente. +En este ejemplo no hemos acortado el código, pero muestra con claridad el principio descrito arriba. diff --git a/modules/40-methods-definition/500-packages/en/EXERCISE.md b/modules/40-methods-definition/500-packages/en/EXERCISE.md new file mode 100644 index 00000000..e111fe36 --- /dev/null +++ b/modules/40-methods-definition/500-packages/en/EXERCISE.md @@ -0,0 +1,10 @@ +Implement the method `amountPerPerson()`. It accepts the restaurant bill amount `total`, the number of people `people` and the tip percentage `tipPercent`, and returns the amount each person pays. The result is rounded **up** — nobody should underpay. + +To round up, use the `ceil()` method. It is already connected at the beginning of the file with a static import from the `Math` class, so it can be called without the `Math.` prefix. + +```java +App.amountPerPerson(300, 4, 20); // => 90 +App.amountPerPerson(350, 3, 10); // => 129 +``` + +First calculate the final amount with the tip, then divide it by the number of people and round up. The result of the `ceil()` method has the type `double`, and you need to return an `int` — do not forget about type casting. diff --git a/modules/40-methods-definition/500-packages/en/README.md b/modules/40-methods-definition/500-packages/en/README.md new file mode 100644 index 00000000..bd6d94f4 --- /dev/null +++ b/modules/40-methods-definition/500-packages/en/README.md @@ -0,0 +1,84 @@ +When a program grows, it gets not only more lines of code, but also more classes. Each class solves its own task and lies in a separate file, and in a real application there can be hundreds or thousands of such files. Some of the classes are written by you, some come along with the connected libraries. + +With such a number of classes, a situation almost inevitably arises where two different classes get the same names. If two classes with the same name end up in one project, the program will not compile. Your own class can be renamed, but with a class from someone else's library that will not work. That is why the requirement of unique names would seriously get in the way of reusing other people's code. + +To solve this problem, Java uses **packages**. A package is a mechanism for combining classes into logically related groups. Packages are similar to folders in a file system: just as folders organize files, packages organize classes. Different packages can contain classes with the same names, and no conflict will arise. + +## Defining packages + +A package is specified with the `package` keyword at the very beginning of the file, immediately followed by the name of the package: + +```java +// File company/User.java +package company; + +public class User { + // code for working with the user +} +``` + +The structure of packages is tied to the file structure of the project: the name of the package corresponds to the directory in which the file lies. Packages can be nested — then the directories are nested into each other as well. If a class lies in the `io.hexlet.model` package, then the file is located in the `io/hexlet/model` directory. + +Usually the name of a package starts with a prefix assigned to a company or a developer — most often it is the domain name in reverse order. For example, for the domain `hexlet.io` packages start with `io.hexlet`. Further on, the structure depends on the architecture of the application: classes are grouped by meaning, for example, the main entities — users and courses — are put into the `model` package: + +```java +// File io/hexlet/model/User.java +package io.hexlet.model; + +public class User { + public static String getGreeting(String userName) { + return "Hello, " + userName + "!"; + } +} +``` + +## Importing classes + +Classes from the same package refer to each other simply by name. But you constantly have to use classes from other packages too. To refer to a class from another package, it has to be imported — the `import` keyword serves for this, followed by the full name of the class: + +```java +package io.hexlet; + +import io.hexlet.model.User; + +class App { + public static void main(String[] args) { + var greeting = User.getGreeting("John"); + System.out.println(greeting); + } +} +``` + +After the import, the class is referred to by its short name. Without the import you would have to write the full (fully qualified) name every time, including the name of the package: + +```java +var greeting = io.hexlet.model.User.getGreeting("John"); +``` + +The full name comes to the rescue when two classes with the same name from different packages are needed in one place: one class is imported, and the second one is referred to by its full name. + +You can import all the classes of a package at once with the help of `*`: + +```java +import java.util.*; +``` + +This is convenient when many classes from the package are needed, but you should not abuse it: importing "everything at once" clutters the namespace and increases the risk of a name conflict between packages. + +## Static import + +Java allows you to import not only classes, but also individual static methods — then they can be called without specifying the class. This is convenient when some method is used often, and it makes the code more compact: + +```java +import static java.lang.Math.ceil; + +public class App { + public static void main(String[] args) { + // The Math class name can be omitted in the call + double result = ceil(2.3); // 3.0 + System.out.println(result); + } +} +``` + +You can also import all the static methods of a class at once: `import static java.lang.Math.*;`. We use static import in the exercise of this lesson. diff --git a/modules/40-methods-definition/500-packages/en/data.yml b/modules/40-methods-definition/500-packages/en/data.yml new file mode 100644 index 00000000..cb82cf9b --- /dev/null +++ b/modules/40-methods-definition/500-packages/en/data.yml @@ -0,0 +1,15 @@ +--- +name: Packages +tips: + - > + [An example of a Java application with packages and + imports](https://github.com/hexlet-boilerplates/java-package) +definitions: + - name: Package + description: >- + a mechanism for grouping classes into logically related groups; helps to + avoid name conflicts. It is specified with the `package` keyword. + - name: import + description: >- + a keyword that connects a class from another package so that you can refer + to it by its short name without specifying the package. diff --git a/modules/40-methods-definition/500-packages/es/EXERCISE.md b/modules/40-methods-definition/500-packages/es/EXERCISE.md new file mode 100644 index 00000000..8a7aee8e --- /dev/null +++ b/modules/40-methods-definition/500-packages/es/EXERCISE.md @@ -0,0 +1,10 @@ +Implementa el método `amountPerPerson()`. Recibe el importe de la cuenta del restaurante `total`, la cantidad de personas `people` y el porcentaje de propina `tipPercent`, y devuelve el importe que paga cada uno. El resultado se redondea **hacia arriba**: nadie debe pagar de menos. + +Para redondear hacia arriba usa el método `ceil()`. Ya está conectado al principio del archivo con una importación estática de la clase `Math`, por eso se puede llamar sin el prefijo `Math.`. + +```java +App.amountPerPerson(300, 4, 20); // => 90 +App.amountPerPerson(350, 3, 10); // => 129 +``` + +Primero calcula el importe final con la propina, después divídelo entre la cantidad de personas y redondea hacia arriba. El resultado del método `ceil()` es de tipo `double`, y hay que devolver un `int`: no te olvides de la conversión de tipo. diff --git a/modules/40-methods-definition/500-packages/es/README.md b/modules/40-methods-definition/500-packages/es/README.md new file mode 100644 index 00000000..70ef2933 --- /dev/null +++ b/modules/40-methods-definition/500-packages/es/README.md @@ -0,0 +1,84 @@ +Cuando un programa crece, en él no solo hay más líneas de código, sino también más clases. Cada clase resuelve su propia tarea y está en un archivo aparte, y en una aplicación real esos archivos pueden ser cientos o miles. Una parte de las clases se escribe uno mismo, y otra parte llega junto con las bibliotecas conectadas. + +Con esa cantidad de clases, es casi inevitable que aparezca una situación en la que dos clases distintas reciban el mismo nombre. Si dos clases con el mismo nombre acaban en un mismo proyecto, el programa no compilará. La clase propia se puede renombrar, pero con una clase de una biblioteca ajena eso no funciona. Por eso, la exigencia de que los nombres sean únicos dificultaría mucho la reutilización del código de otros. + +Para resolver este problema, en Java se usan los **paquetes**. Un paquete es un mecanismo para reunir clases en grupos relacionados lógicamente. Los paquetes se parecen a las carpetas del sistema de archivos: igual que las carpetas organizan los archivos, los paquetes organizan las clases. Paquetes distintos pueden contener clases con el mismo nombre, y no habrá conflicto. + +## Definición de paquetes + +El paquete se indica con la palabra clave `package` al principio del archivo; justo después va el nombre del paquete: + +```java +// Archivo company/User.java +package company; + +public class User { + // código para trabajar con el usuario +} +``` + +La estructura de los paquetes está ligada a la estructura de archivos del proyecto: el nombre del paquete corresponde al directorio en el que está el archivo. Los paquetes pueden estar anidados; entonces los directorios también están anidados unos dentro de otros. Si una clase está en el paquete `io.hexlet.model`, el archivo se encuentra en el directorio `io/hexlet/model`. + +Normalmente el nombre del paquete empieza con un prefijo asignado a la empresa o al desarrollador, y lo más habitual es que sea el nombre de dominio en orden inverso. Por ejemplo, para el dominio `hexlet.io` los paquetes empiezan por `io.hexlet`. Después la estructura depende de la arquitectura de la aplicación: las clases se agrupan por su sentido; por ejemplo, en el paquete `model` se ponen las entidades principales, los usuarios y los cursos: + +```java +// Archivo io/hexlet/model/User.java +package io.hexlet.model; + +public class User { + public static String getGreeting(String userName) { + return "Hello, " + userName + "!"; + } +} +``` + +## Importación de clases + +Las clases de un mismo paquete se llaman entre sí simplemente por su nombre. Pero constantemente hay que usar también clases de otros paquetes. Para acceder a una clase de otro paquete hay que importarla; para eso sirve la palabra clave `import`, tras la cual va el nombre completo de la clase: + +```java +package io.hexlet; + +import io.hexlet.model.User; + +class App { + public static void main(String[] args) { + var greeting = User.getGreeting("John"); + System.out.println(greeting); + } +} +``` + +Después de la importación, a la clase se accede por su nombre corto. Sin la importación habría que escribir cada vez el nombre completo (fully qualified), incluido el nombre del paquete: + +```java +var greeting = io.hexlet.model.User.getGreeting("John"); +``` + +El nombre completo saca del apuro cuando en un mismo lugar se necesitan dos clases con el mismo nombre de paquetes distintos: una clase se importa y a la segunda se accede por su nombre completo. + +Se pueden importar a la vez todas las clases de un paquete con la ayuda de `*`: + +```java +import java.util.*; +``` + +Así es cómodo cuando del paquete se necesitan muchas clases, pero no conviene abusar de ello: importar «todo de golpe» ensucia el espacio de nombres y aumenta el riesgo de conflicto de nombres entre paquetes. + +## Importación estática + +Java permite importar no solo clases, sino también métodos estáticos concretos; entonces se pueden llamar sin indicar la clase. Esto es cómodo cuando algún método se usa a menudo, y hace el código más compacto: + +```java +import static java.lang.Math.ceil; + +public class App { + public static void main(String[] args) { + // El nombre de la clase Math se puede omitir en la llamada + double result = ceil(2.3); // 3.0 + System.out.println(result); + } +} +``` + +También se pueden importar a la vez todos los métodos estáticos de una clase: `import static java.lang.Math.*;`. La importación estática la usamos en el ejercicio de esta lección. diff --git a/modules/40-methods-definition/500-packages/es/data.yml b/modules/40-methods-definition/500-packages/es/data.yml new file mode 100644 index 00000000..d4d588f3 --- /dev/null +++ b/modules/40-methods-definition/500-packages/es/data.yml @@ -0,0 +1,15 @@ +--- +name: Paquetes +tips: + - > + [Ejemplo de aplicación en Java con paquetes e + importaciones](https://github.com/hexlet-boilerplates/java-package) +definitions: + - name: Paquete + description: >- + mecanismo para agrupar clases en grupos relacionados lógicamente; ayuda a + evitar conflictos de nombres. Se indica con la palabra clave `package`. + - name: import + description: >- + palabra clave que conecta una clase de otro paquete para acceder a ella + por su nombre corto, sin indicar el paquete. diff --git a/modules/40-methods-definition/description.en.yml b/modules/40-methods-definition/description.en.yml new file mode 100644 index 00000000..98ce9956 --- /dev/null +++ b/modules/40-methods-definition/description.en.yml @@ -0,0 +1,5 @@ +--- + +name: Defining methods +description: | + Defining your own methods makes writing and maintaining programs much easier. For example, the ability to define methods lets you combine complex (compound) operations into one — all the complexity can be hidden inside one simple method. By learning to create methods, you will take the first step towards building truly useful programs. And we will help you with that. In this module you will create your first method and learn how to give it (and variables along the way) understandable names.