Міністерство освіти і науки України
Національний університет “Львівська політехніка”
/
Звіт
До Лабораторної роботи №3
З дисципліни: «Кросплатформені засоби програмування»
Мета: ознайомитися з процесом розробки класів та пакетів мовою Java.
ТЕОРЕТИЧНІ ВІДОМОСТІ
Класи
Мова Java є повністю об’єктно-орієнтованою мовою програмування, тому вона дозволяє писати програми лише з використанням об’єктно-орієнтованих парадигм програмування, що базуються на понятті класів.
Синтаксис оголошення простого класу в мові Java має наступний вигляд:
[public] class НазваКласу
{
[конструктори] [методи] [поля]
}
Приклад оголошення загальнодоступного класу:
public class StartClass
{
public StartClass()
{
str = "Hello";
}
public StartClass(String initString)
{
str = initString;
}
public void showMessage()
{
System.out.print(str);
}
private String str;
}
Необов’язковий специфікатор доступу public робить клас загальнодоступним. У кожному файлі з кодом програми може бути лише один загальнодоступний клас, ім’я якого співпадає з назвою файлу, та безліч класів без специфікатора public.
Створення об’єкту класу складається з двох етапів: оголошення та ініціалізації посилання на об’єкт. Оголошення посилання на об’єкт класу має синтаксис:
НазваКласу назваПосилання;
Приклад оголошення посилання на об’єкт класу StartClass:
StartClass obj;
Ініціалізація посилання на об’єкт класу здійснюється за допомогою оператора new і вказування конструктора, який має збудувати об’єкт. Одержаний в результаті цих операцій об’єкт розташується у області оперативної пам’яті що зветься ”куча”. Ініціалізація посилання на об’єкт класу за допомогою конструктора за замовчуванням має такий синтаксис:
назваПосилання = new НазваКонструтора();
Приклад ініціалізації посилання на об’єкт класу StartClass:
obj = new StartClass();
При створенні об’єктів дозволяється суміщати оголошення та ініціалізацію об’єктів, а також створювати анонімні об’єкти. Якщо посилання на об’єкт не посилається на жоден об’єкт, то йому слід присвоїти значення null. На відміну від полів-посилань на об’єкти, локальні змінні-посилання на об’єкти не ініціалізуються значенням null при оголошенні. Для них ініціалізацію посилання слід проводити явно.
Методи
Метод – функція-член класу, яка призначена маніпулювати станом об’єкту класу. Методи можуть бути перевантаженими. Перевантаження методів відбувається шляхом вказування різної кількості параметрів та їх типів методам з однаковими назвами. Синтаксис оголошення методу наступний:
[СпецифікаторДоступу] [static] [final] Тип назваМетоду([параметри]) [throws класи]
{
[Тіло методу] [return [значення]];
}
Конструктори, методи, та поля класу можуть бути відкритими (public),
закритими (private) та захищеними (protected), що визначається специфікатором доступу.
Специфікатор доступу public робить елемент класу загальнодоступним в межах пакету (набору класів, з яких складається програма).
Специфікатор доступу private робить елемент класу закритим (недоступним) для всіх зовнішніх відносно даного класу елементів програми (включаючи похідні класи).
Специфікатор доступу protected робить елемент класу закритим (недоступним) для всіх зовнішніх відносно даного класу елементів програми, проте цей елемент буде загальнодоступним для похідних класів.
Якщо будь-який елемент класу не має специфікатора доступу, то цей елемент автоматично стає відкритим та видимим у межах пакету (не плутати з public).
Всі елементи класу, що оголошені без використання ключового слова static, належать об’єкту класу. Тобто, кожен об’єкт класу містить власну копію цих елементів класу. Ключове слово static робить поле або метод членом класу, а не об’єкту, тобто вони є спільними для всіх об’єктів класу. Оскільки клас існує завжди, на відміну від об’єктів, які створюються в процесі роботи програми, то статичні елементи класу доступні
навіть тоді, коли ще не створено жодного об’єкту класу. Цей підхід використовується при написанні методу main з якого починається виконання консольної програми, бо на момент її запуску ще не існує жодного об’єкту.
Метод може генерувати виключну ситуацію. Якщо виключна ситуація не опрацьовується у тілі методу, то вона повинна бути описана в оголошені методу після ключового слова throws. Якщо виключна ситуація опрацьовується у тілі методу, то цього робити не потрібно.
Передача параметрів у метод відбувається по значенню шляхом копіювання значень реальних параметрів у формальні параметри методу. Якщо ці значення є простими типами, то відбудеться копіювання значень. Якщо ці значення є посиланнями, то копіюватимуться не об’єкти, а посилання на об’єкти. Таким чином зміна значення посилання формального параметру в середині методу не вплине на значення посилання за його межами.
Вихід та повернення значення з методу відбувається за допомогою оператора
return. Якщо метод не повертає значення, то оператор return можна опустити. Перед
поверненням з методу значення об’єкту, що може змінювати свій стан, слід обов’язково
скористатися методом clone об’єкту, який створює його копію.
Синтаксис виклику нестатичного методу:
НазваОб’єкту.назваМетоду([параметри]);
Синтаксис виклику статичного методу має 2 види:
НазваОб’єкту.назваМетоду([параметри]); // через об’єкт класу НазваКласу.назваМетоду([параметри]); // через назву класу
Виконання лабораторної роботи
Завдання:
Варіант-14 - Телевізор
Написати та налагодити програму на мові Java, що реалізує у вигляді класу предметну область згідно варіанту. Програма має задовольняти наступним вимогам:
програма має розміщуватися в пакеті Група.Прізвище.Lab3;
клас має містити мінімум 3 поля, що є об’єктами класів, які описують складові частини предметної області;
клас має містити кілька конструкторів та мінімум 10 методів;
для тестування і демонстрації роботи розробленого класу розробити клас-драйвер;
методи класу мають вести протокол своєї діяльності, що записується у файл;
розробити механізм коректного завершення роботи з файлом (не надіятися на метод finalize());
Код програми:
package ki43.karabas.Lab3;
import javafx.util.Pair;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.*;
class Screen {
private int width;
private int height;
public Screen() {
width = 100;
height = 100;
}
public Screen(int width, int height) {
if (width < 0 || height < 0) {
throw new IllegalArgumentException("Screen width and height must be positive number");
}
this.width = width;
this.height = height;
}
public Screen(Screen other) {
this.width = other.width;
this.height = other.height;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
if (width < 0) {
throw new IllegalArgumentException("Screen width and height must be positive number");
}
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
if (height < 0) {
throw new IllegalArgumentException("Screen width and height must be positive number");
}
this.height = height;
}
public void setResolution(int width, int height) {
setHeight(height);
setWidth(width);
}
}
class Channels {
private List<String> channels = new ArrayList<>();
public Channels() {
}
public Channels(Collection<String> channels) {
this.channels.addAll(channels);
}
public Channels(Channels channels) {
this.channels.addAll(channels.channels);
}
public List<String> getChannels() {
return channels;
}
public void addChanel(String chanel) {
if (channels.contains(chanel)) {
throw new IllegalArgumentException("This channel already at list");
}
channels.add(chanel);
}
public void removeChanel(String chanel) {
if (channels.contains(chanel)) {
throw new IllegalArgumentException("No such channel at list");
}
channels.remove(chanel);
}
public boolean hasChanel(String chanel) {
return channels.contains(chanel);
}
public String getNext(String chanel) {
if (!channels.contains(chanel)) {
return null;
}
int i = channels.indexOf(chanel);
if (i == channels.size()) {
return null;
}
return channels.get(i + 1);
}
public String getPrev(String chanel) {
if (!channels.contains(chanel)) {
return null;
}
int i = channels.indexOf(chanel);
if (i == 0) {
return null;
}
return channels.get(i - 1);
}
}
public class TV {
private Screen screen;
private Channels channels;
private String currentChanel;
private boolean isWorking;
private static final String LOG_FILE = "log.txt";
public TV() {
this.screen = new Screen();
this.isWorking = false;
this.channels = new Channels();
}
public TV(int width, int height, Collection<String> channels) {
this.screen = new Screen(width, height);
this.channels = new Channels(channels);
this.isWorking = false;
}
public TV(int width, int height) {
this(width, height, Collections.emptyList());
}
public TV(TV tv) {
this.channels = new Channels(tv.channels);
this.screen = new Screen(tv.screen);
this.currentChanel = tv.currentChanel;
this.isWorking = tv.isWorking;
}
public void turnOn() {
log("Turn on TV");
isWorking = true;
}
public void turnOff() {
log("Turn off TV");
isWorking = false;
}
public boolean isWorking() {
log("Is TV working: " + isWorking);
return isWorking;
}
private static void log(String text) {
try {
Files.write(Paths.get(LOG_FILE), (text + "\n").getBytes(), StandardOpenOption.APPEND);
} catch (Exception e) {
e.printStackTrace();
}
}
public void addChanel(String... channels) {
log("Add channels: " + String.join(", ", channels));
Arrays.stream(channels).forEach(this.channels::addChanel);
}
public Collection<String> getChannels() {
log("Current list of channels: " + String.join(", ", channels.getChannels()));
return new ArrayList<>(channels.getChannels());
}
public void setCurrentChanel(String currentChanel) {
if (!isWorking) {
System.err.println("You must turn on TV first");
} else if (!channels.hasChanel(currentChanel)) {
System.err.println("No such chanel");
} else {
log("Set channel to " + currentChanel);
this.currentChanel = currentChanel;
}
}
public String getCurrentChanel() {
log("Get current channel");
if (!isWorking) {
System.err.println("You must turn on TV first");
return null;
} else {
log("Current channel is " + currentChanel);
return currentChanel;
}
}
public void goToNextChanel() {
if (!isWorking) {
System.out.println("You must turn on TV first");
} else {
log("Go to next channel");
Optional<String> next = Optional.ofNullable(channels.getNext(currentChanel));
next.ifPresentOrElse(this::setCurrentChanel, () -> System.err.println("Can't go to next chanel"));
}
}
public void goToPreviousChanel() {
if (!isWorking) {
System.out.println("You must turn on TV first");
} else {
log("Go to previous channel");
Optional<String> next = Optional.ofNullable(channels.getPrev(currentChanel));
next.ifPresentOrElse(this::setCurrentChanel, () -> System.err.println("Can't go to next chanel"));
}
}
public void setScreen(Screen screen) {
log("Set screen resolution");
setScreenResolution(screen.getWidth(), screen.getHeight());
}
public Screen getScreenResolution() {
log("Get screen resolution");
return screen;
}
public void setScreenResolution(Pair<Integer, Integer> resolution) {
log("Set screen resolution");
setScreenResolution(resolution.getKey(), resolution.getValue());
}
public void setScreenResolution(int width, int height) {
log("Set screen resolution");
if (width < 0 || height < 0) {
System.out.println("Width and height must be bigger than 0");
} else {
screen.setResolution(width, height);
}
}
}
package ki43.karabas.Lab3;
import javafx.util.Pair;
public class TVApp {
public static void main(String[] args) {
var t1 = new TV();
t1.getCurrentChanel();
t1.turnOn();
t1.addChanel("1+1", "5", "ICTV");
t1.setCurrentChanel("5");
t1.setScreenResolution(1200, 800);
t1.getCurrentChanel();
var t2 = new TV(t1);
t2.goToNextChanel();
t2.goToPreviousChanel();
t2.setCurrentChanel("1+1");
var t3 = new TV(200, 400);
t3.setScreenResolution(new Pair<>(200, 400));
t3.getScreenResolution();
t3.turnOff();
t3.isWorking();
}
}
Результат виконання програми:
Get current channel
Turn on TV
Add channels: 1+1, 5, ICTV
Set channel to 5
Set screen resolution
Get current channel
Current channel is 5
Go to next channel
Set channel to ICTV
Go to previous channel
Set channel to 5
Set channel to 1+1
Set screen resolution
Set screen resolution
Get screen resolution
Turn off TV
Is TV working: false
Get current channel
Turn on TV
Add channels: 1+1, 5, ICTV
Set channel to 5
Set screen resolution
Get current channel
Current channel is 5
Go to next channel
Set channel to ICTV
Go to previous channel
Set channel to 5
Set channel to 1+1
Set screen resolution
Set screen resolution
Get screen resolution
Turn off TV
Is TV working: false
Висновок: на даній лабораторній роботі я ознайомився з процесом розробки класів та пакетів мовою Java.