Что такое абстракция java
Перейти к содержимому

Что такое абстракция java

  • автор:

26. Java – Абстракция: абстрактный класс и метод, наследование абстрактного класса

Абстракция – это качество общения с идеями, а не с событиями. Например, в случае с e-mail, подробные детали о происходящем во время отправки e-mail, используемый протокол сервером e-mail – всё это скрыто от пользователя. Тем не менее, для отправки e-mail вам достаточно напечатать содержимое, адрес получателя и нажать «отправить».

Так и в объектно-ориентированном программировании: абстракция – это процесс скрытия деталей реализации от пользователя, предоставляя ему только функционал. Иными словами, пользователь будет владеть информацией о том, что объект делает, а не как он это делает.

В Java абстракция достигается с использованием абстрактных классов и интерфейсов.

Абстрактный класс

Класс, который во время объявления содержит в себе ключевое слово abstract, известен как абстрактный класс.

  • Абстрактные классы в Java могут содержать или не содержать абстрактные методы, т.е. методы без тела (public void get();)
  • Если класс имеет хотя бы один абстрактный метод, то класс должен быть объявлен абстрактным.
  • Если класс объявлен абстрактным, его нельзя реализовать.
  • Чтобы использовать абстрактный класс, вам нужно наследовать его из другого класса, обеспечить реализацию абстрактных методов в нём.
  • Если вы наследуете абстрактный класс в Java, вам нужно обеспечить реализацию всех абстрактных методов в нём.

Пример

Эта глава показывает вам пример абстрактного класса. Чтобы создать абстрактный класс, просто используйте ключевое слово abstract перед ключевым словом class во время объявления класса.

/* File name : Employee.java */ public abstract class Employee < private String name; private String address; private int number; public Employee(String name, String address, int number) < System.out.println("Собираем данные о работнике"); this.name = name; this.address = address; this.number = number; >public double computePay() < System.out.println("Внутри Employee computePay"); return 0.0; >public void mailCheck() < System.out.println("Отправляем чек " + this.name + " " + this.address); >public String toString() < return name + " " + address + " " + number; >public String getName() < return name; >public String getAddress() < return address; >public void setAddress(String newAddress) < address = newAddress; >public int getNumber() < return number; >> 

Вы можете наблюдать, что помимо абстрактных методов класс Employee такой же, как и обычный класс в Java. Класс теперь абстрактный, но он всё ещё имеет три поля, семь методов и один конструктор.

Теперь попробуйте создать экземпляр класса Employee следующим образом:

/* File name : AbstractDemo.java */ public class AbstractDemo < public static void main(String [] args) < /* Следующие действия неверны и выдадут ошибку */ Employee e = new Employee("Иванов И.И.", "Минск, Беларусь", 43); System.out.println("\n Вызываем mailCheck, используя ссылку Employee --"); e.mailCheck(); >> 

При попытке компиляции вышеприведённого класса вы получите следующую ошибку:

Employee.java:46: Employee is abstract; cannot be instantiated Employee e = new Employee("Иванов И.И.", "Минск, Беларусь", 43); ^ 1 error 

Наследование абстрактного класса

Рассмотрим наследоавние абстрактного класса в Java на примере. Вы можете наследовать класс Employee, как конкретный класс, следующим образом:

Пример

/* File name : Salary.java */ public class Salary extends Employee < private double salary; // Годовая заработная плата public Salary(String name, String address, int number, double salary) < super(name, address, number); setSalary(salary); >public void mailCheck() < System.out.println("Внутри mailCheck класса Salary "); System.out.println("Отправляем чек" + getName() + " с зарплатой " + salary); >public double getSalary() < return salary; >public void setSalary(double newSalary) < if(newSalary >= 0.0) < salary = newSalary; >> public double computePay() < System.out.println("Вычисляем заработную плату для " + getName()); return salary/52; >> 

Здесь вы не можете создать экземпляр класса Employee, но вы можете создать экземпляр класса Salary, используя который вы сможете получить доступ ко всем трём полям и семи методам класса Employee, как в примере ниже.

/* File name : AbstractDemo.java */ public class AbstractDemo < public static void main(String [] args) < Salary s = new Salary ("Петров П.П.", "Москва, Россия", 3, 3600.00); Employee e = new Salary ("Смирнов О.И.", "Смоленск, Россия", 2, 2400.00); System.out.println("Вызываем mailCheck, используя ссылку Salary --"); s.mailCheck(); System.out.println("\n Вызываем mailCheck, используя ссылку Employee --"); e.mailCheck(); >> 

После запуска программы будет выдан такой результат:

Собираем данные о работнике Собираем данные о работнике Вызываем mailCheck, используя ссылку Salary –– Внутри mailCheck класса Salary Отправляем чек Петров П.П. с зарплатой 3600.0 Вызываем mailCheck, используя ссылку Employee –– Внутри mailCheck класса Salary Отправляем чек Смирнов О.И. с зарплатой 2400.0 

Абстрактный метод

Если вы хотите, чтобы класс содержал конкретный метод, но вы желаете, чтобы фактическая реализация этого метода определялась дочерними классами, вы можете объявить метод в родительском классе как абстрактный

  • Ключевое слово abstract используется для объявления метода абстрактным.
  • Вам нужно разместить ключевое слово abstract перед именем метода во время его объявления.
  • Абстрактный метод в Java содержит сигнатуру метода, но не содержит тела метода.
  • Вместо фигурных скобок у абстрактного метода будет точка с запятой (;) на конце.

Рассмотрим пример абстрактного метода в Java.

Пример

public abstract class Employee < private String name; private String address; private int number; public abstract double computePay(); // Остаток определения класса >

Объявление метода абстрактным ведёт к двум последствиям:

  • Класс, содержащий его, должен быть объявлен абстрактным.
  • Любой класс, наследующий текущий класс, должен либо переопределить абстрактный метод, либо объявить себя абстрактным.

Примечание. В конце концов, класс-потомок должен реализовать абстрактный метод, иначе у вас будет иерархия абстрактных классов, экземпляры которых нельзя будет создать.

Предположим, что класс Salary наследует класс Employee, тогда он должен реализовать метод computePay() , как показано ниже:

/* File name : Salary.java */ public class Salary extends Employee < private double salary; // Годовая заработная плата public double computePay() < System.out.println("Вычисляем заработную плату для " + getName()); return salary/52; >// Остаток определения класса > 

Оглавление

  • 1. Java – Самоучитель для начинающих
  • 2. Java – Обзор языка
  • 3. Java – Установка и настройка
  • 4. Java – Синтаксис
  • 5. Java – Классы и объекты
  • 6. Java – Конструкторы
  • 7. Java – Типы данных и литералы
  • 8. Java – Типы переменных
  • 9. Java – Модификаторы
  • 10. Java – Операторы
  • 11. Java – Циклы и операторы цикла
  • 11.1. Java – Цикл while
  • 11.2. Java – Цикл for
  • 11.3. Java – Улучшенный цикл for
  • 11.4. Java – Цикл do..while
  • 11.5. Java – Оператор break
  • 11.6. Java – Оператор continue
  • 12. Java – Операторы принятия решений
  • 12.1. Java – Оператор if
  • 12.2. Java – Оператор if..else
  • 12.3. Java – Вложенный оператор if
  • 12.4. Java – Оператор switch..case
  • 12.5. Java – Условный оператор (? 🙂
  • 13. Java – Числа
  • 13.1. Java – Методы byteValue(), shortValue(), intValue(), longValue(), floatValue(), doubleValue()
  • 13.2. Java – Метод compareTo()
  • 13.3. Java – Метод equals()
  • 13.4. Java – Метод valueOf()
  • 13.5. Java – Метод toString()
  • 13.6. Java – Метод parseInt()
  • 13.7. Java – Метод Math.abs()
  • 13.8. Java – Метод Math.ceil()
  • 13.9. Java – Метод Math.floor()
  • 13.10. Java – Метод Math.rint()
  • 13.11. Java – Метод Math.round()
  • 13.12. Java – Метод Math.min()
  • 13.13. Java – Метод Math.max()
  • 13.14. Java – Метод Math.exp()
  • 13.15. Java – Метод Math.log()
  • 13.16. Java – Метод Math.pow()
  • 13.17. Java – Метод Math.sqrt()
  • 13.18. Java – Метод Math.sin()
  • 13.19. Java – Метод Math.cos()
  • 13.20. Java – Метод Math.tan()
  • 13.21. Java – Метод Math.asin()
  • 13.22. Java – Метод Math.acos()
  • 13.23. Java – Метод Math.atan()
  • 13.24. Java – Метод Math.atan2()
  • 13.25. Java – Метод Math.toDegrees()
  • 13.26. Java – Метод Math.toRadians()
  • 13.27. Java – Метод Math.random()
  • 14. Java – Символы
  • 14.1. Java – Метод Character.isLetter()
  • 14.2. Java – Метод Character.isDigit()
  • 14.3. Java – Метод Character.isWhitespace()
  • 14.4. Java – Метод Character.isUpperCase()
  • 14.5. Java – Метод Character.isLowerCase()
  • 14.6. Java – Метод Character.toUpperCase()
  • 14.7. Java – Метод Character.toLowerCase()
  • 14.8. Java – Метод Character.toString()
  • 15. Java – Строки
  • 15.1. Java – Метод charAt()
  • 15.2. Java – Метод compareTo()
  • 15.3. Java – Метод compareToIgnoreCase()
  • 15.4. Java – Метод concat()
  • 15.5. Java – Метод contentEquals()
  • 15.6. Java – Метод copyValueOf()
  • 15.7. Java – Метод endsWith()
  • 15.8. Java – Метод equals()
  • 15.9. Java – Метод equalsIgnoreCase()
  • 15.10. Java – Метод getBytes()
  • 15.11. Java – Метод getChars()
  • 15.12. Java – Метод hashCode()
  • 15.13. Java – Метод indexOf()
  • 15.14. Java – Метод intern()
  • 15.15. Java – Метод lastIndexOf()
  • 15.16. Java – Метод length()
  • 15.17. Java – Метод matches()
  • 15.18. Java – Метод regionMatches()
  • 15.19. Java – Метод replace()
  • 15.20. Java – Метод replaceAll()
  • 15.21. Java – Метод replaceFirst()
  • 15.22. Java – Метод split()
  • 15.23. Java – Метод startsWith()
  • 15.24. Java – Метод subSequence()
  • 15.25. Java – Метод substring()
  • 15.26. Java – Метод toCharArray()
  • 15.27. Java – Метод toLowerCase()
  • 15.28. Java – Метод toString()
  • 15.29. Java – Метод toUpperCase()
  • 15.30. Java – Метод trim()
  • 15.31. Java – Метод valueOf()
  • 15.32. Java – Классы StringBuilder и StringBuffer
  • 15.32.1. Java – Метод append()
  • 15.32.2. Java – Метод reverse()
  • 15.32.3. Java – Метод delete()
  • 15.32.4. Java – Метод insert()
  • 15.32.5. Java – Метод replace()
  • 16. Java – Массивы
  • 17. Java – Дата и время
  • 18. Java – Регулярные выражения
  • 19. Java – Методы
  • 20. Java – Потоки ввода/вывода, файлы и каталоги
  • 20.1. Java – Класс ByteArrayInputStream
  • 20.2. Java – Класс DataInputStream
  • 20.3. Java – Класс ByteArrayOutputStream
  • 20.4. Java – Класс DataOutputStream
  • 20.5. Java – Класс File
  • 20.6. Java – Класс FileReader
  • 20.7. Java – Класс FileWriter
  • 21. Java – Исключения
  • 21.1. Java – Встроенные исключения
  • 22. Java – Вложенные и внутренние классы
  • 23. Java – Наследование
  • 24. Java – Переопределение
  • 25. Java – Полиморфизм
  • 26. Java – Абстракция
  • 27. Java – Инкапсуляция
  • 28. Java – Интерфейсы
  • 29. Java – Пакеты
  • 30. Java – Структуры данных
  • 30.1. Java – Интерфейс Enumeration
  • 30.2. Java – Класс BitSet
  • 30.3. Java – Класс Vector
  • 30.4. Java – Класс Stack
  • 30.5. Java – Класс Dictionary
  • 30.6. Java – Класс Hashtable
  • 30.7. Java – Класс Properties
  • 31. Java – Коллекции
  • 31.1. Java – Интерфейс Collection
  • 31.2. Java – Интерфейс List
  • 31.3. Java – Интерфейс Set
  • 31.4. Java – Интерфейс SortedSet
  • 31.5. Java – Интерфейс Map
  • 31.6. Java – Интерфейс Map.Entry
  • 31.7. Java – Интерфейс SortedMap
  • 31.8. Java – Класс LinkedList
  • 31.9. Java – Класс ArrayList
  • 31.10. Java – Класс HashSet
  • 31.11. Java – Класс LinkedHashSet
  • 31.12. Java – Класс TreeSet
  • 31.13. Java – Класс HashMap
  • 31.14. Java – Класс TreeMap
  • 31.15. Java – Класс WeakHashMap
  • 31.16. Java – Класс LinkedHashMap
  • 31.17. Java – Класс IdentityHashMap
  • 31.18. Java – Алгоритмы Collection
  • 31.19. Java – Iterator и ListIterator
  • 31.20. Java – Comparator
  • 32. Java – Дженерики
  • 33. Java – Сериализация
  • 34. Java – Сеть
  • 34.1. Java – Обработка URL
  • 35. Java – Отправка Email
  • 36. Java – Многопоточность
  • 36.1. Java – Синхронизация потоков
  • 36.2. Java – Межпоточная связь
  • 36.3. Java – Взаимная блокировка потоков
  • 36.4. Java – Управление потоками
  • 37. Java – Основы работы с апплетами
  • 38. Java – Javadoc

Абстракция в Java

Читаю про ООП и там сказано , что у ООП есть 3 основных основных понятия. Это инкапсуляция, полиморфизм и наследование. Так же сказано , что к ним еще можно отнести абстракцию. Про первые три понятия я понял , а вот про абстракцию что то вообще ничего не пойму. Можете на каком то понятном примере объяснить , что такое абстракция в ООП ? (Книга : «ОО Анализ и Проектирование» , Гради Буч ). У первых трех понятий есть конкретное применение в языке , а про абстракцию читаю только в теории и не пойму зачем она и какой в ней смысл ?

Отслеживать
1,552 2 2 золотых знака 10 10 серебряных знаков 17 17 бронзовых знаков
задан 5 дек 2013 в 15:06
521 2 2 золотых знака 10 10 серебряных знаков 23 23 бронзовых знака
5 дек 2013 в 21:55

4 ответа 4

Сортировка: Сброс на вариант по умолчанию

Отличный вопрос! чтобы понять, что такое Абстракция можно почитать пару статей из интернета (один, два).

Но по сути достаточно запомнить следующее:

(абстракция будет возрастать с каждым пунктом)

1) instance (Объект) сущность обладающая набором характеристик свойственных конкретному экземпляру класса. Имеет конкретные значения полей (низший уровень, без абстракции)

2) class (класс) описание множества объектов схожих по свойствам и внутренней структуре (шаблон для создания объектов).

3) abstract class (Абстрактный класс) — абстрактное описание характеристик множества классов (выступает как шаблон для наследования другими классами). Имеет высокий уровень абстракции, в связи с чем, от абстрактного класса нельзя создавать объекты напрямую* (только через создание объектов от классов наследников)

Внутри абстрактного класса могут присутствовать методы с реализацией (но не обязательно)

4) interface (Интерфейс) — это конструкция языка программирования Java, в рамках которой могут описываться только абстрактные публичные методы (abstract public) и статические константы свойства (final static). То есть также, как и на основе абстрактных классов, на основе интерфейсов нельзя порождать объекты.

upd: Начиная с Java 8 кроме абстрактных методов и констант мы также можем использовать в интерфейсах стандартные методы (default methods) и статические методы (static methods).

немного о реализации:

классы в java не поддерживают множественное наследование(это касается и абстрактных классов), поэтому могут наследоваться (напрямую), лишь от одного родителя:

class Имя_класса_наследника extends Имя_класса_родителя < // реализация >

за-то класс может реализовывать множество интерфейсов

class Имя_класса implements интерфейс_1, интерфейс_2, . ,интерфейс_N < // реализация методов интерфейсов // и реализация собственных методов >

Один интерфейс может быть наследником (может расширяться) нескольких интерфейсов:

interface интерфейс_1 extends интерфейс_2, интерфейс_3, . , интерфейс_N < //описание методов и полей для интерфейс_1 //также методов и поля будут взяты из интерфейсов интерфейс_2 . интерфейс_N >

Классы могут реализовывать интерфейсы (т. е. получать от интерфейса список методов и описывать реализацию каждого из них), притом, что особенно важно, один класс может реализовывать сразу несколько интерфейсов:

class Имя_класса implements интерфейс_1, интерфейс_2, . ,интерфейс_N < // реализация методов интерфейсов // и реализация собственных методов >

Класс может напрямую наследовать свойства и методы, только от одного родительского класса (extends), и одновременно с этим, он может реализовывать множество интерфейсов (implements):

class Имя_класса extends Имя_класса_2 implements интерфейс_1,интерфейс_2. интерфейс_N < // реализация методов интерфейсов // реализация собственных методов // переопределение методов родительского класса >

Вывод: так как интерфейс схож с абстрактным классом, но позволяет (неявно) выполнить множественное расширение — он имеет максимальный уровень Абстракции

Что такое абстрактные классы и методы в Java

Абстрагирование – это процесс, в ходе которого от пользователя скрываются многие детали реализации, а предоставляются только те детали, которые действительно важны. Так удаётся сфокусироваться на том, что делает объект, а не как он это делает.

В Java абстрактные классы и методы – это основные инструменты для реализации абстракций. Абстрактные классы служат шаблонами для создания субклассов, а абстрактные методы можно сравнить с чертежами, описывающими поведение этих субклассов.

Если вы новичок в Java или хотите освежить знания о том, чем отличаются абстрактные классы или интерфейсы, то можете почитать руководство и на эту тему: Difference Between Interface and Abstract class in Java.

Абстрактные классы
Определение синтаксиса абстрактных классов в Java

Абстрактным называется такой класс, экземпляр которого нельзя создать сам по себе – он служит основой для других классов. При объявлении такого класса в его определении ставится ключевое слово abstract .

public abstract class Shape < // class body >

Обратите внимание: абстрактные классы могут содержать как абстрактные, так и неабстрактные методы, а также переменные экземпляров, конструкторы и другие члены. Правда, напрямую инстанцировать абстрактные классы нельзя, а это означает, что их не получится напрямую использовать для создания объектов.

Различия между абстрактными и конкретными классами

Для абстрактных классов (в отличие от конкретных) нельзя напрямую создавать экземпляры. Напротив, абстрактные классы непосредственно предназначены для того, чтобы их расширяли другие классы, которые затем могут реализовывать абстрактные методы и наследовать неабстрактные члены и поведение абстрактного класса.

Кроме того, у абстрактных классов могут быть конструкторы, но их нельзя вызывать прямо из субклассов. Напротив, конструктор конкретного субкласса обязан явно вызывать конструктор соответствующего суперкласса. Для этого вызывается либо super() , либо конкретный конструктор суперкласса.

Когда использовать абстрактные классы: пример

Абстрактные классы часто применяются для определения общего интерфейса или такого поведения, которое может совместно использоваться сразу множеством субклассов. Например, представьте, что вы проектируете игру, в которой используются различные фигуры – скажем, круги, квадраты и треугольники. У всех этих фигур есть определённые общие свойства, например, периметр и площадь. Но у них могут быть и уникальные характеристики, такие как количество сторон и радиус.

Чтобы представить эти фигуры в вашей игре, можно создать абстрактный класс Shape, определяющий общее поведение для всех фигур:

public abstract class Shape < protected int x, y; public Shape(int x, int y) < this.x = x; this.y = y; >public abstract double getArea(); public abstract double getPerimeter(); >

В этом примере класс Shape содержит переменные экземпляра для координат x и y некоторой фигуры, а также абстрактные методы для вычисления площади и периметра. Определяя эти методы как абстрактные, мы позволяем каждому конкретному субклассу реализовать их по-своему.

Например, можно было бы создать субкласс Circle , расширяющий класс Shape и реализующий собственные версии методов getArea() и getPerimeter() :

public class Circle extends Shape < private double radius; public Circle(int x, int y, double radius) < super(x, y); this.radius = radius; >public double getArea() < return Math.PI * radius * radius; >public double getPerimeter() < return 2 * Math.PI * radius; >> 

Аналогично, можно было бы создать субклассы Square и Triangle , также реализующие собственные версии методов getArea() и getPerimeter() , в то же время наследующие координаты x и y от суперкласса Shape .

Используя абстрактные классы таким образом, мы создаём гибкую и расширяемую систему, позволяющую представлять в нашей игре различные фигуры, в то же время выдерживая общий интерфейс для всех субклассов, обеспечивающий общность их поведения.

Абстрактные методы
Определение и синтаксис абстрактных методов в Java

Абстрактным называется такой метод, который объявляется, но не предоставляет реализации. Он объявляется при помощи ключевого слова abstract, присутствующего в сигнатуре этого метода, и это ключевое слово обязательно должно быть включено в абстрактный класс.

public abstract double getArea();

Обратите внимание: в абстрактных методах нет тела, но они могут содержать возвращаемый тип, параметры и модификаторы. Ответственность за реализацию абстрактного метода ложится на конкретные субклассы, расширяющие абстрактный класс.

Правила и ограничения при работе с абстрактными методами

Существует несколько правил и ограничений, применимых к абстрактным методам в Java:

  • Абстрактный метод не может быть объявлен как final или private.
  • Абстрактный метод обязательно должен объявляться внутри абстрактного класса.
  • Конкретный субкласс, расширяющий абстрактный класс, обязательно должен предоставлять реализацию для всех его унаследованных абстрактных методов.

Мы уже определили абстрактный класс Shape , содержащий абстрактные методы для вычисления площади и периметра фигуры:

public abstract class Shape < protected int x, y; public Shape(int x, int y) < this.x = x; this.y = y; >public abstract double getArea(); public abstract double getPerimeter(); >

Чтобы создать конкретный субкласс Shape , необходимо реализовать следующие абстрактные методы:

public class Circle extends Shape < private double radius; public Circle(int x, int y, double radius) < super(x, y); this.radius = radius; >public double getArea() < return Math.PI * radius * radius; >public double getPerimeter() < return 2 * Math.PI * radius; >>

В данном примере класс Circle реализует методы getArea() и getPerimeter() при помощи собственных уникальных формул для расчёта площади круга и периметра окружности.
Аналогично, можно было бы создать субклассы Square и Triangle , реализующие собственные версии методов getArea() и getPerimeter().

Используя абстрактные методы в сочетании с абстрактными классами, можно предоставить общий интерфейс для вычисления площади и периметра различных фигур, в то же время позволяя каждому конкретному субклассу по-своему реализовывать эти методы.

Наилучшие практики

Работая с абстрактными классами и методами в Java, нужно держать в уме некоторые наилучшие практики. Вот некоторые рекомендации, которые помогут вам эффективно пользоваться этими мощными инструментами:

  1. Пользуйтесь абстрактными классами, чтобы моделировать иерархии взаимосвязанных классов: при помощи абстрактных классов очень удобно представить группу таких взаимосвязанных классов, которые совместно используют некий общий функционал. Создавая абстрактный класс, который определяет общие методы и свойства, вы тем самым избегаете дублирования, повышаете модульность вашего кода и облегчаете его поддержку.
  2. Пользуйтесь абстрактными методами, чтобы определять общее поведение: абстрактные методы полезны в тех случаях, когда требуется навязать конкретное поведение сразу для множества субклассов. Определяя абстрактный метод в абстрактном классе, вы можете гарантировать, что все субклассы (каждый по-своему) будут реализовывать одно и то же поведение.
  3. Не переборщите с абстрактными классами и методами: притом, что абстрактные классы и методы могут быть довольно мощными, важно не прибегать к ним сверх меры. Вообще, следует создавать абстрактный класс или метод только в том случае, когда на то есть явная причина. Если слишком активно ими пользоваться, то код может излишне усложниться, и его станет тяжелее поддерживать.
  4. Придерживайтесь соглашений об именованиях: подбирая имена для абстрактных классов и методов, важно придерживаться стандартных соглашений об именованиях, действующих в Java. Именем абстрактного класса должно быть абстрактное существительное (напр., “Shape”), а имена абстрактных методов должны быть глаголами (напр. “draw”).
  5. Документируйте ваш код: как и при работе с любым кодом, абстрактные классы и методы важно документировать, чтобы они были понятнее другим разработчикам. Снабжайте код чёткими и краткими комментариями, которые поясняли бы смысл поведения каждого класса и метода, а также их назначение.

Заключение

Итак, абстрактные классы и методы – это мощные инструменты для реализации абстракций в Java. Умело пользуясь ими, вы сможете создавать более модульный и удобный в поддержке код, который проще понимать и расширять. Если вы моделируете иерархии взаимосвязанных классов или определяете общее поведение, которое должно реализовываться сразу во множестве субклассов, то вам в этом могут особенно помочь абстрактные классы и методы. Пользуясь рекомендованными практиками, рассмотренными выше, вы сможете освоить этот важный аспект программирования на Java.

Часто задаваемые вопросы

• Могут ли у абстрактных классов быть конструкторы?

Да, у абстрактных классов могут быть конструкторы. Правда, их нельзя напрямую инстанцировать, поэтому их конструкторы обычно вызываются конструкторами их субклассов.

• Могут ли абстрактные классы реализовывать интерфейсы?
Да, абстрактные классы могут реализовывать интерфейсы, это могут делать вообще любые классы. Эта возможность может пригодиться, если вы хотите предоставить некое общее поведение сразу для нескольких классов, так, чтобы они реализовывали один и тот же интерфейс.

• Могут ли абстрактные методы быть статическими?
Нет, абстрактные методы не могут быть статическими, так как для их работы требуется вызвать экземпляр класса. Правда, статические методы могут вызывать абстрактные методы, если они реализованы в конкретных субклассах.

• Могут ли абстрактные классы быть финальными?
Нет, абстрактные классы не могут быть финальными, так как они предназначены именно для расширения субклассами. Если сделать абстрактный класс финальным, то такое расширение будет исключено.

• Когда следует использовать абстрактные классы вместо интерфейсов?
Абстрактные классы хорошо вам подойдут, если вы хотите предоставить некоторый общий функционал для множества классов, входящих в общую иерархию. Интерфейсы лучше подходят для определения такого набора, методы из которого разные классы могут реализовывать независимо. Правило такое: пользуйтесь абстрактными классами, когда хотите предоставить базовую реализацию для группы взаимосвязанных классов. Интерфейсы уместнее, когда нужно определить группу методов для реализации разрозненными классами, в каждом по-своему.

  • Блог компании Издательский дом «Питер»
  • Java
  • Совершенный код
  • ООП

Руководство по Java Core. Абстракция.

Что такое абстракция. Когда мы говорим слово “программа”, мы подразумеваем некую сущность, которая решает определённые задачи. Мы опускаем тот факт, что программа состоит из объектов, методов, классов и т.д.

В этом случае мы можем сказать, что программа – это абстракция.

Ранее мы уже обсуждали инкапсуляцию на примере полей класса. Теперь рассмотрим ситуацию, когда мы “прячем” от пользователя саму реализацию определённого функционала. То есть, мы акцентируем внимание на том, какую работу выполняет класс, а не на том, как именно он её выполняет.

В языке программирования Java, абстракция реализуется с помощью интерфейсов и абстрактных классов.

Абстрактные классы

Абстрактным называют класс, который не может иметь экземпляров. Также, он может содержать абстрактные методы (методы без реализации). Для того чтобы сделать класс абстрактным, необходимо применить ключевое слово abstract. Вот некоторые данные об абстрактных классах:

  • Абстрактный класс не может иметь ни одного экземпляра.
  • Если мы наследуем абстрактный класс, то мы должны имплементировать все его абстрактные методы (методы без реализации).
  • Абстрактный класс может содержать обычные и/или абстрактные методы.
  • Если класс содержит хотя бы один абстрактный метод, то он должен быть объявлен, как абстрактный.

Для понимания того, как это работает на практике, рассмотрим пример простого приложения.

Пример:
Абстрактный класс Profession

 public abstract class Profession < String professionName; String industry; public Profession(String professionName, String industry) < this.professionName = professionName; this.industry = industry; >public String getProfessionName() < return professionName; >public void setProfessionName(String professionName) < this.professionName = professionName; >public String getIndustry() < return industry; >public void setIndustry(String industry) < this.industry = industry; >public abstract void doJob(); @Override public String toString() < return "Profession Info:" + "\nProfession Name: " + professionName + "\nIndustry: " + industry + "\n"; >> 
 public class Developer extends Profession < private String specialty; public Developer(String professionName, String industry, String specialty) < super(professionName, industry); this.specialty = specialty; >public String getSpecialty() < return specialty; >public void setSpecialty(String specialty) < this.specialty = specialty; >@Override public void doJob() < System.out.println("Developer writes code. "); >@Override public String toString() < return "Developer Info" + "\nProfession Name: " + this.getProfessionName() + "\nIndustry: " + this.getIndustry() + "\nSpecialty: " + specialty; >> 
 public class Pilot extends Profession < private String aircraftType; public Pilot(String professionName, String industry, String aircraftType) < super(professionName, industry); this.aircraftType = aircraftType; >public String getAircraftType() < return aircraftType; >public void setAircraftType(String aircraftType) < this.aircraftType = aircraftType; >@Override public void doJob() < System.out.println("Pilot controls " + this.aircraftType); >@Override public String toString() < return "Pilot Info" + "\nProfession Name: " + this.getProfessionName() + "\nIndustry: " + this.getIndustry() + "\nAircraft type: " + aircraftType; >> 
 public class ProfessionDemo < public static void main(String[] args) < Developer developer = new Developer("Developer", "IT", "Java"); Pilot pilot = new Pilot("Pilot", "Aviation", "Boeing 737-800"); Profession cppDeveloper = new Developer("Developer", "IT", "C++"); System.out.println(developer); System.out.println("======================="); System.out.println(pilot); System.out.println("====================== Java developer writes Java Code. "); >@Override public void enjoyLife() < System.out.println("Java developer enjoys life. "); >@Override public void breath() < System.out.println("Breathing like a human. "); >@Override public String toString() < return "Java Developer" + "\nName: " + name + "\n"; >> 
 public class CppDeveloper implements Developer, Human < private String name; public CppDeveloper(String name) < this.name = name; >public String getName() < return name; >public void setName(String name) < this.name = name; >@Override public void writeCode() < System.out.println("C++ Developer writes C++ code. "); >@Override public void enjoyLife() < System.out.println("C++ Developer does not have time to enjoy life, he learn C++ all time. "); >@Override public void breath() < System.out.println("Breathing like a human. "); >@Override public String toString() < return "C++ Developer" + "\nName: " + name + "\n"; >> 
 public class DeveloperRunner < public static void main(String[] args) < JavaDeveloper javaDeveloper = new JavaDeveloper("Java Man"); CppDeveloper cppDeveloper = new CppDeveloper("Cpp Hero"); System.out.println("Developers Info:"); System.out.println(javaDeveloper); System.out.println(cppDeveloper); System.out.println("Java Developer's methods: "); javaDeveloper.breath(); javaDeveloper.writeCode(); javaDeveloper.enjoyLife(); System.out.println("\n==============\n"); System.out.println("C++ Developer's methods: "); cppDeveloper.breath(); cppDeveloper.writeCode(); cppDeveloper.enjoyLife(); >> 

В результате работы программы мы получим следующий результат:

 Developers Info: Java Developer Name: Java Man C++ Developer Name: Cpp Hero Java Developer's methods: Breathing like a human. Java developer writes Java Code. Java developer enjoys life. ============== C++ Developer's methods: Breathing like a human. C++ Developer writes C++ code. C++ Developer does not have time to enjoy life, he learn C++ all time. 

Существует ряд правил реализации интерфейсов:

  • Класс может имплементировать более любое количество интерфейсов.
  • Интерфейс может наследовать другой интерфейс (по аналогии с классами).

Для того чтобы наследовать интерфейс, нам необходимо использовать ключевое слово extends.

Рассмотрим следующий пример.

Пример:
У нас есть интерфейс Job, который имеет один метод doJob(). Другой интерфейс – ProductManagement наследует этот интерфейс и добавляет свой собственный getPowerOverDevelopers().

Класс ProductManager, который имплементирует интерфейс ProductManagement, должен реализовывать все методы этих классов.

 public interface Job
 public interface ProductManagement extends Job
 public class ProductManager implements ProductManagement < private String name; public ProductManager(String name) < this.name = name; >public String getName() < return name; >public void setName(String name) < this.name = name; >@Override public void getPowerOverDevelopers() < System.out.println("Product Manger responsible for bonuses. "); >@Override public void doJob() < System.out.println("Product manager controls everything. "); >@Override public String toString() < return "Product Manager: " + "\nName: " + name + "\n"; >> 
 public class ProductManagerRunner < public static void main(String[] args) < ProductManager productManager = new ProductManager("Number One"); System.out.println("Product Manager Info"); System.out.println(productManager); System.out.println("Product Manager's methods:"); productManager.doJob(); productManager.getPowerOverDevelopers(); >> 

В результате работы программы мы получим следующий результат:

 /*Some system messages*/ Product Manager Info Product Manager: Name: Number One Product Manager's methods: Product manager controls everything. Product Manger responsible for bonuses. 

В этом уроке мы глубже изучили понятие абстракции и её реализацию в языке программирования Java в виде абстрактных классов и интерфейсов. Мы рассмотрели несколько примеров с их использованием.

В следующем уроке мы рассмотрим структуры данных в языке Java.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *