Uploaded by danrus110

ООП в Java (Часть 1)

advertisement
Лекция 3.
ООП в Java (часть 1)
© 2013 NetCracker Technology Corporation Confidential
План лекции
• Основные понятия ООП
• Объявление классов
• Создание объектов
• Работа с пакетами
• Некоторые полезные классы
© 2013 NetCracker Technology Corporation Confidential
2
Основные понятия ООП
Принципы ООП
Другие важные понятия
• 0. Абстрагирование
• Классы
• 1. Инкапсуляция
• Объекты
• 2. Наследование
• Поля
• 3. Полиморфизм
• Методы
• Пакеты
• Область видимости
• Интерфейсы
© 2013 NetCracker Technology Corporation Confidential
3
Абстрагирование
• Абстрагирование — это способ выделить набор значимых характеристик
объекта, исключая из рассмотрения незначимые.
public class MyClock {
public int hours;
public int minutes;
public void nextMinute() {
minutes++;
if (minutes >=60) {
minutes=0;
hours++;
if (hours >=24) {
hours=0;
}
}
}
}
© 2013 NetCracker Technology Corporation Confidential
4
Инкапсуляция
• Инкапсуляция — объединение данных и методов работающих с ними;
обеспечение публичного интерфейса, скрытие реализации
‒ данные и вспомогательные методы «скрывают» с помощью сужения области видимости
‒ предоставляют публичный интерфейс
• Это позволяет:
‒ в будущем менять реализацию без изменения интерфейса
‒ обеспечить «защиту от дурака»
© 2013 NetCracker Technology Corporation Confidential
5
Инкапсуляция — пример
public class MyClock {
public int hours;
public int minutes;
public class MyClock {
private int hours;
private int minutes;
// ...
public int getHours() {
return hours;
}
}
public int getMinutes() {
return minutes;
}
// ...
}
© 2013 NetCracker Technology Corporation Confidential
6
Наследование
• Наследование — описание нового класса на основе уже существующего с
частично или полностью заимствующейся функциональностью
• В отличие от С++ в Java наследование единичное (но есть интерфейсы)
‒ у любого класса есть только один непосредственный предок
‒ граф наследования представляет собой дерево
‒ все объекты прямо или косвенно унаследованы от класса Object
• С помощью наследования реализуется отношение IS-A
(объект является чем-то). Не путать с HAS-A (объект содержит что-то)
‒ любой человек является приматом (человек extends примат)
‒ не всякий примат является человеком
‒ человек является животным, рыба является животным, человек не является рыбой
• Проверить является ли объект реализацией какого-либо класса или
интерфейса можно с помощью оператора instanceof
‒ иванов instanceof Человек == true
‒ иванов instanceof Примат == true
‒ иванов instanceof Рыба == false
© 2013 NetCracker Technology Corporation Confidential
7
Наследование — пример
public class MyPreciseClock extends MyClock {
private int seconds;
public int getSeconds() {
return seconds;
}
public void nextSecond() {
seconds++;
if (seconds>=60) {
seconds = 0;
nextMinute();
}
}
}
...
MyClock mc = new MyClock();
MyPreciseClock mpc = new MyPreciseClock();
System.out.println(mc instanceof MyClock);
System.out.println(mc instanceof MyPreciseClock);
System.out.println(mpc instanceof MyClock);
System.out.println(mpc instanceof MyPreciseClock);
© 2013 NetCracker Technology Corporation Confidential
Результат:
// true
true
// false
false
// true
true
// true
true
8
Полиморфизм
• Полиморфизм — использование объектов с одинаковыми интерфейсами
без информации о типе и внутренней структуре объектов
• Для этого нужно в наследниках переопределить (override) методы,
объявленные в базовом классе или интерфейсе
‒ в отличие от С++/С#, в Java все методы являются виртуальными, специально это указывать
не надо
• Выбор нужного метода выполняется автоматически во время выполнения
программы (runtime) на основании информации о типе объекта
‒ полиморфизм работает только для методов!
‒ никогда не пытайтесь переопределять поля!!
‒ выбор поля осуществляется на этапе компиляции
на основании типа ссылки на объект, а не типа самого объекта!!!
• Начиная с Java 1.5 рекомендуется переопределяемые методы помечать
аннотацией @Override
© 2013 NetCracker Technology Corporation Confidential
9
Полиморфизм — пример 1
public class MyClock {
// ...
public String toString() {
return "MyClock [" + hours + ":" + minutes + "]";
}
}
public class MyPreciseClock extends MyClock {
// ...
public String toString() {
return "MyPreciseClock [" + getHours() + ":" + getMinutes() + ":"
+ seconds + "]";
}
}
...
MyClock mc = new MyClock();
MyPreciseClock mpc = new MyPreciseClock();
MyClock mpc2 = new MyPreciseClock();
System.out.println(mc.toString());
System.out.println(mpc.toString());
System.out.println(mpc2.toString());
© 2013 NetCracker Technology Corporation Confidential
Результат:
MyClock
[0:0]
//
MyClock
[0:0]
MyPreciseClock
[0:0:0]
//
MyPreciseClock
[0:0:0]
MyPreciseClock
[0:0:0]
//
MyPreciseClock
[0:0:0]
10
Полиморфизм — пример 2
class A{
String name = "Class A";
String getName() {
return name;
}
}
class B extends A{
String name = "Class B"; // Никогда так не делайте (не переопределяйте поля)!
String getName() {
return name;
}
}
public class AB{
public static void main(String[] args) {
A a = new A();
B b = new B();
A ab= new B();
Результат:
System.out.println("a : " + a.name + " " + a.getName()); a : Class A Class A
System.out.println("b : " + b.name + " " + b.getName()); b : Class B Class B
System.out.println("ab: " + ab.name+ " " + ab.getName()); ab: Class A Class B
}
}
© 2013 NetCracker Technology Corporation Confidential
11
План лекции
• Основные понятия ООП
• Объявление классов
• Создание объектов
• Работа с пакетами
• Некоторые полезные классы
© 2013 NetCracker Technology Corporation Confidential
12
Объявление классов
• Объявление класса
[<модификаторы>] class <ИмяКласса>
[extends <ИмяБазовогоКласса>]
[implements <ИмяИнтерфейса1>[, <ИмяИнтерфейса2> [, ...]]] {
<объявление полей, конструкторов и методов класса>
}
• Объявление поля
[<модификаторы>] <тип> <имяПоля> [=<значение_по_умолчанию>];
• Объявление метода
[<модификаторы>] <тип_возвращаемых_данных> <имяМетода>
([список аргументов])
[throws <список классов исключительных ситуаций>]{
<блок программного кода>
}
© 2013 NetCracker Technology Corporation Confidential
13
Статические поля и методы
• Статические поля и методы принадлежат всему классу, а не конкретным
объектам, поэтому:
• С ними можно работать без необходимости создания объектов
‒ начинающие ленивые программисты очень любят static поля и методы, т.к. для работы с
ними не нужно создавать объекты. НЕ ДЕЛАЙТЕ ТАК!
‒ используйте static там, где это действительно необходимо (см. паттерны)
• Статические поля не привязаны к конкретным объектам, поэтому:
• из них можно обращаться только к другим static полям и методам
• из них нельзя обращаться к нестатическим полям и методам
• в них отсутствует this (см. ниже)
• Из вне обращаться к static полям и методам можно:
• через имя объекта (имя_объекта.статическое_поле)
• через имя класса (Имя_класса.статическое_поле)
‒ предпочтительнее через имя класса (выше читаемость кода)
• Для static методов не работает полиморфизм
‒ можно «переопределить», но выбор метода выполняется на этапе компиляции
© 2013 NetCracker Technology Corporation Confidential
14
Перегрузка методов (method overloading)
• Перегрузка методов (method overloading) – определение нескольких
методов с одинаковыми названиями, но разными аргументами
‒ не путать с override – переопределение в потомке метода, объявленного в базовом
классе
• Сигнатура метода – название метода + порядок и тип параметров
• Тип возвращаемого значения и декларация исключений не является частью
сигнатуры метода в языке Java
• Выбор нужного метода выполняется на этапе компиляции по сигнатуре
метода
• При перегрузке не должно быть 2х методов с одинаковой сигнатурой
‒ если у 2х методов совпадут сигнатуры в одном классе – ошибка компиляции
‒ если у метода в потомке совпадет сигнатура с методом в базовом классе,
то получится override, а не overload
© 2013 NetCracker Technology Corporation Confidential
15
Конструкторы (1)
• Конструктор – специальный «метод», который вызывается при создании
объекта для его инициализации
• Конструкторы можно перегружать (overload)
• Отличия конструкторов от методов:
•
•
•
•
•
имя конструктора совпадает с именем класса (с учетом регистра)
отсутствует возвращаемый тип. Совсем. Даже слово void не указывается
не может быть вызван после создания объекта
не может быть перегружен (overload) или переопределён (override) в потомке
не может быть abstract, final, static, ...
‒ допускаются только модификаторы области видимости (public, protected, private)
‒ если конструкторы не видны – невозможно создать экземпляр (пример – класс Math)
• Если конструкторы не объявлены, создается конструктор по умолчанию:
‒ область видимости – как у класса
‒ без параметров
‒ ничего не делает кроме вызова конструктора базового класса без параметров;
если в базовом классе такового нет – ошибка компиляции
© 2013 NetCracker Technology Corporation Confidential
16
Конструкторы (2)
• В первой строке конструктора можно:
• вызвать другой конструктор данного класса с помощью this(параметры)
• вызвать конструктор базового класса с помощью super(параметры)
• сделать что-нибудь другое, и тогда компилятор автоматически вставит первой
строкой вызов super() без параметров
‒ если в базовом классе такого конструктора нет, то ошибка компиляции
• Не рекомендуется вызывать из конструктора нестатические методы данного
класса
‒ если в наследнике их переопределить, то могут возникнуть проблемы
‒ статические методы переопределить нельзя, т.е. с ними проблем не будет
• Не рекомендуется из конструктора вызывать методы других классов,
передавая в них this
‒ объект до конца не проинициализирован, могут возникнуть проблемы
• Если конструктор бросит Exception, инициализация прекратится, и частично
проинициализированный объект станет доступен сборщику мусора
‒ об этом нужно помнить, если вдруг решите переопределить finalize() (см. ниже)
© 2013 NetCracker Technology Corporation Confidential
17
План лекции
• Основные понятия ООП
• Объявление классов
• Создание объектов
• Работа с пакетами
• Некоторые полезные классы
© 2013 NetCracker Technology Corporation Confidential
18
Создание объектов
• В Java объекты создаются и хранятся только в куче (heap)
‒ в Java не бывает объектов в стеке или в сегменте данных как с C++
‒ в Java объекты не передаются по значению как с C++
‒ в Java объекты не передаются по ссылке как с C++
‒ в Java объекты вообще никак не передаются (они остаются лежать в куче, где лежали)
‒ в Java передаются ссылки на объекты. Как и примитивы, они передаются по значению
• В результате создания объекта мы получаем ссылку на объект
‒ с помощью этой ссылки можно обратиться только к этому объекту
‒ отсутствуют адресная арифметика, произвольный доступ к памяти, преобразование
ссылки в примитив и наоборот
‒ копирование ссылки не приводит к созданию копии объекта
• Способы создания объектов:
‒ оператор new
‒ метод clone()
‒ serialization
‒ reflection
в следующих лекциях
© 2013 NetCracker Technology Corporation Confidential
19
Создание объектов – оператор new
1.
Если класс не был загружен в память он загружается
‒ инициализируются статические поля, выполняются блоки статической инициализации
2.
Выделяется место в памяти под объект
3.
Инициализируются нестатические поля и выполняются нестатические
блоки инициализации
• Поля инициализируются значениями, указанными в описании класса
• Если они не были указаны, то поля инициализируются значениями по-умолчанию:
‒ числовые поля = 0, логические поля = false, ссылки = null
4.
Вызывается конструктор (см. ниже), использованный в операторе new
‒ если в данном классе в явном виде конструктор не описан, используется
конструктор по-умолчанию (см. ниже)
• перед выполнением конструктора происходит вызов конструкторов всех
суперклассов по цепочке
‒ если явном конструктор не вызывается, неявно вызывается конструктор по-умолчанию
5.
Когда конструктор завершился, new возвращает ссылку на новый объект
© 2013 NetCracker Technology Corporation Confidential
20
this
• this ссылается на текущий объект
• Нельзя использовать в статических методах
• Можно использовать в нестатических методах и конструкторах для:
• получения ссылки на данный объект:
‒ this
• доступа к полю, имя которого перекрыто областью видимости параметра или
локальной переменной:
‒ this.имяполя
• вызова перегруженного конструктора данного класса:
‒ this(параметры)
© 2013 NetCracker Technology Corporation Confidential
21
this – пример
public class Student {
String name;
public Student(String name) {
this.name = name;
}
public Student() {
this("No Name");
конструктора
}
// область видимости
// вызов перегруженного
public void addToGroup(Group group) {
group.addStudent(this);
// передача ссылки на себя
}
}
© 2013 NetCracker Technology Corporation Confidential
22
super
• super используется для вызова конструкторов и методов базового класса
• Вызов переопределенного метода базового класса
super.имяМетода(параметры)
• Вызов конструктора базового класса
super(параметры)
‒ вызов конструктора базового класса может быть только в первой строке конструктора
‒ если перед вызовом конструктора суперкласса все-таки требуется выполнить какой-то
код, его можно включить в статический метод и сделать так:
super(myStaticMethod(параметры));
или
this(myStaticMethod(параметры));
© 2013 NetCracker Technology Corporation Confidential
23
super – пример
class Employee {
String name;
public Employee(String name) {
this.name = name;
}
public String toString() {
return "Name:" + name;
}
}
class Manager extends Employee {
String department;
public Manager(String name, String departament) {
super(name);
// вызов конструктора базового класса
this.department = departament;
}
public String toString() {
return super.toString() + " is manager of " +
department;
// вызов переопределенного метода базового класса
}
}
© 2013 NetCracker Technology Corporation Confidential
24
План лекции
• Основные понятия ООП
• Объявление классов
• Создание объектов
• Работа с пакетами
• Некоторые полезные классы
© 2013 NetCracker Technology Corporation Confidential
25
Пакеты
• Пакеты предназначены для организации иерархического пространства имен
классов. Цель – избежать конфликта имен классов
• Пакеты могут включать в себя классы и другие пакеты
• На уровне файловой системы: пакет = каталог, класс = файл
• Чтобы избежать конфликта имен пакетов в качестве пакета верхнего уровня
используют доменное имя своей компании в обратном порядке:
‒ com.netcracker, ru.edunc, ua.kpi.nc, ...
• имяпакета принято записывать маленькими буквами никак не выделяя
регистр или составляющие его слова:
‒ mypackage.mycompany.example.com
• java-файл должен начинаться с:
package packagename;
• Если в явном виде пакеты не используются, то классы размещаются в пакете
«по-умолчанию». Не делайте так. ОСОБЕННО в JavaEE-приложениях
© 2013 NetCracker Technology Corporation Confidential
26
Импортирование классов
• Полное имя класса (fully qualified class name) –
имяпакета.ИмяКласса
• Чтобы использовать короткое имя класса, его нужно импортировать:
package mypackage;
import java.util.Date;
public class MyClass {
Date date = new Date(); // Просто Date вместо java.util.Date
}
• import пишется после package, но перед class
• Если нужно несколько классов из одного пакета, можно использовать «*»
import java.util.*;
• включаются все классы из указанного пакета
‒ классы из пакетов в указанном пакете не включаются
• это никак не влияет ни на размер class-файла, ни на быстродействие
• import работает на этапе компиляции
• если заглянуть в середину class-файла, там записаны полные имена классов
• Автоматически импортируются все классы из пакета java.lang.*
© 2013 NetCracker Technology Corporation Confidential
27
Статический импорт
• Импортируются не сами классы, а их статические методы
• Java 1.5 и выше
public class Test {
public static void main(String[] args) {
double x = 0.5;
double y = Math.sin(x)*Math.sin(x) + Math.cos(x)*Math.cos(x);
System.out.println(y);
}
}
import static java.lang.Math.*;
public class Test {
public static void main(String[] args) {
double x = 0.5;
double y = sin(x)*sin(x) + cos(x)*cos(x);
System.out.println(y);
}
}
© 2013 NetCracker Technology Corporation Confidential
28
План лекции
• Основные понятия ООП
• Объявление классов
• Создание объектов
• Работа с пакетами
• Некоторые полезные классы
© 2013 NetCracker Technology Corporation Confidential
29
Класс Object
• Класс Object – корень дерева иерархии наследования всех классов
Доступ
public
Тип
boolean
Имя
equals(Object obj)
public
int
hashCode()
public
String
toString()
protected
Object
clone()
protected
void
finalize()
public
Class<?>
getClass()
public
void
notify()
public
void
notifyAll()
public
void
wait()
public
void
wait(long timeout)
public
void
wait(long timeout, int nanos)
© 2013 NetCracker Technology Corporation Confidential
30
Класс Class
• Объекты класса Class содержат информацию о классах, загруженных в
виртуальную машину. Обеспечивают информацию о классах во время
выполнения программы (Reflection)
• Некоторые методы:
•
•
•
•
•
•
getName()
getSuperclass()
forName(String className)
newInstance()
getFields()
getMethods()
© 2013 NetCracker Technology Corporation Confidential
31
Классы-обертки
• Представляют значение примитивного типа в виде объекта
•
•
•
•
•
•
•
•
Integer
Byte
Character
Short
Long
Double
Float
Boolean
• Дополнительные полезные функции
• преобразование в/из строк
• хранение констант (MIN_VALUE, MAX_VALUE, NaN, POSITIVE_INFINITY, ...)
• другие функции (в зависимости от типа)
• Объекты являются неизменяемыми (immutable)
© 2013 NetCracker Technology Corporation Confidential
32
Класс String
• Представляет собой строку
• Объекты String – immutable! После того как объект создан, его состояние
невозможно изменить
• Класс String является final. Невозможно создать его наследников
• Некоторые полезные методы – их очень много (см. JavaDoc)
• Важно помнить: ни один из этих методов не изменяет данный объект (immutable)
• «Изменяющие» методы создают новые объекты и возвращают ссылки на них.
• String умеет работать с юникодом, локалями, регулярными выражениями
• Для объектов String работает оператор «+» (конкатенация)
• Если нужно очень интенсивно выполнять операции над строками, лучше
использовать StringBuffer или StringBuilder
© 2013 NetCracker Technology Corporation Confidential
33
Классы StringBuffer и StringBuilder
• StringBuffer и StringBuilder представляют собой mutable строку, с которой
очень эффективно выполняются операции добавления, вставки и удаления
символов
‒ не создаются новые объекты как при использовании String
• StringBuffer
• начиная с Java 1.0
• синхронизирован (thread-safe)
• работает чуть медленнее чем StringBuilder
• StringBuilder
• начиная с Java 1.5
• не синхронизирован (non thread-safe)
• работает чуть быстрее чем StringBuffer
© 2013 NetCracker Technology Corporation Confidential
34
Классы System и Runtime
• System – очень полезный класс. Много полезных статических полей и
методов
•
•
•
•
•
•
•
•
Поля in, out, err
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
static Console console()
static long currentTimeMillis()
static long nanoTime()
static void exit(int status)
static String lineSeparator()
методы для работы со свойствами (properties) и переменными окружения
(environment variables)
• Runtime – тоже полезный класс. Много методов как у класса System, но эти
методы – нестатические
• для работы с ними вначале нужно получить ссылку на объект с помощью вызова
Runtime. getRuntime()
© 2013 NetCracker Technology Corporation Confidential
35
Работа с датами/временем
• Класс Date (java.util.Date)
• Частично устаревший класс (содержит много Deprecated методов)
• Корректно работает со временем в формате «количеством миллисекунд,
прошедших с January 1, 1970, 00:00:00 GMT»
• Для других целей лучше пользоваться классом Calendar
• Класс Calendar
• Учитывает «хитрые» особенности работы с датой/временем
• Много дополнительных функций по сравнению с Date
• Совместим с Date
‒ методы getTime(), setTime()
• Умеет работать с локалями
• Является абстрактным классом (невозможно создать его экземпляр)
• Чтобы работать с Calendar нужно вызвать статический метод
Calendar. getInstance(). Он вернет ссылку на объект класса унаследованного от
Calendar (у нас – GregorianCalendar)
© 2013 NetCracker Technology Corporation Confidential
36
Другие полезные классы
• Math содержит много статических методов для вычисления математических
функций
‒ sin, cos, log, exp, pow, random, ....
• Random генератор псевдослучайных величин
‒ более богатые функции, чем у Math.random
• Arrays содержит много статических методов для работы с массивами
‒ копирование, поиск, сортировка, заполнение
• Pattern, Matcher – работа с регулярными выражениями
‒ см. http://docs.oracle.com/javase/tutorial/essential/regex/index.html
• Locale – работа с настройками локализации (язык, национальные настройки)
© 2013 NetCracker Technology Corporation Confidential
37
Thank you!
© 2013 NetCracker Technology Corporation Confidential
38
Download