понеділок, 23 грудня 2013 р.

Мічіо Кайку – Фізика майбутнього

Почав читати Мічіо Кайку "Фізика майбутнього". На книгу натрапив в книгарні Є. Дещо вагався
потрібна вона мені чи ні. На полиці і так лежить недочитані "Тиранія ринку" та "Теорія Брехні". Проте все ж придбав і не пожалів.

Попри страшне слово "фізика" у назві, книга не містить жодної формули і написана в доступній формі для широкого загалу. Написано про те як може помінятися світ в найближчі 100 років. Раджу читати всім, особливо науковцям і програмістам:). Кайку сам фізик і пишучи книгу він не видумував майбутнє у стилі фантастів, а спирався на уже існуючі прототипи певних технологій. В книзі ви знайдете чимало згадок про них. При написанні Він радився з науковцями, що займалися тими речами про що він писав. І це відрізняє книгу від недолугих опусів журналістів та різних любителів пописати про майбутнє.І найголовніше не обов'язково її читати із самого початку, можна починати читати з будь-якої сторінки.

Я ще недочитав її, але хочеться вже її похвалити і навести дещо з того, що прогнозує автор.

Чіпи у всьому. До 2020 року чіпи максимально здешевляться (десь до 1 цента) і їх будуть вставляти у все що тільки можна: окуляри, стіни, крісла, одяг і навіть тіло. 

Інтернет-повсюди. Усі речі і навіть тіла(з медичною метою) матимуть підключення до глобальної мережі.

Зручне медичне домашнє діагностичне і лікувальне обладнання. Усе що потрібно для діагностики хвороби і її лікування можна буде отримувати дома (переносні персональні томографи). З лікарем спілкування відбуватиметься віртуально. І навіть лікаря в більшості випадків зможуть заміняти автоматичні програми.

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

Екрани-шпалери. Це мені найбільше сподобалося. Замість шпалер можна буде клеїти екрани і створювати будь-яке зображення на стінах, навіть рухоме. Уже зараз є прототипи плівчастих екратів, в майбутньому екранами будуть стіни, вікна, двері, стеля.


Читання-думок. Керування розумними речами можна буде здійснювати навіть не словесно, а подумки.

Лінзи - екрани. Уже зараз ведуться розробки над окулярами та лінзами, які можуть слугувати для перегляду зображень. В результаті в комплексі з іншими засобами і поширенням інтернету вчителям в школам та викладачам прийдеться змінювати підходи до перевірки знань учнів та студентів. Їм прийдеться зосередитися на перевірці умінь думати та аргументувати. Учні запросто зможуть отримувати усе з інтернету непомітно від викладача/вчителя, безпосередньо під час контрольної, екзамену чи навіть під час спілкування з ним.

Люди-боги: До 2100 року завдяки тим же чіпам і безпровідному зв'язку та іншим технологіям, люди зможуть вести спосіб життя, що нагадуватиме життя богів на олімпі.

Можлива деградація. Кайку також піднімає цікаве питання, що буде коли замість купляти речі, люди створюватимуть усе потрібне у себе вдома за допомогою нових технологій, які оточуватимуть їх скрізь.  Людям не потрібно буде надто старатись для отримання певних речей і навіть гроші скоріш за все втратять сенс. Чи не деградує людство із зникненням мотивації до діяльності. На це питання так відповіді і не дано

Тож як я вже казав раджу читати всім. Цікаве, якісне і корисне чтиво. Я би  цю книгу ввів в шкільну програму.

Мічіо Кайку "Фізика майбутнього"

Сумна історія нашої мікроелектроніки

Натрапив на статтю в журналі "Економіст" за 1997 рік  "Наша електроніка була гіганською" авторства Августімова В. Л. Автор очолював цілий ряд підприємств пов'язаних з мікроелектронікою за часів СРСР і на початку незалежності, тож його думці можна довіряти.  Власне весь випуск журналу було присвячено сумному стану мікроеклектроніки в 1997 році, коли вона ще в нас хоч якось існувала. Стаття в черговий раз переконала мене в недосконалості планової економіки СССР і тому як у нас не вміють мислити на перспективу.

Власне це підтверджує не тільки дана стаття, але й книги по історії комп'ютерної техніки в Україні і в Союзі загалом. Зокрема свого часу я читав декілька книг присвячених В.М. Глушкову, людині, що після від'їзду Лєбєдєва з Києва, очолила нашу українську кібернетику і по суті за його керівництва в Києві була створена потужна комп'ютерна галузь. У нас створювались власні, оригінальні комп'ютери і усе що з ними було пов'язано. В 70-х роках поки комп'ютери в світі розвивалися відносно повільно  ми успішно конкурували із західними взірцями комп'ютерної техніки. Проте уже на початку 80-х ми почали відставати. СРСР повністю перейшов на копіювання американських комп'ютерів.  Закордонні новинки детально вивчалися і створювалися власні копії. Звичайно, що на це був потрібен час і ми постійно ішли по заду. Копіюванням займалися наукові установи Києва, Москви та Мінська.

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

У вищезгаданій журнальній статті наводиться такий приклад "...мікрохвильових печей не було, тому що не було поставлено такого завдання, а коли це втямили наші керівники, союз вже почав розпадатись". Ці слова показують увесь стан справ в цілому. Нормальний розвиток науки і високих технологій можливий лише в конкурентних ринкових умовах. Власне Китай тому і перейшов на капіталізм, оскільки їхні керівники добре зрозуміли до чого усе йде, та й торгівля у них в крові давно. До цього Китай пережив усе те що і ми в союзі і воєнний комунізм і голодомор за його загинуло до 35 мільйонів людей і всі інші переваги комуністичного життя.  В СРСР же усі спроби реформування провалювались, ну не хотіло наше комуністичне керівництво випускати хоч трішечки влади із своїх рух, усе хотіли контролювати і рахувати, хоча радянські економісти постійно втовкмачували про необхідність змін в цьому плані. Навіть коли у 80-х дозволили дрібне підприємництво, воно залишалось обкладене величезними податками і під тотальним контролем усіх можливих органів, навіть КДБ.

На жаль, і теперішня влада регіоналі абсолютно не розуміє, що підприємців потрібно стимулювати, а не давити. Але зараз не про це... Щодо галузі мікроелектроніки в незалежній Україні, то її намагалися якось реформувати від початку 90-х, проте як завжди робилося усе через велике Ж.. Підприємства потребували податкових пільг і серйозних поступків в плані зменшення митних обмежень на ввезення імпортних мікроелектронних елементів, проте цього не робилося. Боялися що надходження в бюджет впадуть і що розваляться і так давно відсталі заводи по виготовлення своєї елементної бази. В разультаті останні і так відмерли, із біля 2-х сотень потужних заводів, практично нічого не залишилося. На плаву залишилися одиниці, які займаються дрібними розробками під заказ або ж які субсидуються державою, існують ще тех.відділи при деяких підприємствах, які переважно займаються поточними ремонтами, а не створенням чогось нового.

Нормальних справді сучасних високотехнологічних заводів у нас просто уже не існує, а щоб створилися нові потрібно або ж вкладення шалених грошей або ж серйозні стимули для інвесторів. Мікроелектроніка не може жити без хорошого підходу, це не ІТ-галузь  де крім кількох комп'ютерів, інтернету і хороших програмістів більше нічого майже не потрібно і куди державі із своїми обмеженнями і правилами доволі важко втиснутися. Мікроелектронна галузь - це передусім енергоємке, матеріалоємне виробництво і яке дуже залежне від податкової та митної політики держави. Для цієї галузі потрібна  продумана політика побудована на досвіді Південної Кореї, Сінгапуру, Японії, Німеччини і того ж Китаю як розвинути власну високотехнологічну базу практично з нічого. Проте для цього потрібна влада яка б дбали про державу, а не про власні кишені....


P.S. Хоча початково не думав зачіпати цю тему,  але зараз рішив ще дописати про ЄС. Зараз нас лякають що при в ступі в ЄС наші підприємства будуть неконкурентні і відімруть, проте навіть і без вступу в ЄС вони років через 10 також відімруть. Весь світ рухається вперед в технологічному плані і якщо ми швидко не обновимо застаріле обладнання цих заводів і не створимо нові високотехнологічні, то перспективи в нашої економіки невеселі...

В одному із форумів програмісті я зустрів обговорення про євромайдан і ось дещо з чим я цілком згоден (http://dou.ua/forums/topic/8668/):

Вам то пофиг, вы как получали деньги из Европы, так и будете получать, а что делать тем, кого уволят с заводов?
Эти совковые заводы давно должны умереть. Живут они лишь за счёт того, что:
— в Украине есть куча совковых тупиц, желающих горбатиться на заводе за еду, да ещё и гордящихся этим (мол, «мы кормим страну»)
— украинчеги субсидируют эти заводы дешёвым газом из своего кармана
— украинчеги отстёгивают прямые госбюджетные субсидии из своего кармана
— владельцы заводов оставляют прибыль от сбыта зарубежом, а украинчеги покрывают убытки

И нужны тебе такие заводы?

А что касается работающих, которые станут безработными — пускай едут в деревни и займутся полезной и перспективной деятельностью (агропромом). Здоровее и богаче будут.




вівторок, 10 грудня 2013 р.

Що робити, якщо не видно жорсткого диску



Відеоурок, присвячений тому, що робити у Windows, коли вставили вінчестер (HDD), а розділів диску не видно. Вирішення проблеми через керування пристроями.

середа, 4 грудня 2013 р.

Електронні словники для Linux

Якщо ви працюєте часто з текстами на англійські мові, то тут не обійтися без електронного словника. Дехто під linux ставить Lingvo, проте це не шлях для початківців і часто виникають деякі проблеми, хоча коли є бажання усе можна зробити.

Власне ж для linux існує декілька програм аналогів Lingvo. Зокрема є такі програми як StarDict та GoldenDict. Встановлення цих прикладень не повинно скласти проблем. В Ubuntu це взагалі доволі просто робиться через  Ubuntu Software Center. Ввівши в пошуку StarDict або ж GoldenDict і натиснувши install отримуємо бажане.

Особисто я почав із StarDict. Після його встановлення звантажив з PirateBay словники для lingvo конвертовані у формат DICT і закинув їх у каталог (з правами адміністратора):

usr/share/stardict/dic

В налаштуваннях можна налаштувати почерговість пошуку по словниках. Проте з групуванням їх у мене дещо не склалося. Та й взагалі інтерфейс не дуже дружній до користувача.

Більш краще встановити GoldenDict. Набагато зручніший інтерфейс. Плюс підтримує мовні словники різних форматів, в тому числі і формат, який використовує StarDict, також підтримується пошук в інтернеті.


Після встановлення GoldenDict автоматично знайшов словники StarDict (в каталозі usr/share/stardict/dic). В разі якщо необхідні додаткові словники: права кнока миші на зображення словників та тиснемо edit this group або ж вибираємо меню edit/Dictionaries. На вкладці Sources вказуємо місце знаходження словників. Словники для різних мов можна знайти в інтернеті. Зокрема на http://www.babylon.com.

На вкладці Groups можна по-групувати словники. При здійсненні пошуку слова можна вказати в якій групі шукати.

 


В принципі з програмою і її налаштуваннями не складно розібратися.

середа, 13 листопада 2013 р.

Урок 3. Оператори Java. Арифметичні оператори та оператори присвоєння


Урок 03 - Оператори в Java. Частина 1.

У відеоуроці:
Які є оператори в Java? Арифметичні оператори та оператори присвоєння. Оператор залишку від ділення по модулю, оператор присвоєння, короткі оператори присвоєння.

четвер, 7 листопада 2013 р.

Змінні в Java



Відеоурок присвячений змінним в Javа.

Примітивні та об'єктні типи змінних, оголошення змінних, ініціалізація змінних, типи змінних, приведення типів

середа, 25 вересня 2013 р.

Вимоги до програмістів

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


Що було б якби до водіїв при влаштуванні на роботу пред’являлися вимоги, як до програмістів

Вакансія: водій.
Вимоги: професійні навички управлінні легковими та вантажними автомобілями, тролейбусами, трамваями, поїздами метрополітену і фунікулера, екскаваторами і бульдозерами, спецмашинами на гусеничному ходу, бойовими машинами піхоти і сучасними легкими / середніми танками, що знаходяться на озброєнні країн СНД і НАТО.


Навички раллійского і екстремального водіння – обов’язкові, досвід управління болідами F1 – вітається. Знання та досвід ремонту поршневих і роторних двигунів, автоматичних і ручних трансмісій, систем запалювання, бортових комп’ютерів, антиблокувальну систему, навігаційних систем (GPS) та автомобільних аудіосистем провідних виробників – обов’язкові. Досвід проведення кузовних та фарбувальних робіт вітається.

Претенденти повинні мати сертифікати:
Mercedes, BMV, Ceneral Motors, а також довідки про участь у великих міжнародних ралі не більш ніж дворічної давності. Зарплата 1500-2500 у.о., визначається за результатами співбесіди


середа, 11 вересня 2013 р.

JSP та кириличні запити

Почав розбиратися з JSP. Зробив найпростіший приклад і вийшла проблема з кирилицею. Коли запит приймається і формується html сторінка, вміст запиту відображається не в тому кодуванні. Хоча усюди усе на UTF-8.  При чому, що цікаво, що на комп'ютері з windows7 усе нормально, під windows XP проблема. Програмне забезпечення і там і там ставив одне і те ж Tomcat7, jdk7, Netbeans 7.3.1

Вирішується проблема частково через створення сервлет-фільтра, який запускається перед зверненням до будь якої jsp сторінки, або ж сервлета. Де додав у метод doBeforeProcessing рядок: request.setCharacterEncoding("utf-8");  Для POST запитів подіяло, але для GET не спрацьовує.

Почитав що можливо допоможе зміна деяких налаштувань в Tomcat. Інші рекомендації рекомендують погратися з локалями. Вирішив поки що в це не влазити, хоча судячи зі всього прийдеться, оскільки при зв'язці з базами даних проблема з кирилицею та різними кодуваннями прийдеться долати. В PHP якось проблем з цим по-менше :)

четвер, 6 червня 2013 р.

Як зробити відеоурок в Camtasio Studio 8.0



Відеоурок присвячений знайомству з Camtasia Studio 8. Наводиться інформація як записати відео і як додати деякі спецефекти, як то додати титулку, накласти відео на відео, виділити окрему частину екрану, збільшити частину екрану, як додати відео-переходи між окремими частинами відео та як працювати зі звуком. Висвітлено не всі можливості Camtasia Studio 8, але інформації достатньо для створення власного відеоуроку.

четвер, 30 травня 2013 р.

Вступ в Java - Привіт Світ!

Hello world!

У відеоуроці проводиться знайомство з Java та наводиться приклад написання HelloWorld у текстовому редакторі та у Eclipse.







Дивіться інші відеоуроки тут
Все стосовно Джава тут

четвер, 14 лютого 2013 р.

Як перекласти Source code?

Уже багато років в юанеті точиться постійна суперечка як краще перекласти Source сode. Кожен перекладач по своєму вирішує дану проблему. Росіяни цю проблему уже вирішили. Проте українські існуючі переклади мають певні недоліки, зокрема, із неоднозначністю пропонованих варіантів та утворення більш коротшої форми як то в англ source, в рос. исходник. (принаймні на цю неоднозначність вказує багато програмістів і багатьом існуючі варіанти не подобаються :) ). Власне, мабуть, саме бажання мати коротку форму для зручності і породжує стільки шуму.

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

Вихідний код може сприйматися як код на виході компілятора.

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

Є навіть екзотичний варіант сирець, сирцевий код, який по суті є англіцизмом, своєрідною передачею англійського терміну з приведенням його до слова сирець. Слід зазначити, що схоже слово "сорцы" популярне і застосовується в неформальному середовищі рунету. Судячи зі всього саме таке неформальне використання англійського терміну навело когось на думку порівняти дане слово із сирцем і сказати що це найкраще позначає сирий код. Хоча міра сирості та готовності тут умовна. В англ. мові існує також термін raw code (сирий, чорновий код).

Найбільш однозначним, дослівним перекладом Source code є "Джерельний код". Проте утворювана скорочена форма "Джерело" дещо незрозуміла і незручна у використанні. Тож якщо вже так всім хочеться короткий варіант для source, то чому б не використати "Джеркод"(скорочення від джерельний код). Принаймні усе однозначно, інтуітивно зрозуміло навіть тому, хто вперше зустріне джеркод у тексті. Будь-хто зрозуміє, що мається на увазі код, а не щось інше. За "сирець" явно "джеркод" краще. Хоча вухо дещо ріже і те і інше.

P.S. Ех хороша була ідея, але Тарас Буник нижнім коментарем убив її в зародку:)

вівторок, 29 січня 2013 р.

Поліморфізм в 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 general=(General)sg;  // наш Генерал тепер повноцінний
general.getSlogan();          // метод класу General доступний

Якщо виникає необхідність визначити, до якого класу належить відповідний об’єкт, то можна використати метод getClass(), який може викликати будь-який об’єкт оскільки він дістається йому від прабатька усіх класів Object:

System.out.println(sg.getClass());
// результат: class osvjava.ua.General

Власне об’єктні змінні класу Object доволі часто застосовується з метою збереження посилань на інші класи. Це дозволяє одночасно працювати з різнотипними об’єктами. Наприклад, можна, тримати різнотипні об’єкти в одному масиві типу Object. Також використання поліморфних об’єктних змінних дозволяє створювати своєрідні універсальні класи та методи (узагальнене програмування). Таким чином непотрібне створення великої кількості перевантаження методів з різним типом параметрів. Власне практично всі внутрішні бібліотеки Java спочатку будувалася таким чином. Щоправда, використання поліморфних змінних може слугувати джерелом багатьох помилок, тому в Java починаючи з JSE 5.0 у мову введено так звані Узагальнення (Generics), які дозволяють більш краще будувати такі універсальні засоби (дивіться детальніше відповідний розділ даного вікіпідручника). Приклади використання поліморфізму

Вище наведено основні правила використання поліморфних об’єктних змінних. Проте, щоб зрозуміти усе вищесказане та користь від поліморфізму розглянемо повноцінний приклад. Тож розробимо певну заготовку для своєрідної гри-стратегії. Наша заготовка гри повинна оперувати трьома об'єктами Soldier, General, Sergeant та проводитиме бій між двома військовими до загибелі одного із них.

Клас Солдат

Спочатку створимо батьківський клас Soldier. Наш солдат як і у всіх іграх матиме певний рівень здоров’я, певний рівень захисту від ударів (броню), отримуватиме удари (поранення) та наноситиме удари іншому солдату.

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


Як бачимо в програмі визначено конструктор Soldier(String rank), який проводить початкову ініціалізацію об’єкту, встановлює рівень здоров’я, оживляє, випадковим чином надає захист та присвоює порядковий номер.

Для того, щоб об’єкт когось вдарив у нас є публічний метод hit(Soldier targetSoldier, int hit), при використанні якого потрібно вказати кого вдарити і з якою силою. Даний метод отримавши аргументи викликає метод hit(int hit) того солдата(інший екземпляр класу Soldier), якому наноситься удар вказаної сили. Метод hit() визначає, яке пошкодження нанесено. Якщо сила удару більша рівня захисту, то наноситься пошкодження, яке рівне defense – hit (захист мінус сила удару). Якщо здоров’я солдата стає менше або рівне 0, то солдат вмирає.

Також у нас є додаткові інформаційні методи getHealth, getId та toString, для отримання інформації про стан нашого об’єкту (тобто солдата).

Для підрахунку кількості об’єктів використана статична змінна count, яка спільно використовується усіма екземплярами класу Soldier.

Більшість полів оголошені з модифікатором доступу protected, таким чином до них матимуть доступ лише об’єкти класу Soldier, його підкласи та об’єкти класів даного пакету. Таким чином клас Soldier певним чином інкапсульовано, проте при створенні класу з оголошенням, що він належить до даного пакету принцип інкапсуляції порушується. Ніщо не завадить напряму змінити health чи інше поле. Краще б було оголосити дані поля приватними, проте тоді б код програми ускладнився б, прийшлось би оголошувати більше методів доступу і відповідно розуміння програми ускладнилось би та й створення нащадків також ускладнюється. Ви можете самі пізніше переробити даний клас.

Наступний клас TestBattle створений для тестування бою між солдатами. Він оголошений у іншому пакеті, для правильного використання класу (щоб не було спокуси обійти наш інкапсульований інтерфейс роботи із солдатами). Якщо ви ще не до кінця розібралися, як працювати із пакетами в Java, то ви можете даний файл розмістити в одному ж каталозі з попереднім прикладом і вказати, що вони належать до одного пакету, або й взагалі прибрати написи з вказанням приналежності пакету (інструкції із словом package) у всіх файлах класів.

Для імітації бою у класі TestBattle визначено метод battle (Soldier s1, Soldier s2), в якому солдат 1 та солдат 2 наносять почергово один одному удари із випадковою силою. Бій проводиться до загибелі одного з них, після чого виводить інформація про переможця.

//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 раз");
    } 
}

Як бачимо клас сержанта доволі простий. При оголошенні класу ми написали, що він розширює клас Soldier. Далі визначили конструктор даного методу, який в свою чергу викликає конструктор суперкласу передаючи йому ранг. Якщо б ми б не визначили б конструктори у даних класах, а існували б лише конструктори по замовчуванню. То виклик конструкторів по замовчуванню відбувався б у тій же послідовності. При виклику конструктора Sergeant із нього б викликався конструктор Soldier і лише після створення Солдата відбувалось би створення Сержанта. Такий же механізм реалізовано в даному прикладі явно.

При створенні сержанта інструкцією new Sergeant(“Sergeant”), ми отримуємо наступне:

Сержант П№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;
    }
}


Давайте заставимо нашого генерала битися із сержантом. Оскільки вони розширяють клас Soldier, то нам непотрібно створювати новий метод battle() з параметрами типу General та Sergeant. Створений попередньо метод цілком підходить

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 його лозунг: Ніколи не здаватись ***** 


Як і можна було сподіватись, сили були занадто нерівні:). Генерал переміг

Таким чином завдяки тому, що наш метод battle використовує об’єктні змінні типу Soldier він без проблем приймає змінні типу Sergiant та General. Звичайно, що при цьому дані дочірні класи повинні битися через інтерфейс описаний у батьківському класі. Якщо вони реалізовуватимуть бій власним чином, то метод battle можливо не працюватиме правильно.

Крім того згадаймо метод hit(Soldier targetSoldier, int hit) класу Soldier. Там використовується посилання на об’єкт класу Soldier проте після успадкування даного методу він продовжує правильно працювати і з об’єктами Sergeant та General. Це також можливо завдяки поліморфізму.

Створюємо Армію

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

Ось клас Army, доволі простий, лише додає солдат до армії і в ньому існує метод, який підраховує здоров’я армії:

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

Як бачимо у класі Army для того, щоб просумувати здоров’я усіх солдат, нам не знадобилося три масиви типу Soldier, Sergeant та General, замість цього ми використали один масив Soldier, у який поміщаємо як рядових солдат так і генералів та сержантів. Метод army.calcArmyHealth() підбиває усе здоров’я армії простим перебором елементів масиву. Зверніть увагу як модифіковано метод battle у класі TestBattle2, тепер він повертає посилання на переможця: тип повернення Soldier.

Як вже зазначалося у вступі до поліморфізму, якщо ми хочемо викликати методи дочірніх класів, то прийдеться здійснити явне приведення до типу дочірнього класу, інакше методи General будуть недоступні ззовні, хоча всередині себе об’єкт без проблем застосовує власні методи та поля. Також, якщо в дочірньому класі перевизначено метод батьківського класу(в даному випадку метод toString), то навіть при використанні об’єктного посилання батьківського класу, метод усе рівно буде заміщено (override) (крім статичних методів). Нестатичні методи можна перевизначити у дочірньому класі, проте при поліморфізмі вони не будуть заміщатися. При виклику статичного метода об'єкту типу General, через об’єктну змінну типу Soldier буде викликаний метод Soldier, а не визначений в General одноіменний статичний метод. Все це потрібно враховувати при створенні власних програм. Тому виділіть час і поекспериментуйте з механізмами успадкування і поліморфізму, хоча б на даних прикладах.

Структура створених вищенаведених класів зображено на UML діаграмі. UML діаграма класів



 Власне, щоб не повторювати постійно метод battle при тестуванні, його б було доцільно розмістити у відповідному класі Battle. Можете зробити це самостійно. Також було б непогано реалізувати бій між арміями, а не тільки між двома солдатами.