3.01M
Категория: ПрограммированиеПрограммирование

Объектно-ориентированное программирование в Java

1.

Объектно-ориентированное
программирование в Java
9 ноября 2016
Хранина Ирина
Халимов Руслан
1

2.

Содержание занятия
1. Основные концепции ООП
2. Абстрактные классы и методы
3. Виртуальные методы и позднее связывание
4. Пакеты и директивы импорта
5. Практическое задание
2

3.

1. Основные концепции ООП
3

4.

Основные концепции ООП
Определение и назначение
Объектно-ориентированное программирование
(ООП) – это парадигма программирования, в
которой
программа
строится
из
взаимодействующих объектов.
ООП
позволяет
эффективно
использовать
продуктивность разработчиков и с минимальными
затратами создавать масштабируемые системы.
4

5.

Основные концепции ООП
Используемые понятия
Основными понятиями ООП являются:
• Объект
• Класс
• Наследование
• Полиморфизм
• Инкапсуляция
• Абстрагирование
5

6.

Основные концепции ООП
Объект
Объект – некоторая сущность реального мира (например, человек, место
или какое-либо понятие), обладающая состоянием, определяемым
заданными значениями своих свойств (набором данных – атрибутов),
и
поведением, определяемым операциями (методами) над своими
атрибутами.
Свойства объекта:
• Объект принадлежит одному классу (в Java), который определяет
поведение (является «моделью») объекта.
• Объект имеет внутреннее состояние (в Java это поля – переменные).
• Может оперировать своими данными напрямую.
• Объекты могут взаимодействовать между собой путем отправки друг
другу сообщений (в Java – через методы).
Объект – это данные и методы для работы с этими данными.
В Java все является объектом, кроме примитивных типов.
6

7.

Основные концепции ООП
Класс. Определение и ограничения
Класс

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

8.

Основные концепции ООП
Класс. Пример
Класс может содержать:
• поля,
• методы,
• вложенные классы и интерфейсы.
Пример класса Person:
public class Person {
public static final boolean RESIDENT
= true;
public static final boolean NOT_RESIDENT = false;
private
private
private
private
private
Long id;
String firstName;
String lastName;
int age;
boolean isResident;
}
8

9.

Основные концепции ООП
Класс. Особенности и модификаторы
Поля класса инициализируются значениями по умолчанию.
Модификатор final в контексте класса не допускает наследование
класса.
Модификатор public является признаком общедоступности класса.
Модификатор abstract является признаком абстрактности класса.
Если класс объявлен final
и abstract (взаимоисключающие понятия),
произойдет ошибка компиляции.
Так как final класс не может наследоваться, его методы никогда не могут
быть переопределены.
9

10.

Основные концепции ООП
Класс. Конструкторы
Процесс создания объекта класса называется его конструированием (construction).
При создании объекта:
• выделяется под него память;
• происходит инициализация атрибутов (свойств)
определены;
• предоставляется доступ к атрибутам и методам.
объекта,
Существует два вида конструктора:
• явный – описывается разработчиком внутри класса;
• неявный – конструктор по умолчанию, который
автоматически.
JVM
если
они
реализует
Также:
• Память для объекта класса выделяет оператор new
• Конструкторы предназначены для формирования начального состояния объекта.
• Правила написания конструктора сходны с правилами написания методов.
• Имя конструктора совпадает с именем класса.
10

11.

Основные концепции ООП
Класс. Конструкторы
Пример:
public class SampleClass {
int field;
private void method1() {
field = 1;
}
public String method2() {
return "Hello World!";
}
public SampleClass() {
field = 0;
// конструктор
}
public SampleClass(String name) {
// перегруженный (overloaded ) конструктор
System.out.println("Hello " + name);
}
public void SampleClass() {
field = 0;
}
// обычный метод!
}
11

12.

Модификатор Static
• Класс – это описание свойств и методов некоторого
объекта.
• Объект – экземпляр (инстанс) класса.
• Поля и методы объекта существуют только, когда
объект создан.
• static – означает, что поле или метод принадлежит
классу, как таковому, а не конкретному объекту.
Обращаться к такому полю (методу) можно через
имя класса.
12

13.

Модификатор Static
Public class StaticDemo{
class Account{
public static void main(String[] args){
static int idCounter = 0;
int current = Account.idCounter;
int id;
for(int i = 0; i < 5; i++){
public Account() {
Account acc = new Account();
this.id = idCounter++;
log.info(acc.toString());
}
}
Account acc = null;
// Так делать нехорошо!!!
@override
acc.idCounter = 10;
public String toString(){
return “Account: id = ” +
// А так можно
id.toString();
Account.idCounter = 10;
}
}
}
}
13

14.

Основные концепции ООП
Класс. Конструкторы
• Для конструкторов разрешено
модификаторов доступа.
использование
только
• При написании конструктор не имеет возвращаемого типа.
• Оператор возврата return
текущего конструктора.
прекращает
выполнение
• Конструкторы могут быть перегружены (overloaded).
• Конструкторы могут вызывать друг друга с помощью
ключевого слова this в первой строке конструктора.
• Конструкторы могут вызывать конструкторы
предков с помощью ключевого слова super
классов14

15.

Основные концепции ООП
Класс. Конструкторы
Конструктор по умолчанию:
• Если в классе явно не описан ни один конструктор,
автоматически создается т.н. конструктор по умолчанию,
не имеющий параметров.
• Если в классе описан хотя бы один
конструктор, то
неявный конструктор по умолчанию не создается.
• Также конструктором по умолчанию называют конструктор,
не имеющий параметров.
15

16.

Основные концепции ООП
Класс. Деструктор и «сборка мусора»
Механизм, осуществляющий удаление объекта называется деструктором.
В ряде языков деструкторы выполняют действия, обратные действию конструкторов:
освобождают память, занимаемую объектом, и «деинициализируют» объект
(освобождают ресурсы, очищают связи, изменяют состояние связанных объектов).
Если после вызова деструктора где-то осталась ссылка (указатель)
на объект, ее
использование приведет к возникновению ошибки.
В Java деструкторов нет, вместо них применяется механизм автоматической
сборки мусора:
• В случае нехватки памяти для создания очередного объекта виртуальная машина
находит недостижимые объекты и удаляет их.
• Процесс сборки мусора можно инициировать принудительно.
• Для явного удаления объекта следует
удалить все ссылки на этот
объект и
инициировать сбор мусора.
• Взаимодействие со сборщиком осуществляется через системные классы
java.lang.System и java.lang.Runtime
В Java существует метод void finalize(), но пользоваться им не рекомендуется (не
известно, когда будет вызван). При необходимости освободить ресурсы заводят
обычный метод void close() или void dispose() и вызывают его явно.
16

17.

Основные концепции ООП
Класс. Блоки инициализации
Если некоторые действия по инициализации должны выполняться в любом варианте создания
объекта, удобнее использовать блоки инициализации.
Тело блока инициализации заключается в фигурные скобки и располагается на одном уровне с
полями и методами класса.
При создании объекта сначала выполняются инициализирующие выражения полей и блоки
инициализации (в порядке их описания в теле класса) и только потом тело конструктора.
// пример блока инициализации
class Student {
public long id;
public String name = “noname”;
public Group group;
{ // блок инициализации
id = -1;
}
public Student() {
// ...
}
public Student(String name) {
this.name = name;
}
}
17

18.

Основные концепции ООП
Класс. Блоки инициализации
Статический блок инициализации выполняет инициализацию контекста
класса.
Вызов статического блока инициализации происходит в процессе загрузки
класса в виртуальную машину.
Пример:
class Student {
static int[] marks = new int[10];
// пример статического блока инициализации:
static {
for (inti= 0; i< marks.length; i++)
marks[i] = 0;
}
// ...
}
18

19.

Основные концепции ООП
• Почему main() – static?
• Можно ли переопределить статический метод
в дочернем классе?
• Перечислите плюсы и
переменной.
минусы статической
19

20.

Основные концепции ООП
Наследование
Наследование – создание производных классов, наследующих свойства базового.
При этом существуют:
• Дочерний класс (потомок, subclass) – класс, наследующий от другого
класса.
Родительский класс (предок, super class) – класс, поведение которого
наследуют другие классы (потомки).
Пример наследования:
// класс -предок
class User{
long id;
String name;
short age;
public void like(Photo photo){}
}
}
// класс -потомок, наследующий метод like() родительского класса
class Admin extends User{
Permission permission;
void ban(User user){}
}
20

21.

Основные концепции ООП
Наследование
Композиция Отношение Has-A. Класс обладает свойствами своих составных
частей. Абстрагируемся от реализации, используем интерфейс. Можем динамически
менять поведение класса.
Пример композиции:
class Robot
{
// Робот управляется оператором
private Operator operator;
// Можно узнать какой оператор
управляет роботом
public Operator getOperator() {
return operator;
}
// Можно установить оператора для
робота
public void setOperator(Operator
operator) {
this.operator = operator;
}
class Operator {
// Оператор управляет конкретным роботом
private Robot robot;
public Operator(String firstName, String
lastName) {…}
// У оператора можно спросить каким
// роботом он управляет
public Robot getRobot() {
return robot;
}
// Оператору можно поручить управлять
// роботом
public void setRobot(Robot robot) {
this.robot = robot;
}
}
}
21

22.

Основные концепции ООП
Наследование: Преимущества и недостатки
• (+)
– Повторное
использование
протестированных участков кода.
– Композиция
наследованию.

проверенных
альтернатива
и
множественному
• (-)
– Дочерний класс зависит от изменений в родительском.
– Сложность
расширения
наследовании.
функционала
при
неверном
22

23.

Основные концепции ООП
Наследование: Самопроверка
Для каких пунктов справедливо отношение
наследования и почему?
• Фотография и фотоальбом.
• Видеоролик и рекламный ролик.
• Чат и мультичат.
• Медиа-пост в ленте и текстовый пост.
23

24.

Основные концепции ООП
Инкапсуляция
• Контроль доступа.
• Контроль целостности / валидности данных.
• Возможность изменения реализации.
24

25.

Основные концепции ООП
Инкапсуляция: Уровни доступа
Access
Modifiers
Same class
Same
package
Subclass
Other
package
Public
+
+
+
+
Protected
+
+
+
-
No access
modifier
+
+
-
-
Private
+
-
-
-
25

26.

Класс Object
Методы:
• toString()
• hashCode()
• equals()
• getClass()
• wait()
• notify()
• clone()
26

27.

Equals
class User {
int id;
String name;
public User(int id, String name) {
this.id = id;
this.name = name;
}
}
User u1 = new User(1, “Bob”);
User u2 = new User(1, “Bob”);
User bob = u1;
Что вернут
операции?
следующие
Assert(u1 == u2);
При отсутствии переопределения метода
equals() в пользовательском классе, будет
использоваться метод сравнения по
умолчанию – сравнение по ссылке, а не по
содержимому объекта.
Assert(u1.equals(u2));
Assert(u1 == bob);
Assert(u1.equals(bob));
27

28.

Equals
Пример переопределения метода equals() в пользовательском классе User
class User {
public boolean equals(Object other) {
if (other == null) return false;
if (other == this) return true;
if (!(other instance of this)) return false;
User otherUser = (User) other;
return ((id == otherUser.id) &&
(name != null) &&
(name.equals(otherUser.name));
}
}
User u1 = new User(1, “Bob”);
Что вернут следующие
операции теперь?
User u2 = new User(1, “Bob”);
Assert(u1 == u2);
User bob = u1;
Assert(u1.equals(u2));
Assert(u1 == bob);
Assert(u1.equals(bob));
28

29.

Основные концепции ООП
Абстракция
Абстрактный класс:
• Определяет «каркас» поведения.
• Детали
отданы
дочерним
классам
на
переопределение,
а
общее
поведение
вынесено в родительский абстрактный класс.
• Создать экземпляр такого класса нельзя,
его описание неполно.
т.к.
29

30.

Абстрактные классы
и методы
• Модификатор abstract применяется только для методов и
классов;
• У абстрактных методов нет тела метода;
• Абстрактный класс должен содержать по крайней мере один
абстрактный метод;
• Является противоположностью final:
final класс не может
наследоваться, abstract класс обязан наследоваться.
Класс должен быть объявлен как abstract если:
• он содержит хотя бы один абстрактный метод;
• он не предоставляет реализацию наследуемых абстрактных
методов;
• он не предоставляет реализацию методов интерфейса,
реализацию которого он объявил;
• необходимо запретить создание экземпляров класса.
30

31.

Абстрактные классы
и методы
Примеры абстрактных класса и метода:
// абстрактный класс ClientImpl:
public abstract class ClientImpl {
private Long id;
// абстрактный метод getFullName:
public abstract String getFullName();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
protected abstract void proccessData();
protected void onError(){
return “Failed parsing”;}
}
31

32.

Абстрактные классы
и методы
Пример реализации абстрактного класса:
// абстрактный класс ClientImpl:
public class Client extends ClientImpl {
@Override
public String getFullName();
@Override
protected void proccessData(){…};
@Override
protected void onError(){
return “Failed define text”;}
}
32

33.

Основные концепции ООП
Полиморфизм
• Дочерний класс может быть использован везде,
используется родительский класс.
где
• Если дочерний класс приведен к родительскому
классу, то доступны только методы родительского
класса (по типу ссылки).
• Вызывается
реализация
класса(@Override).
из
дочернего
33

34.

Полиморфизм. Пример
class Parent {
void m1() {
System.out.print(“Parent");
class D {
}
public static void main(String[] args) {
}
Child child = new Child ();
Parent pchild = child;
class Child extends Parent {
@Override
child.m1();
void m1() {
pchild.m1();
}
System.out.print(" Child ");
}
}
}
}
34

35.

Связывание
Раннее связывание (compile time)
• Overloading – поиск подходящей сигнатуры
в зависимости от списка параметров.
Позднее связывание (runtime)
• Overriding – поиск подходящей реализации
(по реальному типу объекта).
35

36.

Виртуальные методы и
позднее связывание
Понятия
виртуальных
методов и
позднего
непосредственное отношение к полиморфизму.
связывания
имеют
Рассмотрим классический пример с геометрическими фигурами:
Методы drow() в каждом классе-наследнике будут переопределены, а метод
erase() будет просто наследоваться от класса Shape
36

37.

Виртуальные методы и
позднее связывание
Заполним массив
shape[] случайным
образом выбранными
объектами:
37

38.

Виртуальные методы и
позднее связывание
Присоединение вызова метода к
телу метода называется связыванием. Если связывание
проводится перед запуском программы (компилятором и компоновщиком, если он есть), то оно
называется ранним связыванием (early binding).
Проблема определения того, метод какого объекта вызывать в приведенном примере программы,
решается благодаря позднему связыванию (late binding), то есть связыванию, производимому во
время выполнения программы и в зависимости от типа объекта.
Позднее связывание также
называют динамическим (dynamic binding) или связыванием на стадии выполнения (runtime
binding).
В Java существует механизм определения фактического типа объекта во время работы
программы, для вызова подходящего метода. Иначе говоря, компилятор не знает тип объекта, но
механизм вызова методов определяет его и вызывает соответствующее тело метода.
Для всех методов Java используется механизм позднего связывания, если только метод не был
объявлен как private. Вызов private-метода компилируется в инструкцию байткода
invokespecial,
которая
вызывает
реализацию
метода
из
конкретного
класса, определенного в момент компиляции. Вызов метода с другим уровнем доступа
компилируется в invokevirtual, которая уже «смотрит» на тип объекта по ссылке в
момент исполнения. Финальные неприватные методы тоже вызываются через invokevirtual.
В инструкцию байт-кода invokespecial компилируются:
• Инициализационный вызов (<init>) при создании объекта,
• Вызов private метода,
• Вызов метода с использованием ключевого слова super
38

39.

Виртуальные методы и
позднее связывание
Пример:
Ссылка root в данном случае имеет тип Root, но указывает на объект типа Branch. И
обычные методы вызываются по версии объекта,
на который указывает ссылка.
Именно через это свойство и реализуется полиморфизм.
Но в нашем случае, несмотря на это, первая команда выведет в консоль Root, а не
Branch.
39

40.

Виртуальные методы и
позднее связывание
Почему так происходит?
Если выполнить команду: javap -c -p -v Root.class то получим следующий результат:
Как видно из вывода команда root.prt() была преобразована
типа invokespecial, а команда branch.prt() в invokevirtual
в
вызов
40

41.

4. Пакеты и директивы импорта
41

42.

Пакеты и директивы импорта
Пакеты
Пакет это:
• способ логической группировки классов;
• комплект ПО, который можно распространять независимо и
применять в сочетании с другими пакетами.
Членами пакетов являются:
• классы,
• интерфейсы,
• вложенные пакеты,
• дополнительные файлы ресурсов.
• Позволяют группировать взаимосвязанные классы и интерфейсы
в единое целое.
• Способствуют созданию пространств имен, позволяющих
избежать конфликтов
идентификаторов,
относящихся
к
различным типам.
• Обеспечивают дополнительные средства защиты элементов
кода.
• Формируют иерархическую систему.
42

43.

Пакеты и директивы импорта
Пакеты
Пакеты могут быть реализованы:
• в виде структуры каталогов с файлами классов,
• в виде jar-архива.
Путь к используемым пакетам указывается:
• непосредственно при запуске JVM,
• через
переменную
окружения
(по умолчанию CLASSPATH="").
CLASSPATH
Объявление пакета:
Первое выражение
java/lang/Object.java:
в
модуле
компиляции.
Например,
для
файла
package java.lang;
При отсутствии объявления пакета модуль компиляции принадлежит
безымянному пакету (не имеет вложенных пакетов).
Пакет доступен, если доступен модуль компиляции с объявлением пакета.
Ограничений на использование пакетов нет.
43

44.

Пакеты и директивы импорта
Пакеты
Примеры составных имен пакетов:
• Java.lang
• Java.applet
• Java.awt
• Java.io
• Java.util
• Java.net
• Java.rmi
• и т.д.
44

45.

Пакеты и директивы импорта
Пакеты
Пример создания пакета:
package MyPackage;
public class Compute{
public int Add(int x,int y){
return (x+y);
}
public int Subtract(int x,int y){
return (x-y);
}
public int Multiply(int x,int y){
return (x*y);
}
public int Divide(int x,int y){
return (x/y);
}
}
45

46.

Пакеты и директивы импорта
Пакеты
Пример использование созданного пакета MyPackage:
import MyPackage.*;
class PKDemo{
public static void main(String args[]){
Compute obj = new Compute();
int sum = obj.Add(10, 20);
int sub = obj.Subtract(20,10);
System.out.println("The total is " + sum);
System.out.println("The minus is " + sub);
}
}
46

47.

Пакеты и директивы импорта
Выражения импорта
• Доступ к типу из данного пакета осуществляется по простому имени типа.
• Доступ к типу из других пакетов осуществляется по составному имени
пакета и имени типа – такой вариант предполагает сложности при
многократном использовании.
• import-выражения упрощают доступ:
импорт одного конкретного типа:
import java.net.URL;
импорт множества типов из пакета:
import java.net.*;
• Попытка импорта пакета, недоступного на момент компиляции, вызовет
ошибку.
• Дублирование импорта игнорируется.
• Нельзя импортировать вложенный пакет:
import java.net; //ошибка компиляции
• При импорте типов пакета вложенные пакеты не импортируются!
47

48.

Пакеты и директивы импорта
Выражения импорта (продолжение)
• Алгоритм компилятора при анализе типов:
выражения, импортирующие типы,
другие объявленные типы,
выражения, импортирующие пакеты.
• Если тип импортирован явно невозможны:
объявление нового типа с таким же именем,
доступ по простому имени к одноименному типу в текущем
пакете.
• Импорт пакета не мешает объявлять новые типы или обращаться к
имеющимся типам текущего пакета по простым именам – поиск типа
осуществляется сначала в текущем пакете.
• Импорт конкретных типов дает возможность при прочтении кода сразу
понять, какие внешние типы используются – но фактически эти типы
могут и не использоваться в работе программы.
48

49.

5. Практическое задание
49

50.

Практическое задание 2
• Разработать абстрактный класс Car со строковыми полями Марка,
Госномер, переопределить метод toString()
• Реализовать 2 наследника: PassengerCar и TruckCar
• Разработать класс CarParking с полем-массивом, хранящим
автомобили разных типов.
• В основном классе приложения создать экземпляр класса-стоянки,
добавить в него 4 автомобиля разных типов.
• Вывести в консоль список автомобилей.
• Посчитать общую стоимость арендной платы за парковку, исходя из
стоимости аренды 1 машиноместа для легкового автомобиля 1000
рублей, для грузового – 1500 рублей.
50

51.

Спасибо за внимание!
51
English     Русский Правила