deb try fail

This commit is contained in:
Ivan I. Ovchinnikov 2022-12-15 11:36:00 +00:00
parent f4551ea09f
commit ab2d8730ca
24 changed files with 242 additions and 121 deletions

Binary file not shown.

BIN
build/jc3-03a.pdf Normal file

Binary file not shown.

BIN
build/jtc4-04a.pdf Normal file

Binary file not shown.

View File

@ -23,12 +23,14 @@
\newpage
\subfile{jtc2-02a}
\newpage
\subfile{jtd6-11a}
\subfile{jtc3-03a}
%\newpage
%\subfile{jtd6-11a}
\section{Специализация: ООП}
%\section{Специализация: ООП}
\section{Специализация: Тонкости работы}
Файловая система и представление данных; Пакеты \code{java.io}, \code{java.nio}, \code{String}, \code{StringBuilder}, string pool, ?JSON/XML?
%\section{Специализация: Тонкости работы}
%Файловая система и представление данных; Пакеты \code{java.io}, \code{java.nio}, \code{String}, \code{StringBuilder}, string pool, ?JSON/XML?
\newpage
\appendix

View File

@ -1,72 +0,0 @@
% enum Color{
% RED("#FF0000"), BLUE("#0000FF"), GREEN("#00FF00");
% private String code;
% Color(String code){
% this.code = code;
% }
% public String getCode(){ return code;}
% }
%public class Main{
% public static void main(String[] args) {
% System.out.println(Color.RED.getCode());
% System.out.println(Color.GREEN.getCode());
% }
%}
% package ru.gb.jcore;
% public class Orange {
% public void squeezeJuice(){
% System.out.println("Squeeze juice ...");
% }
% class Juice{
% public void flow(){
% System.out.println("Juice dripped ...");
% }
% }
% }
% package ru.gb.jcore;
% public class Main {
% public static void main(String[] args) {
% Orange orange = new Orange();
% Orange.Juice juice = orange.new Juice();
% orange.squeezeJuice();
% juice.flow();
% }
% }
%///////////////////////////////
% public class Orange {
% private Juice juice;
% public Orange(){
% this.juice = new Juice();
% }
% public void squeezeJuice(){
% System.out.println("Squeeze juice ...");
% juice.flow();
% }
% private class Juice{
% public void flow(){
% System.out.println("Juice dripped ...");
% }
% }
% }
% public class Main {
% public static void main(String[] args) {
% Orange orange = new Orange();
% orange.squeezeJuice();
% }
% }

View File

@ -401,7 +401,7 @@
Также существует понятие \textit{инициализации} -- это когда объединяются на одной строке объявление и присваивание.\end{frm}
\subsubsection{Преобразование типов}
Java - это язык со строгой статической типизацией, но преобразование типов в ней всё равно есть. Простыми словами, преобразование типов -- это когда компилятор видит, что типы переменных по разные стороны присваивания разные, начинает разрешать это противоречие, успешно или нет. Преобразование типов бывает явное и неявное. Неявное преобразование типов происходит когда компилятор в состоянии сам преобразовать типы, явное, когда ему нужна помощь.
Java -- это язык со строгой статической типизацией, но преобразование типов в ней всё равно есть. Простыми словами, преобразование типов -- это когда компилятор видит, что типы переменных по разные стороны присваивания разные, начинает разрешать это противоречие, успешно или нет. Преобразование типов бывает явное и неявное. Неявное преобразование типов происходит когда компилятор в состоянии сам преобразовать типы, явное, когда ему нужна помощь.
\begin{frm}
\info В разговоре или в сообществах можно услышать или прочитать термины тайпкастинг, кастинг, каст, кастануть, и другие производные от английского typecasting.

View File

@ -15,7 +15,7 @@
\begin{itemize}
\item \nom{Класс}{определяет форму и сущность объекта и является логической конструкцией, на основе которой построен весь язык Java. Определяет новый тип данных};
\item \nom{Объект}{конкретный экземпляр класса, созданный в программе};
\item \nom{Статика}{(статический контекст) static - (от греч. неподвижный) — раздел механики, в котором изучаются условия равновесия механических систем под действием приложенных к ним сил и возникших моментов. В языке программирования Java - принадлежность поля и его значения не объекту, а классу, и, как следствие, доступность такого поля и его значения в единственном экземпляре всем объектам класса.};
\item \nom{Статика}{(статический контекст) static -- (от греч. неподвижный) -- раздел механики, в котором изучаются условия равновесия механических систем под действием приложенных к ним сил и возникших моментов. В языке программирования Java -- принадлежность поля и его значения не объекту, а классу, и, как следствие, доступность такого поля и его значения в единственном экземпляре всем объектам класса.};
\item \nom{Стек}{структура данных, работающая по принципу LIFO (last in, first out) или FILO (first in, last out). Стековая память отвечает за хранение ссылок на объекты кучи и за хранение типов значений (также известных в Java как примитивные типы), которые содержат само значение, а не ссылку на объект из кучи.};
\item \nom{Куча}{адресуемое пространство оперативной памяти компьютера. Куча содержит все объекты, созданные в вашем приложении, независимо от того, какой поток создал объект.};
\item \nom{Сборщик мусора}{специализированная подпрограмма, очищающая память от неиспользуемых объектов.};
@ -157,7 +157,7 @@ Cat2 named: Murzik is Black has age: 6
\item Сначала создается переменная, имеющая интересующий нас тип, в неё возможно записать ссылку на объект;
\item затем необходимо выделить память под объект;
\item создать и положить объект в выделенную часть памяти;
\item и сохранить ссылку на этот объект в памяти - в нашу переменную.
\item и сохранить ссылку на этот объект в памяти -- в переменную.
\end{itemize}
Для непосредственного создания объекта применяется оператор \code{new}, который динамически резервирует память под объект и возвращает ссылку на него, в общих чертах эта ссылка представляет собой адрес объекта в памяти, зарезервированной оператором \code{new}.
@ -176,7 +176,7 @@ Cat2 named: Murzik is Black has age: 6
[квалификаторы] ИмяКласса имяПеременной = \textbf{\code{new}} ИмяКласса();
\end{frm}
Оператор \code{new} динамически выделяет память для нового объекта, общая форма применения этого оператора имеет вид как на врезке выше, но на самом деле справа - не имя класса, конструкция ИмяКласса() в правой части выполняет вызов конструктора данного класса, который подготавливает вновь создаваемый объект к работе.
Оператор \code{new} динамически выделяет память для нового объекта, общая форма применения этого оператора имеет вид как на врезке выше, но на самом деле справа -- не имя класса, конструкция ИмяКласса() в правой части выполняет вызов конструктора данного класса, который подготавливает вновь создаваемый объект к работе.
Именно от количества применений оператора \code{new} будет зависеть, сколько именно объектов будет создано в программе.
@ -210,16 +210,16 @@ Cat2 named: Murzik is Black has age: 6
\end{verbatim}
\begin{frm}\info
Множественные ссылки на один и тот же объект в памяти довольно легко себе представить как ярлыки для запуска одной и той же программы на рабочем столе и в меню быстрого запуска. Или если на один и тот же шкафчик в раздевалке наклеить два номера - сам шкафчик можно будет найти по двум ссылкам на него.
Множественные ссылки на один и тот же объект в памяти довольно легко себе представить как ярлыки для запуска одной и той же программы на рабочем столе и в меню быстрого запуска. Или если на один и тот же шкафчик в раздевалке наклеить два номера -- сам шкафчик можно будет найти по двум ссылкам на него.
\end{frm}
Важно всегда перепроверять, какие объекты созданы, а какие имеют множественные ссылки.
\subsubsection{Методы}
Ранее было сказано о том, что в языке Java любая программа состоит из классов и функций, которые могут описываться только внутри них. Именно поэтому все функции в языке Java являются методами. А метод - это функция, являющаяся частью некоторого класса, которая может выполнять операции над данными этого класса.
Ранее было сказано о том, что в языке Java любая программа состоит из классов и функций, которые могут описываться только внутри них. Именно поэтому все функции в языке Java являются методами. А метод -- это функция, являющаяся частью некоторого класса, которая может выполнять операции над данными этого класса.
\begin{frm} \info
Метод - это функция, принадлежащая классу
Метод -- это функция, принадлежащая классу
\end{frm}
Метод для своей работы может использовать поля объекта и/или класса, в котором определен, напрямую, без необходимости передавать их во входных параметрах. Это похоже на использование глобальных переменных в функциях, но в отличие от глобальных переменных, метод может получать прямой доступ только к членам класса. Самые простые методы работают с данными объектов. Методы чаще всего формируют API классов, то есть способ взаимодействия с классами, интерфейс. Место методов во взаимодействии классов и объектов показано на рис. \hrf{pic:class-obj-nostatic}.
@ -330,7 +330,7 @@ public class Cat {
}
\end{lstlisting}
Помимо того, что статические поля - это полезный инструмент создания общих свойств это ещ§ и опасный инструмент создания общих свойств. Так, например, мы знаем, что у котов четыре лапы, а не 6 и не 8. Не создавая никакого барсика будет понятно, что у кота - 4 лапы. Это полезное поведение.
Помимо того, что статические поля -- это полезный инструмент создания общих свойств это ещ§ и опасный инструмент создания общих свойств. Так, например, мы знаем, что у котов четыре лапы, а не 6 и не 8. Не создавая никакого барсика будет понятно, что у кота -- 4 лапы. Это полезное поведение.
лайвкод 03-статическое-поле-ошибка Посмотрим на опасность. Мы видим, что у каждого кота есть имя, и помним, что коты хранят значение своего имени каждый сам у себя. А знают экземпляры о названии поля потому что знают, какого класса они экземпляры. Но что если мы по невнимательности добавим свойство статичности к имени кота?
@ -390,7 +390,7 @@ public class Cat {
\begin{itemize}
\item Young Generation — область где размещаются недавно созданные объекты. Когда она заполняется, происходит быстрая сборка мусора;
\item Old (Tenured) Generation — здесь хранятся долгоживущие объекты. Когда объекты из Young Generation достигают определенного порога «возраста», они перемещаются в Old Generation;
\item Permanent Generation — эта область содержит метаинформацию о классах и методах приложения, но начиная с Java 8 данная область памяти была упразднена. В Java 8 Permanent Generation заменён на Metaspace - его динамически изменяемый по размеру аналог. Именно здесь находятся статические поля.
\item Permanent Generation — эта область содержит метаинформацию о классах и методах приложения, но начиная с Java 8 данная область памяти была упразднена. В Java 8 Permanent Generation заменён на Metaspace -- его динамически изменяемый по размеру аналог. Именно здесь находятся статические поля.
\end{itemize}
Особенности кучи:
\begin{itemize}
@ -416,7 +416,7 @@ public class Cat {
Поскольку это довольно сложный процесс и может повлиять на производительность всего приложения, он реализован весьма разумно. Для этого используется так называемый процесс «Mark and Sweep» (отмечай и подметай). Java анализирует переменные из стека и «отмечает» все объекты, которые необходимо поддерживать в рабочем состоянии. Затем все неиспользуемые объекты очищаются. Фактически, чем больше мусора и чем меньше объектов помечены как живые, тем быстрее идет процесс. Чтобы сделать это еще более оптимизированным, память кучи состоит из нескольких частей.
\begin{enumerate}
\item Молодое поколение -- Все новые объекты начинаются с молодого поколения. Как только они выделены в коде Java, они попадают в этот подраздел, называемый \textbf{eden space}. В конце концов пространство эдема заполняется объектами. На этом этапе происходит незначительная сборка мусора, так называемая minor collection. Некоторые объекты (те, на которые есть ссылки) помечаются, а некоторые (те, на которые нет ссылок) - нет. Те, которые были отмечены, затем переходят в другой подраздел молодого поколения под названием пространство выживших (само пространство выживших разделено на две части). Те, которые остались немаркированными, удаляются автоматической сборкой мусора.
\item Молодое поколение -- Все новые объекты начинаются с молодого поколения. Как только они выделены в коде Java, они попадают в этот подраздел, называемый \textbf{eden space}. В конце концов пространство эдема заполняется объектами. На этом этапе происходит незначительная сборка мусора, так называемая minor collection. Некоторые объекты (те, на которые есть ссылки) помечаются, а некоторые (те, на которые нет ссылок) -- нет. Те, которые были отмечены, затем переходят в другой подраздел молодого поколения под названием пространство выживших (само пространство выживших разделено на две части). Те, которые остались немаркированными, удаляются автоматической сборкой мусора.
\item Выжившее поколение -- Так будет продолжаться до тех пор, пока пространство eden снова не заполнится; на этом этапе начинается новый цикл. События minor collection повторяются, но в этом цикле все отмеченные объекты, которые выживают как из пространства eden, так и из S0, фактически попадают во вторую часть пространства survivor, называемую S1.
\item Третье поколение -- Любые объекты, попадающие в пространство выживших, помечаются счетчиком возраста. Алгоритм проверяет этот счётчик, чтобы увидеть, соответствует ли он пороговому значению для перехода в старое поколение. Главная мысль в том, что объекты не обязательно переходят из S0 в S1 пространства выживших. На самом деле, они просто чередуются с тем, куда они переключаются при каждой minor сборке мусора.
@ -436,7 +436,7 @@ public class Cat {
\begin{frm}\info Следует отметить, что, поскольку этот GC является параллельным, вызов явной сборки мусора, такой как использование System.gc() во время работы параллельного процесса, приведет к сбою или прерыванию параллельного режима;
\end{frm}
\item Сборщик мусора G1. Сборщик мусора G1 (Garbage First) предназначен для приложений, работающих на многопроцессорных компьютерах с большим объемом памяти. Он доступен с обновления 4 JDK7 и в более поздних версиях. Сборщик G1 заменит сборщик CMS, поскольку он более эффективен;
\item Z сборщик мусора. ZGC (Z Garbage Collector) - это масштабируемый сборщик мусора с низкой задержкой, который дебютировал в Java 11 в качестве экспериментального варианта для Linux. JDK 14 представил ZGC под операционными системами Windows и macOS. ZGC получил статус production начиная с Java 15.
\item Z сборщик мусора. ZGC (Z Garbage Collector) -- это масштабируемый сборщик мусора с низкой задержкой, который дебютировал в Java 11 в качестве экспериментального варианта для Linux. JDK 14 представил ZGC под операционными системами Windows и macOS. ZGC получил статус production начиная с Java 15.
\end{enumerate}
Итоги рассмотрения устройства памяти
@ -457,7 +457,7 @@ public class Cat {
\subsection{Конструкторы}
\subsubsection{Контроль над созданием объекта}
Чтобы создать объект мы тратим одну строку кода \code{Cat cat1 = new Cat();} поля этого объекта заполнятся автоматически значениями по-умолчанию (числовые - 0, логические - \code{false}, ссылочные - \code{null}). Часто нужно при создании дать коту какое-то имя, указать его возраст и цвет, поэтому пишем ещё три строки кода.
Чтобы создать объект мы тратим одну строку кода \code{Cat cat1 = new Cat();} поля этого объекта заполнятся автоматически значениями по-умолчанию (числовые -- 0, логические -- \code{false}, ссылочные -- \code{null}). Часто нужно при создании дать коту какое-то имя, указать его возраст и цвет, поэтому пишем ещё три строки кода.
\begin{frm} \excl В таком подходе есть несколько недостатков:
\begin{enumerate}
@ -468,7 +468,7 @@ public class Cat {
Было бы неплохо иметь возможность сразу, при создании объекта указывать значения его полей. Для инициализации объектов при создании в Java предназначены конструкторы.
\begin{frm} \info Конструктор - это частный случай метода в том смысле, что он тоже выполняет какие-то действия. Имя конструктора обязательно должно совпадать с именем класса, возвращаемое значение не пишется.
\begin{frm} \info Конструктор -- это частный случай метода в том смысле, что он тоже выполняет какие-то действия. Имя конструктора обязательно должно совпадать с именем класса, возвращаемое значение не пишется.
\end{frm}
Если создать конструктор класса Cat, как показано в листинге \hrf{lst:construct-bad}, он автоматически будет вызываться при создании объекта. Теперь, при создании объектов класса Cat, все коты будут иметь одинаковые имена, цвет и возраст (это будут белые двухлетние Барсики).
@ -552,7 +552,7 @@ public class Cat {
Ключевое слово \code{this} сошлётся на вызвавший объект, в результате чего (в листинге \hrf{lst:constr-this})имя котика через конструктор будет установлено создаваемому объекту. Таким образом, здесь \code{this} позволяет не вводить новые переменные для обозначения одного и того же, что позволяет сделать код менее перегруженным дополнительными переменными.
Второй случай частого использования \code{this} с конструкторами - вызов одного конструктора из другого. это может пригодиться когда в классе описано несколько конструкторов и не хочется в новом конструкторе переписывать код инициализации, приведенный в конструкторе ранее\footnote{один из базовых принципов программирования - DRY (от англ dry - чистый, сухой, акроним don't repeat yourself) - не повторяйся. Его антагонист WET (от англ wet - влажный, акроним write everything twice) - пиши всё дважды.}. В листинге \hrf{lst:constr-this} вызывается обычный конструктор с тремя параметрами, который принимает имя цвет и возраст, но, допустим, когда котята рождаются возраст им задавать смысла нет, поэтому, может пригодиться и конструктор просто с именем и цветом, а зачем писать присваивание имени и цвета несколько раз, если можно вызвать соответствующий конструктор?
Второй случай частого использования \code{this} с конструкторами -- вызов одного конструктора из другого. это может пригодиться когда в классе описано несколько конструкторов и не хочется в новом конструкторе переписывать код инициализации, приведенный в конструкторе ранее\footnote{один из базовых принципов программирования -- DRY (от англ dry -- чистый, сухой, акроним don't repeat yourself) -- не повторяйся. Его антагонист WET (от англ wet -- влажный, акроним write everything twice) -- пиши всё дважды.}. В листинге \hrf{lst:constr-this} вызывается обычный конструктор с тремя параметрами, который принимает имя цвет и возраст, но, допустим, когда котята рождаются возраст им задавать смысла нет, поэтому, может пригодиться и конструктор просто с именем и цветом, а зачем писать присваивание имени и цвета несколько раз, если можно вызвать соответствующий конструктор?
\begin{lstlisting}[language=Java,style=JCodeStyle,label={lst:constr-this},caption={Использование ключевого слова \code{this} для параметров}]
public class Cat {
@ -579,7 +579,7 @@ public class Cat {
\begin{frm} \info Ключевое слово \code{this} в Java используется только в составе экземпляра класса. Но неявно ключевое слово \code{this} передается во все методы, кроме статических (поэтому \code{this} часто называют неявным параметром) и может быть использовано для обращения к объекту, вызвавшему метод.
\end{frm}
Существует ещё один вид конструктора - это \textbf{конструктор копирования}. Чтобы создать конструктор копирования, возможно объявить конструктор, который принимает объект того же типа, в нашем случае котика, в качестве параметра, а в самом конструкторе аналогично конструктору, заполняющему все параметры, заполнить каждое поле входного объекта в новый экземпляр.
Существует ещё один вид конструктора -- это \textbf{конструктор копирования}. Чтобы создать конструктор копирования, возможно объявить конструктор, который принимает объект того же типа, в нашем случае котика, в качестве параметра, а в самом конструкторе аналогично конструктору, заполняющему все параметры, заполнить каждое поле входного объекта в новый экземпляр.
\begin{lstlisting}[language=Java,style=JCodeStyle]
public Cat (Cat cat) {
@ -604,10 +604,10 @@ public Cat (Cat cat) {
Инкапсуляция связывает данные с манипулирующим ими кодом и позволяет управлять доступом к членам класса из отдельных частей программы, предоставляя доступ только с помощью определенного ряда методов, что позволяет предотвратить злоупотребление этими данными. То есть класс должен представлять собой «черный ящик», которым возможно пользоваться, но его внутренний механизм защищен от повреждений.
\begin{frm}\info
\textbf{Инкапсуляция} - (англ. encapsulation, от лат. in capsula) в информатике, процесс разделения элементов абстракций, определяющих ее структуру (данные) и поведение (методы); инкапсуляция предназначена для изоляции контрактных обязательств абстракции (протокол/интерфейс) от их реализации.
\textbf{Инкапсуляция} -- (англ. encapsulation, от лат. in capsula) -- в информатике, процесс разделения элементов абстракций, определяющих ее структуру (данные) и поведение (методы); инкапсуляция предназначена для изоляции контрактных обязательств абстракции (протокол/интерфейс) от их реализации.
\end{frm}
В Java в роли чёрного ящика выступает класс. Класс содержит в себе и данные (поля класса), и действия (методы класса) для работы с этими данными. Все члены класса в языке Java - поля и методы - имеют модификаторы доступа. Ранее уже было описан модификатор \code{public}, означающий доступность отовсюду, обычно используется для методов.
В Java в роли чёрного ящика выступает класс. Класс содержит в себе и данные (поля класса), и действия (методы класса) для работы с этими данными. Все члены класса в языке Java -- поля и методы -- имеют модификаторы доступа. Ранее уже было описан модификатор \code{public}, означающий доступность отовсюду, обычно используется для методов.
\begin{frm} \info Модификаторы доступа позволяют задать допустимую область видимости для членов класса, то есть контекст, в котором можно употреблять данную переменную или метод.
\end{frm}
@ -662,12 +662,12 @@ public class Cat {
Важно, что создавая для класса геттеры и сеттеры не только появляется возможность дополнять установке и возвращению значений полей дополнительную логику, но и возможность регулировать доступ к полям. Например, если в программе нужно запретить менять котикам окрас, то для класса просто не пишется соответствующий сеттер.
Внимательно осмотрев класс кота возможно прийти к выводу, что хранить возраст котов очень неудобно, потому что каждый год нужно будет обновлять это значение для каждого объекта кота в программе, а это может оказаться утомительно. Выходом может оказаться хранение не возраста, а неизменяемого параметра - даты рождения и подсчёт возраста каждый раз, когда его запрашивают, ведь человеку, который запрашивает возраст кота, не интересно, каким образом получено значение, прочитано из поля или вычислено, ему важен конечный результат. Это и есть инкапсуляция, сокрытие реализации.
Внимательно осмотрев класс кота возможно прийти к выводу, что хранить возраст котов очень неудобно, потому что каждый год нужно будет обновлять это значение для каждого объекта кота в программе, а это может оказаться утомительно. Выходом может оказаться хранение не возраста, а неизменяемого параметра -- даты рождения и подсчёт возраста каждый раз, когда его запрашивают, ведь человеку, который запрашивает возраст кота, не интересно, каким образом получено значение, прочитано из поля или вычислено, ему важен конечный результат. Это и есть инкапсуляция, сокрытие реализации.
\subsubsection{Задания для самопроверки}
\begin{enumerate}
\item Перечислите модификаторы доступа
\item Инкапсуляция - это
\item Инкапсуляция -- это
\begin{enumerate}
\item архивирование проекта
\item сокрытие информации о классе
@ -677,7 +677,7 @@ public class Cat {
\subsection{Наследование}
\subsubsection{Проблема}
Второй кит ООП после инкапсуляции - наследование.
Второй кит ООП после инкапсуляции -- наследование.
Представим, что есть необходимость создать помимо класса котиков, класс собачек. Данный класс будет выглядеть очень похожим образом, только он будет не мяукать, а гавкать, и заменим обоим животным прыжок на простое перемещение на лапках.
@ -780,7 +780,7 @@ public class Dog {
\begin{frm} \info Наследование (англ. inheritance) — концепция объектно-ориентированного программирования, согласно которой абстрактный тип данных может наследовать данные и функциональность некоторого существующего типа, способствуя повторному использованию компонентов программного обеспечения.
\end{frm}
Наследование в Java реализуется ключевым словом \code{extends} (англ. - расширять). И кот и пёс являются животными, у всех описываемых в программе животных есть имя, возраст, окрас, все описываемые животные могут бегать, прыгать, и откликаться на имя. Создав так называемый \textbf{родительский класс}, или суперкласс (листинг \hrf{lst:animal-fields}), и поместив в него поля, геттеры и сеттеры, стало возможным убрать поля, геттеры и сеттеры из кота и пса. Если полей много, лаконичность описания родственных классов может быть весьма ощутимой.
Наследование в Java реализуется ключевым словом \code{extends} (англ. -- расширять). И кот и пёс являются животными, у всех описываемых в программе животных есть имя, возраст, окрас, все описываемые животные могут бегать, прыгать, и откликаться на имя. Создав так называемый \textbf{родительский класс}, или суперкласс (листинг \hrf{lst:animal-fields}), и поместив в него поля, геттеры и сеттеры, стало возможным убрать поля, геттеры и сеттеры из кота и пса. Если полей много, лаконичность описания родственных классов может быть весьма ощутимой.
\begin{lstlisting}[language=Java,style=JCodeStyle,label={lst:animal-fields},caption={Класс животного}]
public class Animal {
@ -859,9 +859,9 @@ public class Cat extends Animal {
То есть, к членам данных и методам класса можно применять следующие модификаторы доступа
\begin{itemize}
\item \code{private} - содержимое класса доступно только из методов данного класса;
\item \code{public} - есть доступ фактически отовсюду;
\item default (по-умолчанию) - содержимое класса доступно из любого места пакета, в котором этот класс находится;
\item \code{private} -- содержимое класса доступно только из методов данного класса;
\item \code{public} -- есть доступ фактически отовсюду;
\item default (по-умолчанию) -- содержимое класса доступно из любого места пакета, в котором этот класс находится;
\item \code{protected} (защищенный доступ) содержимое доступно также как с модификатором по-умолчанию, но ещё и для классов-наследников.
\end{itemize}
@ -875,12 +875,12 @@ public class Cat extends Animal {
То есть верным вариантом в листинге \hrf{lst:animal-fields} будет применение модификатора \code{protected}.
\subsubsection{Конструкторы в наследовании}
\begin{frm} \excl Несмотря на то, что конструктор - это частный случай метода, если перенести одинаковые конструкторы кота и пса в общий класс животного, программа снова перестанет работать, потому что важно учитывать механику вызова конструкторов при наследовании.
\begin{frm} \excl Несмотря на то, что конструктор -- это частный случай метода, если перенести одинаковые конструкторы кота и пса в общий класс животного, программа снова перестанет работать, потому что важно учитывать механику вызова конструкторов при наследовании.
\end{frm}
Важно запомнить, что при создании любого объекта в первую очередь вызывается конструктор его базового (родительского) класса, а только потом — конструктор самого класса, объект которого мы создаем. То есть при создании объекта \code{Cat} сначала отработает конструктор класса \code{Animal}, а только потом конструктор \code{Cat}. Но, поскольку конструктор по-умолчанию в нашем случае перестал создаваться, а других может быть бесконечно много, это создало неопределённость, которую программа разрешить не может.
При описании класса, можно явно вызвать конструктор базового класса в конструкторе класса-потомка. Базовый класс еще называют «суперклассом», поэтому в Java для его обозначения используется ключевое слово \code{super}. Здесь такое же ограничение, как и при вызове конструкторов данного класса (через \code{this}) - вызов такого конструктора может быть только один и быть только первой строкой. Таким образом, код, для всех животных в программе будет выглядеть следующим образом:
При описании класса, можно явно вызвать конструктор базового класса в конструкторе класса-потомка. Базовый класс еще называют «суперклассом», поэтому в Java для его обозначения используется ключевое слово \code{super}. Здесь такое же ограничение, как и при вызове конструкторов данного класса (через \code{this}) -- вызов такого конструктора может быть только один и быть только первой строкой. Таким образом, код, для всех животных в программе будет выглядеть следующим образом:
\begin{multicols}{2}
\begin{lstlisting}[language=Java,style=JCodeStyle,label={lst:animal-full},caption={Класс животного}]
@ -975,7 +975,7 @@ public class Bird extends Animal {
\begin{frm} \excl Множественное наследование запрещено! Для каждого создаваемого подкласса можно указать только один суперкласс. В Java не поддерживается множественное наследование, то есть наследование одного класса от нескольких суперклассов. Зато возможно каскадное наследование, то есть класс-наследник вполне может быть чьим-то родителем.
\end{frm}
Если класс-родитель не указан, таковым считается класс \code{Object}. Таким образом можно сделать вывод о том, что любой класс в джава так или иначе - наследник \code{Object} и, соответственно, всех его свойств и методов. Объект подкласса представляет объект суперкласса, выражаясь проще, возможно ко всем котикам обращаться через общее название Животное, и ко всем объектам в программе возможно обратиться через класс \code{Object}. Поэтому в программе не будет ошибкой написать подобный код:
Если класс-родитель не указан, таковым считается класс \code{Object}. Таким образом можно сделать вывод о том, что любой класс в джава так или иначе -- наследник \code{Object} и, соответственно, всех его свойств и методов. Объект подкласса представляет объект суперкласса, выражаясь проще, возможно ко всем котикам обращаться через общее название Животное, и ко всем объектам в программе возможно обратиться через класс \code{Object}. Поэтому в программе не будет ошибкой написать подобный код:
\begin{lstlisting}[language=Java,style=JCodeStyle,label={lst:obj},caption={}]
Object animal = new Animal("Cat", "Black", 3);
Object cat = new Cat("Murka", "Black", 4);
@ -1022,7 +1022,7 @@ if (cat instanceof Dog) {
Абстрактный класс — это написанная максимально широкими мазками, приблизительная «заготовка» для группы будущих классов. Эту заготовку нельзя использовать в чистом виде — слишком «сырая». Но она описывает некое общее состояние и поведение, которым будут обладать будущие классы — наследники абстрактного класса.
Абстрактными могут быть не только классы, но и методы. \textbf{Абстрактный метод} - это метод без реализации. Все животные в примерах выше умеют издавать свой звук. Известно, на этапе проектирования животного, что все животные должны издавать звук, но невозможно сказать, какой именно. Поэтому, определяется, что у животного есть метод издать звук, но реализация этого метода в животном не пишется, слишком мало сведений. Поэтому, метод помечается как абстрактный.
Абстрактными могут быть не только классы, но и методы. \textbf{Абстрактный метод} -- это метод без реализации. Все животные в примерах выше умеют издавать свой звук. Известно, на этапе проектирования животного, что все животные должны издавать звук, но невозможно сказать, какой именно. Поэтому, определяется, что у животного есть метод издать звук, но реализация этого метода в животном не пишется, слишком мало сведений. Поэтому, метод помечается как абстрактный.
Что будет, если программа попытается вызвать метод \code{voice()} у животного?
@ -1030,8 +1030,8 @@ if (cat instanceof Dog) {
\begin{frm} \info
\begin{itemize}
\item Абстрактный метод - это метод не содержащий реализации (объявление метода).
\item Абстрактный класс - класс содержащий хотя бы один абстрактный метод.
\item Абстрактный метод -- это метод не содержащий реализации (объявление метода).
\item Абстрактный класс -- класс содержащий хотя бы один абстрактный метод.
\item Абстрактный класс нельзя инстанциировать (создать экземпляр).
\end{itemize}
\end{frm}
@ -1046,7 +1046,7 @@ if (cat instanceof Dog) {
\item extends
\item как в С++, используется двоеточие
\end{enumerate}
\item super - это
\item super -- это
\begin{enumerate}
\item ссылка на улучшенный класс
\item ссылка на расширенный класс
@ -1134,9 +1134,9 @@ public class Cat extends Animal {
\begin{frm} \info Полиморфизм в языках программирования и теории типов — способность функции обрабатывать данные разных типов. Выделяют параметрический полиморфизм и ad-hoc-полиморфизм.
\end{frm}
Широко распространено определение полиморфизма, приписываемое Бьёрну Страуструпу: «один интерфейс — много реализаций». Полиморфизм - это гораздо более широкое понятие, чем просто переопределение методов, в эту тему завязаны разные интересные теории типов и информации, множество парадигм программирования и другое. С утилитарной точки зрения, остался ещё один вариант, который, тем не менее, не дотягивает до истинного полиморфизма.
Широко распространено определение полиморфизма, приписываемое Бьёрну Страуструпу: «один интерфейс — много реализаций». Полиморфизм -- это гораздо более широкое понятие, чем просто переопределение методов, в эту тему завязаны разные интересные теории типов и информации, множество парадигм программирования и другое. С утилитарной точки зрения, остался ещё один вариант, который, тем не менее, не дотягивает до истинного полиморфизма.
\begin{frm} \info К полиморфизму также относится перегрузка методов (Overloading) - использование более одного метода с одним и тем же именем, но с разными параметрами в одном и том же классе или между суперклассом и подклассами. \end{frm}
\begin{frm} \info К полиморфизму также относится перегрузка методов (Overloading) -- использование более одного метода с одним и тем же именем, но с разными параметрами в одном и том же классе или между суперклассом и подклассами. \end{frm}
Перегрузка работает также, как работала без явной привязки кода к парадигме ООП, ничего нового, но для порядка следует создать возможность животным перемещаться не только абстрактно, но и на какое-то конкретное место или на какое-то конкретное количество шагов.

179
jtc4-04a.tex Normal file
View File

@ -0,0 +1,179 @@
\documentclass[j-spec.tex]{subfiles}
\begin{document}
\setcounter{section}{2}
\setlength{\columnsep}{22pt}
\pagestyle{plain}
\sloppy
\tableofcontents
\section{Специализация: ООП и исключения}
\subsection{В предыдущем разделе}
Была рассмотрена реализация объектно-ориентированного программирования в Java. Рассмотрели классы и объекты, а также наследование, полиморфизм и инкапсуляцию. Дополнительно был освещён вопрос устройства памяти.
\subsection{В этом разделе}
В дополнение к предыдущему, будут разобраны такие понятия, как внутренние и вложенные классы; процессы создания, использования и расширения перечислений. Более детально будет разобрано понятие исключений и их тесная связь с многопоточностью в Java. Будут рассмотрены исключения с точки зрения ООП, процесс обработки исключений.
\begin{itemize}
\item \nom{Внутренний класс}{ };
\item \nom{Вложенный класс}{ };
\item \nom{Исключение}{ };
\item \nom{Многопоточность}{ };
\end{itemize}
\subsection{Перечисления}
Кроме восьми примитивных типов данных и классов в Java есть специальный тип, выведенный на уровень синтаксиса языка - \code{enum} или перечисление. Перечисления представляют набор логически связанных констант. Объявление перечисления происходит с помощью оператора \code{enum}, после которого идет название перечисления. Затем идет список элементов перечисления через запятую.
\begin{frm} \info Перечисление -- это упоминание объектов, объединённых по какому-либо признаку \end{frm}
Перечисления -- это специальные классы, содержащие внутри себя собственные статические экземпляры.
\begin{lstlisting}[language=Java,style=JCodeStyle,caption={Пример перечисления}]
enum Season { WINTER, SPRING, SUMMER, AUTUMN }.
\end{lstlisting}
Когда мы доберёмся до рассмотрения внутренних и вложенных классов, в том числе статических, дополнительно это проговорим.
Перечисление фактически представляет новый тип данных, поэтому мы можем определить переменную данного типа и использовать её. Переменная типа перечисления может хранить любой объект этого исключения.
Season current = Season.SPRING; System.out.println(current);
Интересно также то, что вывод в терминал и запись в коде у исключений полностью совпадают, поэтому, в терминале мы видим ....
Каждое перечисление имеет статический метод values(). Он возвращает массив всех констант перечисления, далее мы можем этим массивом манипулировать как нам нужно, например, вывести на экран все его элементы.
Season[] seasons = Season.values(); for (Season s : seasons) { System.out.printf("s ", s); }
Именно в этом примере, я использую цикл foreach для прохода по массиву, для лаконичности записи. Чуть подробнее о его особенностях мы поговорим на одной из следующих лекций. Если коротко, данный цикл возьмёт последовательно каждый элемент перечисления, присвоит ему имя s точно также, как мы это делали в примере на две строки выше, и сделает эту переменную С доступной в теле цикла в рамках одной итерации, на следующей итерации будет взят следующий элемент, и так далее
% +++ Комментатор_Ильнар. Строго говоря не очень корректная фраза "потому что у перечислений нет индексов". seasons - это уже обычный массив и можно его обойти обычным способом с индексами, скорее мы просто тут показали foreach цикл.
Также в перечисления встроен метод ordinal() возвращающий порядковый номер определенной константы (нумерация начинается с 0).
System.out.println(current.ordinal())
Обратите внимание на синтаксис, метод можно вызвать только у конкретного экземпляра перечисления, а при попытке вызова у самого класса перечисления
System.out.println(Seasons.ordinal())
мы ожидаемо получаем ошибку невозможности вызова нестатического метода из статического контекста.
как мы с вами помним из пояснения связи классов и объектов, такое поведение возможно только если номер элемента как-то хранится в самом объекте. Мы видим в перечислениях очень примечательный пример инкапсуляции - мы не знаем, хранятся ли на самом деле объекты перечисления в виде массива, но можем вызвать метод вельюс. Мы не знаем, хранится ли в каждом объекте перечисления его номер, но можем вызвать его метод ординал. А раз перечисление - это класс, мы можем определять в нём поля, методы, конструкторы и прочее.
Перечисление Color определяет приватное поле code для хранения кода цвета, а с помощью метода getCode оно возвращается.
enum Color {
RED("\#FF0000"), GREEN("\#00FF00"), BLUE("\#0000FF");
String code;
Color (String code) { this.code = code; }
String getCode() { return code; }
}
Через конструктор передается для него значение. Следует отметить, что конструктор по умолчанию приватный, то есть имеет модификатор private. Любой другой модификатор будет считаться ошибкой. Поэтому создать константы перечисления с помощью конструктора мы можем только внутри перечисления. И что косвенно намекает нам на то что объекты перечисления это статические объекты внутри самого класса перечисления. Также важно, что механизм описания конструкторов класса работает по той же логике, что и обычные конструкторы, то есть создав собственный конструктор мы уничтожили конструктор по-умолчанию, впрочем, мы его можем создать, если это будет иметь смысл для решаемой задачи.
Исходя из сказанного ранее можно сделать вывод, что с объектами перечисления можно работать точно также, как с обычными объектами, что мы и сделаем, например, выведя информацию о них в консоль
for (Color c : Color.values()) { System.out.printf("s(s) ", c, c.getCode()); }
\subsubsection{Задания для самопроверки}
\begin{enumerate}
\item Перечисления нужны, чтобы: 3
\begin{enumerate}
\item вести учёт созданных в программе объектов;
\item вести учёт классов в программе;
\item вести учёт схожих по смыслу явлений в программе;
\end{enumerate}
\item Перечисление - это: 2
\begin{enumerate}
\item массив
\item класс
\item объект
\end{enumerate}
\item каждый объект в перечислении - это: 3
\begin{enumerate}
\item статическое поле
\item статический метод
\item статический объект
\end{enumerate}
\end{enumerate}
\subsection*{Практическое задание}
\begin{enumerate}
\item Написать класс кота так, чтобы каждому объекту кота присваивался личный порядковый целочисленный номер.
\end{enumerate}
\newpage
\printnomenclature[40mm]
\end{document}
% enum Color{
% RED("#FF0000"), BLUE("#0000FF"), GREEN("#00FF00");
% private String code;
% Color(String code){
% this.code = code;
% }
% public String getCode(){ return code;}
% }
%public class Main{
% public static void main(String[] args) {
% System.out.println(Color.RED.getCode());
% System.out.println(Color.GREEN.getCode());
% }
%}
% package ru.gb.jcore;
% public class Orange {
% public void squeezeJuice(){
% System.out.println("Squeeze juice ...");
% }
% class Juice{
% public void flow(){
% System.out.println("Juice dripped ...");
% }
% }
% }
% package ru.gb.jcore;
% public class Main {
% public static void main(String[] args) {
% Orange orange = new Orange();
% Orange.Juice juice = orange.new Juice();
% orange.squeezeJuice();
% juice.flow();
% }
% }
%///////////////////////////////
% public class Orange {
% private Juice juice;
% public Orange(){
% this.juice = new Juice();
% }
% public void squeezeJuice(){
% System.out.println("Squeeze juice ...");
% juice.flow();
% }
% private class Juice{
% public void flow(){
% System.out.println("Juice dripped ...");
% }
% }
% }
% public class Main {
% public static void main(String[] args) {
% Orange orange = new Orange();
% orange.squeezeJuice();
% }
% }

View File

@ -1 +0,0 @@
Ovchinnikov_II@OVCHINNIKOV_II.21588:1669277770

View File

@ -1,5 +1,4 @@
\documentclass[../j-spec.tex]{subfiles}
\usepackage{spreadtab}
\begin{document}
\sloppy
@ -88,7 +87,7 @@
\item Библиотеки;
\item Фреймворки.
\end{enumerate}
\item Основная единица исходного кода программы - это? (2)
\item Основная единица исходного кода программы -- это? (2)
\begin{enumerate}
\item Функция;
\item Класс;
@ -336,8 +335,13 @@ javadoc -d doc_bg -sourcepath . -cp ./out ru.bg
\end{itemize}
\item \textbf{Задания}
\begin{enumerate}
\item Решить все задания (в том числе «со звёздочкой»), если они не были решены на семинаре, без ограничений по времени;
\item Создать докер образ для формирования полной документации по проекту/
\item [5-25 мин] Решить все задания (в том числе «со звёздочкой»), если они не были решены на семинаре, без ограничений по времени;
Все варианты решения приведены в тексте семинара выше
\item [10-15 мин] Создать докер образ для формирования полной документации по проекту
\lstinputlisting[style=CCodeStyle,caption={docker-compose-class.yml}]{src/s01-h04-docker-compose-docs.yml}
\end{enumerate}
\end{itemize}

View File

@ -0,0 +1,8 @@
services:
app:
image: bellsoft/liberica-openjdk-alpine:11.0.16.1-1
command: javadoc -sourcepath /app/src -cp /app/out -d /app/doc -subpackages ru
volumes:
- ./bin:/app/out
- ./src:/app/src
- ./doc:/app/doc

View File

@ -19,6 +19,7 @@
\usepackage{booktabs}% http://ctan.org/pkg/booktabs
\usepackage{setspace,fontspec}
\usepackage{amsmath}
\usepackage{spreadtab}
\usepackage{svg}
\newcommand{\tabitem}{~~\llap{\textbullet}~~}
@ -60,7 +61,7 @@
\lhead{\includegraphics[height=5mm]{logo.png}}
% \rhead{И.И. Овчинников \\ \href{https://t.me/ivanigorevichfeed}{Telegram: ivanigorevichfeed}}
\chead{\thepage}
% \cfoot{\faRocket}
\cfoot{\faRocket}
% \rfoot{Всего слов: \wordcount}
}

View File

@ -1,4 +1,4 @@
%% Creator: Inkscape 1.2.1 (9c6d41e4, 2022-07-14), www.inkscape.org
%% Creator: Inkscape inkscape 0.92.4, www.inkscape.org
%% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010
%% Accompanies image file 'jc-02-float-struct32_svg-tex.pdf' (pdf, eps, ps)
%%

View File

@ -1,4 +1,4 @@
%% Creator: Inkscape 1.2.1 (9c6d41e4, 2022-07-14), www.inkscape.org
%% Creator: Inkscape inkscape 0.92.4, www.inkscape.org
%% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010
%% Accompanies image file 'jc-02-float-struct_svg-tex.pdf' (pdf, eps, ps)
%%

View File

@ -1,4 +1,4 @@
%% Creator: Inkscape 1.2.1 (9c6d41e4, 2022-07-14), www.inkscape.org
%% Creator: Inkscape inkscape 0.92.4, www.inkscape.org
%% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010
%% Accompanies image file 'jc-03-class-obj-fields_svg-tex.pdf' (pdf, eps, ps)
%%

View File

@ -1,4 +1,4 @@
%% Creator: Inkscape 1.2.1 (9c6d41e4, 2022-07-14), www.inkscape.org
%% Creator: Inkscape inkscape 0.92.4, www.inkscape.org
%% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010
%% Accompanies image file 'jc-03-class-obj-full_svg-tex.pdf' (pdf, eps, ps)
%%

View File

@ -1,4 +1,4 @@
%% Creator: Inkscape 1.2.1 (9c6d41e4, 2022-07-14), www.inkscape.org
%% Creator: Inkscape inkscape 0.92.4, www.inkscape.org
%% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010
%% Accompanies image file 'jc-03-class-obj-nostatic_svg-tex.pdf' (pdf, eps, ps)
%%