Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions modules/40-methods-definition/500-packages/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import static java.lang.Math.ceil;

public class App {
public static int amountPerPerson(double total, int people, int tipPercent) {
// BEGIN
double withTip = total * (1 + tipPercent / 100.0);
return (int) ceil(withTip / people);
// END
}
}
2 changes: 2 additions & 0 deletions modules/40-methods-definition/500-packages/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
test:
@ test.sh
10 changes: 10 additions & 0 deletions modules/40-methods-definition/500-packages/Test.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import static org.assertj.core.api.Assertions.assertThat;

class Test {
public static void main(String[] args) {
assertThat(App.amountPerPerson(300, 4, 0)).isEqualTo(75);
assertThat(App.amountPerPerson(300, 4, 20)).isEqualTo(90);
assertThat(App.amountPerPerson(350, 3, 10)).isEqualTo(129);
assertThat(App.amountPerPerson(100, 3, 0)).isEqualTo(34);
}
}
10 changes: 10 additions & 0 deletions modules/40-methods-definition/500-packages/ru/EXERCISE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Реализуйте метод `amountPerPerson()`. Он принимает сумму счета в ресторане `total`, количество человек `people` и процент чаевых `tipPercent`, а возвращает сумму, которую платит каждый. Итог округляется **вверх** — никто не должен недоплатить.

Для округления вверх используйте метод `ceil()`. Он уже подключен в начале файла статическим импортом из класса `Math`, поэтому вызывать его можно без префикса `Math.`.

```java
App.amountPerPerson(300, 4, 20); // => 90
App.amountPerPerson(350, 3, 10); // => 129
```

Сначала посчитайте итоговую сумму с чаевыми, затем разделите ее на количество человек и округлите вверх. Результат метода `ceil()` имеет тип `double`, а вернуть нужно `int` — не забудьте про приведение типа.
84 changes: 84 additions & 0 deletions modules/40-methods-definition/500-packages/ru/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
Когда программа растет, в ней становится не только больше строк кода, но и больше классов. Каждый класс решает свою задачу и лежит в отдельном файле, а в реальном приложении таких файлов могут быть сотни и тысячи. Часть классов пишут сами, часть приходит вместе с подключенными библиотеками.

При таком количестве классов почти неизбежно возникает ситуация, когда два разных класса получают одинаковые имена. Если два класса с одинаковым именем оказываются в одном проекте, программа не скомпилируется. Свой класс переименовать можно, а вот с классом из чужой библиотеки так не получится. Поэтому требование уникальности имен сильно мешало бы переиспользовать чужой код.

Чтобы решить эту проблему, в Java используют **пакеты**. Пакет — это механизм для объединения классов в логически связанные группы. Пакеты похожи на папки в файловой системе: как папки организуют файлы, так пакеты организуют классы. Разные пакеты могут содержать классы с одинаковыми именами, и конфликта не возникнет.

## Определение пакетов

Пакет задают ключевым словом `package` в самом начале файла, сразу после него идет имя пакета:

```java
// Файл company/User.java
package company;

public class User {
// код для работы с пользователем
}
```

Структура пакетов связана с файловой структурой проекта: имя пакета соответствует директории, в которой лежит файл. Пакеты бывают вложенными — тогда и директории вложены друг в друга. Если класс лежит в пакете `io.hexlet.model`, то и файл находится в директории `io/hexlet/model`.

Обычно имя пакета начинают с префикса, закрепленного за компанией или разработчиком, — чаще всего это доменное имя в обратном порядке. Например, для домена `hexlet.io` пакеты начинаются с `io.hexlet`. Дальше структура зависит от архитектуры приложения: классы группируют по смыслу, например в пакет `model` складывают основные сущности — пользователей и курсы:

```java
// Файл io/hexlet/model/User.java
package io.hexlet.model;

public class User {
public static String getGreeting(String userName) {
return "Hello, " + userName + "!";
}
}
```

## Импорт классов

Классы из одного пакета обращаются друг к другу просто по имени. Но постоянно приходится использовать и классы из других пакетов. Чтобы обратиться к классу из другого пакета, его нужно импортировать — для этого служит ключевое слово `import`, после которого идет полное имя класса:

```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);
}
}
```

После импорта к классу обращаются по короткому имени. Без импорта пришлось бы каждый раз писать полное (fully qualified) имя, включая название пакета:

```java
var greeting = io.hexlet.model.User.getGreeting("John");
```

Полное имя выручает, когда в одном месте нужны два класса с одинаковым именем из разных пакетов: один класс импортируют, а ко второму обращаются по полному имени.

Можно импортировать сразу все классы пакета с помощью `*`:

```java
import java.util.*;
```

Так удобно, когда из пакета нужно много классов, но злоупотреблять этим не стоит: импорт «всего подряд» захламляет пространство имен и повышает риск конфликта имен между пакетами.

## Статический импорт

Java позволяет импортировать не только классы, но и отдельные статические методы — тогда их можно вызывать без указания класса. Это удобно, когда какой-то метод используется часто, и делает код компактнее:

```java
import static java.lang.Math.ceil;

public class App {
public static void main(String[] args) {
// Имя класса Math при вызове можно опустить
double result = ceil(2.3); // 3.0
System.out.println(result);
}
}
```

Можно импортировать и сразу все статические методы класса: `import static java.lang.Math.*;`. Статический импорт мы используем в задании этого урока.
15 changes: 15 additions & 0 deletions modules/40-methods-definition/500-packages/ru/data.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
name: Пакеты
tips:
- >
[Пример приложения на Java с пакетами и
импортами](https://github.com/hexlet-boilerplates/java-package)
definitions:
- name: Пакет
description: >-
механизм группировки классов в логически связанные группы; помогает
избежать конфликтов имен. Задается ключевым словом `package`.
- name: import
description: >-
ключевое слово, которое подключает класс из другого пакета, чтобы
обращаться к нему по короткому имени без указания пакета.
Loading