1

Тема: Інтерфейс

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

2

Re: Інтерфейс

На скільки я розумію інтерфейс в Java - це щось типу множинного наслідування. В реальних програмах інтерфейс будь-де можна використати. Наприклад, ви хочете створити якусь гру. Нехай буде у вас якийсь монстр з певним інтерфейсом. Ви можете використати цей інтерфейс для створення орка чи дракона з різною реалізацією методів. Але оскільки там є певні обмеження, то писати якусь гру на Java - мазохізм. Як для прикладу, можете написати інтерфейс типу Звіринець і реалізувати його для білочок, песиків, качечок і т.д. Пропоную такий приклад, бо все це краще вкладається в голові, коли проводиться аналогія з реальними об'єктами (по собі суджу).

Подякували: Zolin_7771

3

Re: Інтерфейс

де їх можна примінити в реальних програмах?

ПЗ на Java чи взагалi?

Подякували: Zolin_7771

4

Re: Інтерфейс

Zolin_777 написав:

...по інтерфейсах Java, де їх можна примінити в реальних програмах? ...

Краще розберіться з об'єктно-орієнтованим програмуванням (ООП) і тоді зрозумієте навіщо, ті інтерфейси. Почитатйте, наприклад книгу "Объектно-ориентированный анализ и проектирование" серії Head First. Книга розраховано на початківців, тому там все досить легко читається + для прикладів, якщо мені не зраджує пам'ять, там використовують мову Java.

Подякували: Zolin_777, leofun012

5

Re: Інтерфейс

Vi написав:

де їх можна примінити в реальних програмах?

ПЗ на Java чи взагалi?

Ну ПЗ на Java я вирішив що саме краще застосовувати в компаніях корпоративних, а от інтерфейси....

6

Re: Інтерфейс

LoganRoss написав:

На скільки я розумію інтерфейс в Java - це щось типу множинного наслідування. В реальних програмах інтерфейс будь-де можна використати. Наприклад, ви хочете створити якусь гру. Нехай буде у вас якийсь монстр з певним інтерфейсом. Ви можете використати цей інтерфейс для створення орка чи дракона з різною реалізацією методів. Але оскільки там є певні обмеження, то писати якусь гру на Java - мазохізм. Як для прикладу, можете написати інтерфейс типу Звіринець і реалізувати його для білочок, песиків, качечок і т.д. Пропоную такий приклад, бо все це краще вкладається в голові, коли проводиться аналогія з реальними об'єктами (по собі суджу).

Дякую за відповідь, ви написали зрозуміліше чим в книгах  *HI*

7

Re: Інтерфейс

LoganRoss написав:

На скільки я розумію інтерфейс в Java - це щось типу множинного наслідування.

На скільки я розумію комп'ютер - це щось типу потужної друкарської машинки.  *PARDON* Це не є метою інтерфейсів, лише однією з властивостей його використання.

Ідеологічно, інтерфейс визначає поведінку, яку конкретні імплементації класів мають надавати. Концепцію інтерфейсів в Джаві також можна розуміти як API до реалізацій класів.

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

І так, інтерфейси дозволяють реалізувати множинне успадкування :)

Повертаючись до друкарських машинок. Створимо клас що буде відповідати за друк тексту та ХеллоВорлдер, який буде писати ХеллоВорлд використовуючи вищезгаданий клас:

class SystemOutWriter {
   public void print(String s) {System.out.println(s);}
}

class HelloWorlder {
   private SystemOutWriter writer:
   public HelloWorlder (SystemOutWriter writer) {
      this.writer=writer;
   }
   public void sayHello() {
      writer.print("Hello World");
}

class Main {
   public static void main(String[] arg) {
      SystemOutWriter writer = new SystemOutWriter();
      HelloWorlder helloWorlder = new HelloWorlder(writer);
      helloWorlder.sayHello();
   }
}

За деякий час з'явилася необхідність друкувати ХеллоВорлд ще й до файлу. Створюємо FileWriter та новий HelloWorlder, так як попередній вміє працювати лише з SystemOutWriter. Ще дещо пізніше, з'являється необхідність друкувати ХеллоВорлд на принтері, надсилати на пошту, писати в сокет і ще десятки можливих варіянтів, і кожен з них буде вимагати нового HelloWorlder'а, який за логікою буде завжди однаковим, лише відрізняючись типом властивості writer.

Така ситуація називається high coupling, сильна зв'язаність, що вважається характеристикою поганого коду через важкість внесення змін, дублікацію коду та інші недоліки.

Позбутися цього можна використовуючи інтерфейс:

interface Writer {
   void print(String s);
}
class SystemOutWriter implements Writer {
   public void print(String s) {System.out.println(s);}
}
class FileWriter implements Writer {
   public void print(String s) {FileUtils.writeToFile(s);}
}
class MailWriter implements Writer {
   public void print(String s) {MailService.broadcastMessage(s);}
}
//....

class HelloWorlder {
   private Writer writer; // <----- використання інтерфейсу
   public HelloWorlder (Writer writer) {
      this.writer=writer;
   }
   public void sayHello() {
      writer.print("Hello World");
}

class Main {
   public static void main(String[] arg) {
      SystemOutWriter systemOutWriter = new SystemOutWriter();
      HelloWorlder helloWorlder = new HelloWorlder(systemOutWriter);
//   HelloWorlder helloWorlder = new HelloWorlder(new FileWriter()); // або
//   HelloWorlder helloWorlder = new HelloWorlder(new MailWriter()); // або
      helloWorlder.sayHello();
   }
}

Таким чином ми маємо лише один HelloWorlder, який незнаючи якою конкретно імплементацією він послуговуються, може вільно її використовувати, бо він розуміє інтерфейс взаємодії (API) з нею.

FAQ:
1) Чекайте, я можу реалізувати схожу поведінку використовуючи базовий клас Writer і надписати (override) метод в конкретних імплементаціях!
Можете, одначе:
а) Що буде містити метод print(..) в цьому класі? Клас настільки абстрактний, що відповідь на питання "куди писати?" невизначена.
б) Треба якось запевнити, що кожен нащадок буде надписувати цей метод. В звичайному класі цього не зробити.

2) Переконав. Але ж є ще абстрактні класи. Я можу створити абстрактний клас Writer та абстрактний метод print(..).
Можна, однак поняття клас містить не лише поведінку але й стан (властивості), якого в даному випадку не буде. Саме для таких випадків був запропонований механізм інтерфейсів, що описує лише поведінку. Використовуючи абстрактний клас Ви також позбавляєте себе використати можливість множинного успадкування.

Інтерфейсом також називають повністю абстрактний клас (містить лише абстрактні методи, pure virtual з термінології с++), усі методи якого є public.

У підсумку:
- класи визначають стан та поведінку
- інтерфейси визначають лише поведінку, доступну користувачам інтерфейсів (себто лише публічні методи)
- інтерфейсом також називається pure virtual method, у джаві такий метод також має бути публічним
- усі методи визначені в інтерфейсі - public і тільки.
- в інтерфейсі дозволені лише public static властивості.
- якщо ваш абстрактний клас містить лише абстрактні методи, варто розважити над використанням інтерфейсу в цьому місці

На марґінесі: імплементуючи інтерфейси, пам'ятайте про "I" з принципу SOLID, тобто interface segregating - занадто «товсті» інтерфейси необхідно розділяти на менші та специфічні, щоб вони містили лише необхідні для роботи з ними методи.

Подякували: LoganRoss, Zolin_7772

8

Re: Інтерфейс

iovchynnikov, я якраз і проводив аналогію з абстрактним класом з усіма чистими віртуальними функціями в С++. Воно реалізує ідею поліморфізму та інкапсуляції. Однак, як ви написали, в Джаві є обмеження, що не дає в повній мірі використати поліморфну поведінку.

Подякували: iovchynnikov, Zolin_777, leofun013

9

Re: Інтерфейс

Zolin_777
Приклад від мене: реалізуйте програму у якій є клас Тварини. Усі тварини матимуть методи Рух та Голос. Нащадками цього класу будуть класи Ссавці та Птахи. Нащадками класу ссавці будуть Собаки, Слони, Люди. Нащадками класу птахи будуть Індики, Орли та Папуги. Люди та Папуги мають іще один додатковий метод Говорити. Реалізуйте функцію, яка прийматиме на вхід один параметр об'єкт класу Людна або Папуга, і викликатиме їх метод Говорити. Перевірка класу об'єкту має відбуватися під час компіляції. Реалізовувати метод Говорити в класі Тварини заборонено.

Подякували: Zolin_7771

10

Re: Інтерфейс

Zolin_777 написав:

Ну ПЗ на Java я вирішив що саме краще застосовувати в компаніях корпоративних, а от інтерфейси....

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

Подякували: Zolin_7771

11

Re: Інтерфейс

Прихований текст
Torbins написав:

Zolin_777
Приклад від мене: реалізуйте програму у якій є клас Тварини. Усі тварини матимуть методи Рух та Голос. Нащадками цього класу будуть класи Ссавці та Птахи. Нащадками класу ссавці будуть Собаки, Слони, Люди. Нащадками класу птахи будуть Індики, Орли та Папуги. Люди та Папуги мають іще один додатковий метод Говорити. Реалізуйте функцію, яка прийматиме на вхід один параметр об'єкт класу Людна або Папуга, і викликатиме їх метод Говорити. Перевірка класу об'єкту має відбуватися під час компіляції. Реалізовувати метод Говорити в класі Тварини заборонено.

Ось подивіться так чи ні? скоріше всього я не вловив суть задачі  *TIRED*
перший файл

package Інтерфейс;
// Клас тварини
public class Animals {
    void movers(){
        
    }
    void voice(){
        
    }
}
// Клас ссавці
class Mammans extends Animals{
    
}
class Dog extends Mammans{
    
}
class Elephant extends Mammans{
    
}
class Humen extends Mammans{
    void speak(){
        System.out.print("Людина говорить");
    }
}
//Клас птахи
class Birds extends Animals{
    
}
class turkey extends Birds{
    
}
class Eagle extends Birds{
    
}
class Parrot extends Birds{
    void speak(){
        System.out.print("Папуга говорить");
    }
}

Другий файл з якого визивається метод папуги

package Інтерфейс;

public class index {

    public static void main(String[] args) {
        Parrot papuga = new Parrot();
        papuga.speak();

    }

}

12

Re: Інтерфейс

Vi написав:

Інтерфейс -це список (спеціфікція) властивостей класів, зібраних ...

Інтерфейс не може містити властивостей класів (class properties), що його імплементують.

Подякували: LoganRoss, leofun012

13

Re: Інтерфейс

iovchynnikov написав:
Vi написав:

Інтерфейс -це список (спеціфікція) властивостей класів, зібраних ...

Інтерфейс не може містити властивостей класів (class properties), що його імплементують.

Я не в буквальному сенсi.

14

Re: Інтерфейс

Zolin_777, а тепер додайте десь таку функцію:

public void make_speak(<Щось> speaker)
{
    speaker.speak();
}

і викличте її для двох об'єктів - папуги і людини.

Подякували: Torbins1

15

Re: Інтерфейс

Zolin_777
Початок правильний. Тепер реалізуйте те, що вас попросив koala.

16

Re: Інтерфейс

Vi написав:
iovchynnikov написав:
Vi написав:

Інтерфейс -це список (спеціфікція) властивостей класів, зібраних ...

Інтерфейс не може містити властивостей класів (class properties), що його імплементують.

Я не в буквальному сенсi.

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

Подякували: Zolin_7771

17 Востаннє редагувалося Zolin_777 (27.04.2017 18:48:51)

Re: Інтерфейс

koala написав:

Zolin_777, а тепер додайте десь таку функцію:

public void make_speak(<Щось> speaker)
{
    speaker.speak();
}

і викличте її для двох об'єктів - папуги і людини.

Хороше завдання. Замість <Щось> я написав String
а от ця строчка  speaker.speak(); взагалі не в'яжиться нікуда....

По плану Speaker повинен бути класом щоб так визивати метод? нічого не розумію

18

Re: Інтерфейс

Треба, щоб можна було робити
Parrot parrot=new Parrot();
Humen human=new Humen();
make_speak(parrot);
make_speak(human);

Тобто щоб можна було передати у функцію об'єкт, який може робити speak - але невідомо, чи буде це папуга, чи людина.

19

Re: Інтерфейс

koala написав:

Треба, щоб можна було робити
Parrot parrot=new Parrot();
Humen human=new Humen();
make_speak(parrot);
make_speak(human);

Тобто щоб можна було передати у функцію об'єкт, який може робити speak - але невідомо, чи буде це папуга, чи людина.

Добавив в класс Humen

class Humen extends Mammans{
    void speak(){
        System.out.print("Людина говорить");
    }
    public void make_speak(Humen speaker)
    {
        speaker.speak();
    }
}

і в головний клас

public static void main(String[] args) {
        Parrot papuga = new Parrot();
        papuga.speak();
        Humen human = new Humen();
        human.make_speak(human);
    }

так? але я не зрозумів як це працює, хіба можна передавати параметру метода цілий об'єкт?  *WALL*

20 Востаннє редагувалося LoganRoss (27.04.2017 20:22:50)

Re: Інтерфейс

у вас повинна бути одна функція

make_speak(<Щось> speaker)

, що реалізується і для людини, і для папуги. Одна функція для двох об'єктів.
P.S. Підказка: об'єкти похідного класу також є об'єктами базового класу.