You are on page 1of 15

1

Спрінт 5. Проектування методів з аргументами та з різними типами


повренення. Використання методів класу Math.

1. Проектування методу з аргументами, без повернення

Програмування схожих задач, розв'язок яких утворює сімейство схожих розв'язків,


часто спонукає знаходити універсальне рішення. Наприклад, нехай ми маємо дві
схожі задачі:

1 задача: треба вивести в консоль горизонтальну лінію довжиною 6 "зірочок".


2 задача: треба вивести в консоль горизонтальну лінію довжиною 10 "зірочок".

Задачі схожі, результат їх роботи (рішення) - візуалізація фігури "лінія", але різного
розміру. Тому, строго говорячи, задачі різні (бо розмір фігур різний), але в
загальному вони утворюють одне сімейство розв’язків: фігуру "лінія". Якщо б була
поставлена задача вивести в консоль фігуру "прямокутник" зірочками, то розв'язок
цієї задачі вже не відносився б до сімейства розв'язків попередньої задачі про
"лінію".

Отже, відмінність в розв'язку даних двох задач задачі полягає в різних розмірах
лінії. При цьому тип фігур залишається незмінний, тому алгоритм розв'язку
однаковий.

Код вирішення такої задачі може бути таким:

Результат роботи - дві лінії як розв'язки задачі 1 та 2:

Рядки коду 3-5 та 9-11 - ідентичні, окрім цифр 6 та 10, які регулюють довжину лінії.
Можна зробити висновок, що наведений код містить надлишковість, яка полягає в
"майже" ідентичних блоках коду 3-5 та 9-11

Як позбутися такої надлишковості? З минулих робіт вам відомий механізм -


винести однаковий код в інший метод (drawLine) та в потрібних місцях методу main
2

робити виклик цього методу. Але в даному випадку код "майже" однаковий, окрім
одного значення - розміру лінії (кількості "зірочек" в циклі). Що робити? Робити два
різних методи drawLine1 та drawLine2 - це не вихід, бо код залишиться з
надлишковістю. Вихід один - застосувати метод із вхідним параметром, який буде
керувати довжиною виводимої лінії. Часто слово "вхідний" опускають і говорять
просто "метод з параметром". Параметр - це змінна, додана до коду цього методу
в певному місці, яка приймає різні значення, і таким чином дозволяє змінювати
"масштаби" розв’язків.

Для початку проектування методу з параметром задачу треба параметризувати.


Тобто, знайти таку спільну характеристику окремих роз'вязків (блоки коду у р.3-5
та 9-11), яка приймає різні числові значення в різних розв'язках. Ця характеристика
для даної задачі - це розмір лінії. Вона і буде виступати параметром. Параметр
можна використати навіть і в коді з надлишковістю, що зробить його більш
"читабельним". Приклад нижче:

Для даного прикладу параметр отримав назву lineWidth (довжина лінії). lineWidth -
це змінна, яка для вирішення кожної з задач приймає різні значення: для
першої 6, для другої 10. Зверніть увагу що в р.3 здійснюється декларування цієї
змінної і присвоєння їй значення 6, а в р.11 - тільки присвоєння значення 10 (без
декларування). Так вимагає синтаксис цього коду.

Також зверніть увагу: коли код вирішення задачі параметризований, він вже
однаковий в обох розв'язках. Тобто, рядки 5-6 та 12-14 - містять один і той самий
код. І вже цей код можна спокійно винести в окремий метод. Але цей метод
потребує указання значення цього параметру, тобто змінної lineWidth. Це треба
правильно зробити, згідно синтаксису запису таких методів в Java.

Отже, наступний крок - це створення методу з параметром та винесення коду


розв'язку в цій метод. Після цього здійснюється виклик цього методу в потрібних
місцях. Готовий код показано нижче:
3

В р.10 записаний заголовок методу drawLine який приймає один формальний


параметр - змінну lineWidth типу int. В коді методу змінна параметру
використовується без декларування, бо її декларування знаходиться в заголовку
методу.

В точках виклику цього методу з методу main в якості актуального параметру (або
значення параметру) використовуються,в першому виклику цілочисельне значення
6, в другому виклику - число 10, яке також має тип int.

Кожний виклик методу приводить до виконання коду тілка методу (рядки 11-13),
але із різними значеннями змінної параметру lineWidth.

Результат роботи цього методу буде як і в попередніх версіях програми.

Переваги застосування методів з параметрами

Зверніть увагу не те, що ви два раза з методу main викликали метод drawLine,
передаючи йому різні значення параметру. Фактично, ви з методу main керували
роботою коду в методі drawLine, при різних значеннях параметру lineWidth. Але
окрім довжини лінії, можна керувати і іншими характеристиками лінії. Наприклад,
замість "*" малювати лінію іншим символом, заданим як параметр методу.
Подивіться на код нижче, там це реалізовано за допомогою нової версії методу
drawLine, яка оперує вже двома параметрами. Ми назвемо це метод drawLine2.
4

Результат роботи цього коду показаний нижче.

Для цього ми параметризували той код, який відповідає за вивід символа "*". Це
зроблено так: замість літерального указання символу "*" у методі printl(), ми
вказуємо змінну sym, яка виступає параметром даного методу, див. р.12 методу
drawLine2. Також ми додали в заголовок декларування параметрму з іменем sym
та типом даних String (бо ми будемо зберігати в змінній sysm один символ, який є
текстовим рядком довжиною 1 ). І під час виклику такого методу окрім довжини
лінії, задаємо текстовий символ, який будемо малювати лінії:
р.3: малює лінію методом drawLine2, довжиною 6 та символом "#";
р.5: малює лінію методом drawLine2, довжиною 11 та символом "-";
р.7: малює лінію методом drawLine2, довжиною 3 та символом "+".

Отже, ми розширили набір характеристик лінії, якими ми можемо керувати з


методу main. Якщо узагальнити це твердження, то вводячи більше параметрів, ми
можемо більш гнучко керувати кодом розв'язку певної задачі, тобто рішенням
задачі.

Давайте зробимо ще більше параметризації!

Розробимо додаткову версію методу по виводу лінії, але додамо два параметри,
які керують зображенням першого та останнього символів.
5

Код методу drawLine3 наведено нижче.

Напишіть такий код в методі main :

Результат роботи такої програми має бути таким:

Тобто, ми отримали можливість керувати не тільки зображенням символу, який


малює самі лінію, а і ще символами початку та кінця лінії.
Погодьтесь, це зручно.

2. Перевантажені методи

Перевантажені методи-це такі методи, які мають одне і те саме ім'я, але різну
кількість параметрів в заголовку методу.
Методи drawLine3, drawLine2 та drawLine по суті виконують одну і ту саму задачу-
малюють лінію певного розміру. Чи вони відрізняються- різною кількістю вхідних
параметрів, див. рисунок нижче. Тип повернення в них один і той самий, void
(детально про тип повернення в наступному розділі). Тому ми можемо імена цих
методів зробити однаковими, як показано на рисунку.
6

Відповідно, коди цих методів будуть такі:

1. public class DrawLines3 {


2. public static void main(String[] args) {
3. drawLine(5,"+","|","o");
4. System.out.println();
5. drawLine(9,"+","|","o");
6. System.out.println();
7. drawLine(11,"+","|","o");
8. System.out.println();
9. drawLine(8,"+","|","o");
10. System.out.println();
11. drawLine(3,"+","|","o");
12. }
13.
14. public static void drawLine(int lineWidth, String sym, String
startSym, String endSym)
15. {
16. System.out.print(startSym);
17.
18. for (int i = 2; i <= lineWidth-1; i++) {
19. System.out.print(sym);
20. }
21.
22. System.out.print(endSym);
23. }
24.
25.
26. public static void drawLine(int lineWidth, String sym) {
27. for (int i = 1; i <= lineWidth; i++) {
28. System.out.print(sym);
29. }
30. }
31.
32.
33.
34. public static void drawLine(int lineWidth) {
35. for (int i = 1; i <= lineWidth; i++) {
36. System.out.print("*");
37. }
38. }
39.
40. }
7

Має змінитись і код методу main-методи, які викликаються мають вже однакове
ім'я drawLine, але різну кількість та тип вхідних параметрів. Саме по кількості і типу
вхідних параметрів компілятор Java, під час компіляції, визначає, який метод
треба викликати.

2. Проектування методів з поверненням значення

Методи, які були розроблені до цього, не повертали значення в точку виклику.


Вони здійснювали певну корисну роботу (друк символів в консолі і т.п.), але з точки
зору синтаксису, їх застосування не передбачало отримання значення від роботи
цього методу. Тепер розглянемо методи, які повретають значення. Спочатку
зрозуміємо ідею їх використання. В Java є доволі багато таких методів,
розміщених в різних класах. Один з таких класів це клас Math з
пакету java.lang, вя кому є методи, що здійснюють обчислення різних
математичних функцій. Відповідно, є результат обчислення, який повертається в
програму.

В таблиці нижче наведений перелік найбільш уживаних методів, з описом того, що


вони роблять.

Таблиця. Найбільш розповсюджені математичні функції з класу Math.


Тип Тип
Методи Приклад
аргумент результат Опис
класу застосування
у у
abs(10) →10
abs( a ) int int Повертає абсолютне int значення a
abs(-5) →5
abs( a ) long long Повертає абсолютне long значення a
abs( a ) float float Повертає абсолютне float значення a
Повертає абсолютне double значення
abs( a ) double double
a
Повертає арккосінус від a
acos( a ) double double acos(-1) → 3.14159
(а задається в радіанах)
Повертає арксінус від a
asin( a ) double double asin(1) → 1.57079
(а задається в радіанах)
Повертає арктангенс від a
atan( a ) double double atan(1) → 0.785398
(а задається в радіанах)
Повертає найменше ціле число, яке бі ceil(5.6) → 6.0
ceil( a ) double double льше ceil(5.0) → 5.0
або дорівнює a ceil(-5.6) → -5.0
Повертає тригонометричний косінус ві
cos( a ) double double дa cos(-pi/2) → 0.0
(а задається в радіанах)
Повертає натуральне число e (2.718 .
exp(2) → 7.38905609
exp( a ) double double . . ),
9
піднесене до ступеня a
Повертає найбільше ціле число, яке м floor(5.6) → 5.0
floor( a ) double double енше floor(5.0) → 5.0
або дорівнює a floor(-5.6) → -6.0
Повертає значення натурального лога
log( a ) double double log(2.7183)→ 1.0
рифму (з основою е) від а
8

max( a, b ) int int Повертає найбільше між a та b max(10, 20) → 20


max( a, b ) long long Повертає найбільше між a та b
max( a, b ) float float Повертає найбільше між a та b
min( a, b ) int int Повертає найменше між a та b min(10, 20) → 10
min( a, b ) long long Повертає найменше між a та b
min( a, b ) float float Повертає найменше між a та b
Повертає число a, піднесене до ступе
pow( a, b ) double double pow( 2.0, 3.0) → 8.0
ня b
Генерує та повертає випадкове число,
random( ) <none> double яке
більше або дорівнює 0.0 та менше 1.0
Повертає int значення від числа a, round(5.6) → 6
round( a ) float int округлене до найближчого цілого числ round(5.4) → 5
а round(-5.6) → -6
Повертає long значення від числа a,
double long округлене до найближчого цілого числ
а
Повертає тригонометричний сінус від
sin( a ) double double а sin(pi/2 ) → 1.0
(а задається в радіанах)
sqrt( a ) double double Повертає квадратний корінь від а
Повертає тригонометричний тангенс ві
tan( a ) double double да tan(pi/4) → 1.0
(а задається в радіанах)
Конвертує заданий в радіанах кут a у toDegrees(pi/4) → 45.
toDegrees( a ) double double
градуси 0
Конвертує заданий в градусах кут a у toRadians(90.0)→ 1.5
toRadians( a ) double double
радіани 707963

Також в класі Math є дві константи:

Зверніть увагу на те, як у виразі посилаються на методи класу та константи


класу. Синтаксис такий:

для методів

Math.<method name>( <arguments> )

і так для констант:

Math.<class constant>

Наприклад, щоб записати у коді математичну формулу


9

нам потрібні:
1) функції (метод) обчислення сінусу;
2) функція (метод) обчислення квадратного кореня;
3) константа "пі".

Клас Math з пакету java.lang містить все потрібне з заданого переліку. Із


застосуванням методів класу Math вищезгадана формула набуде вигляду у коді
Java:

(1.0 /2.0) * Math.sin( x - Math.PI / Math.sqrt(y) )

Звісно, змінні x та y мають містити якісь значення, щоб таке обчислення вдалось
здійснити. Повний код програми може бути таким:

Перехід на новий рядок у виводу (символ "\n" у рядку коду 10) здійснено задля
зручності виводу, щоб не розтягувати вивід на всю ширину екрану.

Слід звернути увагу, що параметром для sin, cos, та tan є кут в радіанах.
Значення, яке повертається від методів asin, acos, та
atan, є кут в радіанах, в діапазоні від до . Один градус дорівнює
радіан.

Наприклад, наступний код дозволяє побачити роботу всіх тригономентричних


методів.
10

Зверніть увагу на р.3: застосовується метод перетворення градусів із радіан у


звичайні градуси.
У р.4 застосовується перетворення градусів у радіани.

Наступний блок методів дозволяє здійснювати округлення. Це методи ceil, floor,


rint, round. Слід бути уважним саме з методом round: хоча він і повертає ціле
число, але воно має тип даних long. Це примітивний тип даних, який зберігає
цілочисельне значення, але займає 8 байт пам'яті. Для роботи з типами int, треба
здійснити кастінг до int.

Цікавими є методи min, max визначення мінімального та максимального з двох


чисел, переданих в параметрах. Методи min та max перевантажені для
повернення мінімального та максимального чисел з переданих чисел у різних
11

типах int, long, float, або double. Наприклад, max(3.4, 5.0) повертає 5.0, та min(3, 2)
повертає 2.

І метод abs, який присутній також у перевантажених варіантах, повертає


абсолютне значення числа, переданого в параметрі, і типах int, long, float, або
double). Наприклад,

Але особливе місце серед усіх методів займає метод random(). Цей метод
застосовується для генерації довільних чисел типу double які дорівнюють або
більше за 0.0 але менше за 1.0 (0 <= Math.random() < 1.0). Цей метод є дуже
корисним в задачах моделювання процесів та комп'ютерних іграх. Для генерації
довільних чисел в різних діапазонах, застосовуються такі вирази:

(int) (Math.random( ) * 10) -> повертає ціле число з діапазону [0;9].


50 + (int) (Math.random( ) * 50) -> повертає ціле число з діапазону
[50;99].

Взагалі, вираз a + (int) (Math.random( ) * b) повертає число з діапазона


[a; b].

На базі цього методу можна розробити метод, який буде імітувати підкидування
ігрового кубіка. Кубік має 6 граней, на кожній з них нанесена відповідна кількість
точок. Результатом підкидання кубіка вважається значення тіє
ї грані, яка буде зверху. Кожна грань "випадає" з рівною імовірністю. Отже,
можливий спектр "випавших" граней, описаний числами, буде такий: [1,2,3,4,5,6],
або [1;6]

Для імітації цього пролцесу на комп'ютері, можна застосувати метод random( ),


який як раз і може генерувати кожне число з певного діапазону з однаковою
імовірністю. Але для того, щоб це число попадало в діапазон
можливих значень [1;6], слід застосувати відповідну формулу. Код нижче
дозволяє це зробити. Для генерації саме таких чисел, застосовується метод, який
повертає значення.
12

Результат роботи програми можу бути таким:

Звертаємо увагу, що кожний виклик методу diceRoll(), призводить до генерації


нового числа, що імітує номер грані кубіка. Це саме завдяки тому, що кожний
запуск метода Math.random( ) повертає нове випадкове число з діапазону [0;1).
На цьому принципі базується імітація різноманітної поведінки персонажів
комп'ютерних ігор, працюють різні програми по імітаційному моделюванню
випадкових процесів і т.п.
13

Спрінтовий програмний проект №5

Надайте відповіді на питання:

1. Що таке параметр, як здійснюється параметризація в задачі та коді.


2. Як працює метод з поверненням.
3. Що таке перевантаження методів.
4. Які основні методи та константи бібліотеки Math, як їми користуватись.

Завдання програмного проекту

Розв'яжіть наступні задачі.

1. День тижня. Напишіть програму, в якій розроблений та застосовується метод


dayOfWeek(…), який приймає дату як вхідний параметр і повертає день тижня, на
який припадає ця дата. Ваш метод має приймати три вхідних аргументи: m
(місяць), d (день) і y (рік) відповідних типів даних. Для m використовуйте: 1 для
січня, 2 для лютого і так далі. Метод має повернути цілі числа: 0 для неділі, 1 для
понеділка, 2 для вівторка і так далі. Використовуйте такі формули григоріанський
календар для розрахунків (де / позначає цілочисельний ділення, mod - операція
ділення за модулем):

Приклад обчислення за формулами для обчислення дня тижня дла дати: 14


лютого 2000 року.

y0 = 2000 - 0 = 1999
x = 1999 + 1999/4 - 1999/100 + 1999/400 = 2483
m0 = 2 + 12*1 - 2 = 12
d0 = (13 + 2483 + (31*12) / 12) mod 7 = 2528 mod 7 = 1 (Monday)

Здійсніть тестування методу на даті 14 лютого 2000 року, та поточній (на день
розробки програми).

2. Результат підкидування двох кубіків. Напишіть програму, в якій розроблений


та застосовується метод sumOfTwoDice, який імітує кидок двох кубиків. Цей метод
повинен повертати результат підкидування двох ігрових шостигранних кубіків.
Здійсніть тестування методу, підкинувши кубіки 25 разів.

3. Обчислення довжини відрізка. Напишіть програму, в якій розроблений та


застосовується метод distance, який приймає координати двох точко на площині.
Точки задаються парами координат (x1, y1) та (x2, y2). Координати мають
задаватись дійсними числами. Рівняння для обчислення довжини відрізка має
такий вигляд:
14

Протестуйте програму на відрізках, які мають зазделегідь відому величину


(вертикальне або горизонтальне положення відрізка з цілочисельно заданими
координатами).

4. Швидкість руху супутника Землі. Швидкість супутника, що обертається


навколо Землі, обчислюється за формулою

,
де
— маса Землі,

r — відстань від центру Землі до супутника в метрах, а

всесвітня гравітаційна стала.

Одиницею швидкості v є м/с.

Напишіть програму, в якій присутній метод satelliteSpeed(), який приймає


відстань d від поверхні Землі (задану в метрах) до супутника і повертає швидкість
супутника (в метрах).

Підтвердіть той факт, що супутник, який знаходиться ближче до поверхні Землі,


рухається швидше.

Визначте символічні константи для Me і G як статичні константи методі.


Зверніть увагу, вам, можливо, знадобиться застосувати радіус Землі, якій
дорівнює 6.3781×106 m.

Для прикладу, відстань до космічного телескопа Хаббла від центру Землі


становить приблизно

5. Числа Фібоначчі. Леонардо Фібоначчі з Пізи був одним із найвидатніших


математиків Середньовіччя. Він найбільш відомий, мабуть, завдяки послідовності
Фібоначчі, яку можна застосувати до багатьох різноманітних задач. Одним із
кумедних застосувань послідовності Фібоначчі є визначення швидкості росту
кроликів.

Припустімо, що пара кроликів дорослішає за 2 місяці, і здатна відтворювати ще


одну пару щомісяця, після власного дорослішання. Якщо кожна нова пара має
однакову здатність, скільки пар буде через 1 рік? (Ми припускаємо, що жодна пара
не гине.) У таблиці нижче показано послідовність для перших 7 місяців. Зауважте,
що наприкінці другого місяця перша пара дозріває і народжує своє перше
потомство на третьому місяці, тобто всього дві пари.
15

Послідовніть у другому стовпчику має назву послідовності Фібоначчі. Як її


обчислювати? N - те число Фібоначчі в послідовності обчислюється за формулою:

Напишіть програму, в якій є метод fibonacchi(), який отримує на вхід N та


повертає . Звертаємо увагу, що обчислення за допомогою класа Math можуть
дати результат із типом double, але ви маєте перетворити його на ціле число, для
відображення.

Ваша програма має відобразити таблицю, як на прикладі вгорі.

You might also like