Урок 03 - Оператори в Java. Частина 1.
У відеоуроці:
Які є оператори в Java? Арифметичні оператори та оператори присвоєння. Оператор залишку від ділення по модулю, оператор присвоєння, короткі оператори присвоєння.
-->
// звичайне створення об'єкту Soldier
Soldier s = new Soldier("Солдат");
// об'єктна змінна типу Soldier посилається на об'єкт типу General
Soldier s2 = new General("Генерал");
// !!! Помилка приведення типу (солдат не генерал)
General g=new Soldier("Солдат");Можна спробувати здійснити приведення до типу General, компілятор пропустить, проте під час виконання програми знову ж виникне помилка приведення типу (виняток виду: java.lang.ClassCastException:
osvjava.ua.Soldier cannot be cast to osvjava.ua.General ): General g=(General)new Soldier("Солдат"); // ПОМИЛКА ВИКОНАННЯ!!!Проте коли ми звертаємося до Генерала як до Солдата, то і функціональні можливості Генерала звужуються. Ми можемо викликати методи класу Солдат, проте з методами класу Генерал будуть проблеми. Наприклад, в класі Soldier є метод getHealth(), а в класі General є метод getSlogan():
//змінна sg посилається на об'єкт типу General
Soldier sg= new General("Генерал"); sg.getHealth(); //методи класу Soldier доступні // sg.getSlogan(); //методи класу General недоступніПроте, якщо б метод getSlogan був би у класі Soldier, то викликана б була версія методу getSlogan класу General, оскільки при поліморфізмі заміщення методів все ж відбувається (крім статичних методів).
General general=(General)sg; // наш Генерал тепер повноцінний general.getSlogan(); // метод класу General доступний
System.out.println(sg.getClass()); // результат: class osvjava.ua.GeneralВласне об’єктні змінні класу Object доволі часто застосовується з метою збереження посилань на інші класи. Це дозволяє одночасно працювати з різнотипними об’єктами. Наприклад, можна, тримати різнотипні об’єкти в одному масиві типу Object. Також використання поліморфних об’єктних змінних дозволяє створювати своєрідні універсальні класи та методи (узагальнене програмування). Таким чином непотрібне створення великої кількості перевантаження методів з різним типом параметрів. Власне практично всі внутрішні бібліотеки Java спочатку будувалася таким чином. Щоправда, використання поліморфних змінних може слугувати джерелом багатьох помилок, тому в Java починаючи з JSE 5.0 у мову введено так звані Узагальнення (Generics), які дозволяють більш краще будувати такі універсальні засоби (дивіться детальніше відповідний розділ даного вікіпідручника). Приклади використання поліморфізму
package osvjava.ua; import java.util.Random; public class Soldier { protected int health; // здоров'я солдата protected boolean alive = false; // стан (живий чи мертвий) protected int defense = 0; // захист від ударів protected static int count = 0; // лічильник створених об’єктів private int id = 0; // кожен солдат матиме порядковий номер (П№) protected String rank; // ранг солдата ("Солдат", "Генерал", "Сержант" тощо) /** Конструктор * @param rank - ранг солдатау */ public Soldier(String rank) { this.rank=rank; id = ++count; // збільшити count на 1 та присвоїти id; health = 100; // встановлюємо рівень здоров'я alive = true; // оживляємо солдата //надаємо солдату рівень захисту випадковим чином (від 0 до 50) Random randomGen = new Random(); defense = randomGen.nextInt(50); System.out.println(rank+" П№" + id + " is greated: health=" + health + ", defense=" + defense); } /** * @return здоров'я солдата */ public int getHealth() { return health; } /** Дозволяє солдату отримувати пошкодження * @param hit - сила удару * Метод приватний оскільки отримання удару можливе лише через метод hit() */ private void receiveHit(int hit) { if (isAlive() == true) { // обчислюємо пошкодження int damage = defense - hit; // якщо удар пробив захист солдат отримує пошкодження if (damage > 0) { health = health - damage; } else { return; // вийти з методу } //якщо солдат загинув, то вивести відповідне повідомлення //в іншому випадку вивести рівень його здоров'я if (health <= 0) { alive = false; System.out.println("[X] "+rank+" П№" + id + " отримав пошкодження " + damage + " і героїчно загинув"); } else { System.out.println(rank+" П№" + id + " отримав пошкодження " + damage + ". Залишилось здоров'я " + health); } } } /** Метод для нанесення удару * @param targetSoldier - кого вдарити * @param hit - сила удару */ public void hit(Soldier targetSoldier, int hit) { targetSoldier.receiveHit(hit); } /** * Перевіряємо стан солдата * @return живий(true), ні (false) */ public boolean isAlive() { return alive; } /** * Повертає порядковий номер солдата * @return id */ public int getId() { return id; } /** * Заміщення методу toString класу Object * @return опис солдата */ @Override public String toString() { return rank+" П№" + id + ": здоров'я=" + health + ", захист=" + defense; } }
//TestBattle.java package test.ua; import java.util.Random; import osvjava.ua.Soldier; public class TestBattle { Soldier s1=new Soldier("Солдат"); Soldier s2=new Soldier("Солдат"); public TestBattle() { battle (s1, s2); } public void battle(Soldier s1, Soldier s2) { // бій допоки не виживе хтось один, // сила удару встановлюється випадковим чином Random gen = new Random(); while ((s1.isAlive() == true) && (s2.isAlive() == true)) { s1.hit(s2, gen.nextInt(100)); if (s2.isAlive()) { //якщо другий загинув, то мертві не воюють s2.hit(s1, gen.nextInt(100)); } } //виводимо переможця if (!s1.isAlive()) { // idWinner = soldiers[0].getId(); System.out.println("***** Кінець бою. Переміг " + s2 + " *****"); } else System.out.println("***** Кінець бою. Переміг " + s1 + " *****"); } public static void main(String[] args) { // створюємо об’єкт даного класу, виконання продовжиться з конструктора new TestBattle(); } }
Солдат П№1 is greated: health=100, defense=10 Солдат П№2 is greated: health=100, defense=27 Солдат П№1 отримав пошкодження 9. Залишилось здоров'я 91 Солдат П№2 отримав пошкодження 18. Залишилось здоров'я 82 Солдат П№2 отримав пошкодження 19. Залишилось здоров'я 63 Солдат П№1 отримав пошкодження 2. Залишилось здоров'я 89 Солдат П№2 отримав пошкодження 17. Залишилось здоров'я 46 Солдат П№1 отримав пошкодження 6. Залишилось здоров'я 83 Солдат П№2 отримав пошкодження 4. Залишилось здоров'я 42 Солдат П№2 отримав пошкодження 11. Залишилось здоров'я 31 Солдат П№1 отримав пошкодження 1. Залишилось здоров'я 82 Солдат П№2 отримав пошкодження 4. Залишилось здоров'я 27 Солдат П№2 отримав пошкодження 23. Залишилось здоров'я 4 Солдат П№1 отримав пошкодження 8. Залишилось здоров'я 74 [X] Солдат П№2 отримав пошкодження 5 і героїчно загинув ***** Кінець бою. Переміг Солдат П№1: здоров'я=74, захист=10 *****
// Sergeant.java package osvjava.ua; public class Sergeant extends Soldier { public Sergeant(String rank){ // спочатку створюється солдат, на основі якого створюється наш сержант super(rank); // збільшуємо здоров'я сержанта у 10 раз super.health=super.health*10; System.out.println("Здоров'я сержанта збільшено в 10 раз"); } }
Сержант П№1 is greated: health=100, defense=45 Здоров'я сержанта збільшено в 10 раз
//General.java package osvjava.ua; public class General extends Soldier { private String slogan = "Ніколи не здаватись"; // Лозунг генерала /** Конструктор * @param rank - ранг солдата ("Генерал") */ public General(String rank) { // спочатку створюється солдат, на основі якого створюється наш генерал super(rank); // збільшуємо здоров'я генерала у 100 раз super.health = super.health * 100; System.out.println("Здоров'я генерала збільшено у 100 раз"); } /** Тепер заміщується метод toString класу Soldier * @return Стан генерала із лозунгом */ @Override public String toString() { return "Генерал із здоров'ям " + super.health + " його лозунг: " + slogan; } /**Отримати лозунг генерала * @return лозунг */ public String getSlogan() { return slogan; } }
Sergeant ser=new Sergeant ("Сержант"); General gen=new General ("Генерал"); battle (ser, gen):
Сержант П№1 is greated: health=100, defense=12 Здоров'я сержанта збільшено в 10 раз Генерал П№2 is greated: health=100, defense=29 Здоров'я генерала збільшено у 100 раз Сержант П№1 отримав пошкодження 1. Залишилось здоров'я 999 Генерал П№2 отримав пошкодження 4. Залишилось здоров'я 9996 ... Сержант П№1 отримав пошкодження 12. Залишилось здоров'я 4 Генерал П№2 отримав пошкодження 20. Залишилось здоров'я 5173 Генерал П№2 отримав пошкодження 6. Залишилось здоров'я 5167 [X] Сержант П№1 отримав пошкодження 8 і героїчно загинув ***** Кінець бою. Переміг Генерал із здоров'ям 5167 його лозунг: Ніколи не здаватись *****
package osvjava.ua; public class Army { protected int num=99; protected Soldier[] soldiers; static int count=0; public Army() { soldiers=new Soldier[num]; } /** Метод зарахування солдата в армію * @param soldier * @return true - солдата додано, false - помилка */ public boolean addSoldier(Soldier soldier) { if (count>=num) return false; this.soldiers[count]=soldier; count++; return true; } /** Підрахунок здоров'я армії * @return Сумарне здоров'я усіх солдат в армії */ public int calcArmyHealth() { int armyHealth=0; for (int i = 0; i < count; i++) { armyHealth+=soldiers[i].getHealth(); } return armyHealth; } }
package test.ua; import java.util.Random; import osvjava.ua.Army; import osvjava.ua.General; import osvjava.ua.Sergeant; import osvjava.ua.Soldier; public class TestBattle2 { Sergeant ser=new Sergeant ("Сержант"); General gen=new General ("Генерал"); Soldier[] s= new Soldier[100]; Army army=new Army(); public TestBattle2() { s[0] = new Soldier("Солдат"); s[1] = new Soldier("Солдат"); s[2] = new Soldier("Солдат"); s[3] = new Soldier("Солдат"); army.addSoldier(battle (ser, gen)); army.addSoldier(battle (s[0], s[1])); army.addSoldier(battle (s[2], s[3])); System.out.println("Сумарне здоров'я армії "+ army.calcArmyHealth()); } public Soldier battle(Soldier s1, Soldier s2) { // бій допоки не вижеве хтось один, // сила удару встановлюється випадковим чином Random gen = new Random(); while ((s1.isAlive() == true) && (s2.isAlive() == true)) { s1.hit(s2, gen.nextInt(100)); if (s2.isAlive()) { //якщо другий загинув, то мертві не воюють s2.hit(s1, gen.nextInt(100)); } } //виводимо переможця if (!s1.isAlive()) { // idWinner = soldiers[0].getId(); System.out.println("***** Кінець бою. Переміг " + s2 + " *****"); return s2; } else{ System.out.println("***** Кінець бою. Переміг " + s1 + " *****"); return s1; } } public static void main(String[] args) { new TestBattle2(); } }