Урок 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();
}
}