Класс 1
Понятие класса o Класс является типом данных, определяемым пользователем это шаблон для создания объекта. Он должен представлять собой одну логическую сущность, например, являться моделью реального объекта или процесса. Элементами класса являются данные и функции, предназначенные для их обработки (методы). o Классы в Java не обязательно должны содержать метод main. Единственное назначение этого метода указать интерпретатору Java, откуда надо начинать выполнение программы. Для того, чтобы создать класс, достаточно иметь исходный файл, в котором будет присутствовать ключевое слово class, и вслед за ним допустимый идентификатор и пара фигурных скобок для его тела. class Point { } Имя исходного файла Java должно соответствовать имени хранящегося в нем класса. Регистр букв важен и в имени класса, и в имени файла. o 2
Класс Account
Объявление класса o Синтаксис объявление класса:
Спецификаторы класса определяют свойства класса, а также доступность класса для других элементов программы. 5
Спецификаторы класса Спецификатор Описание new (для вложенных классов). Задает новое описание класса взамен унаследованного от предка. Применяется в иерархиях public Доступ не ограничен protected Используется для вложенных классов. Доступ только из элементов данного пакета и производных классов отсутствует Доступ ограничен пакетом к элементам и классам private Доступ ограничен данным классом abstract Абстрактный класс. Применяется в иерархиях static Статический класс. 6
Атрибуты класса o Атрибуты (поля) задают дополнительную информацию о классе. Это объекты любого типа или переменные примитивных типов. o Если атрибут класса - это ссылка на объект, после объявления необходимо инициализировать эту ссылку, используя оператор new(). o Если атрибут класса - это примитивный тип, то можно его инициализировать простым присваиванием значения.
Объявление атрибутов. Пример Point Атрибуты класса объявляются вне методов, в том числе вне метода main o Синтаксис объявления атрибутов:
Атрибуты не делятся между объектами class Point { int х, у; public static void main(String args[]) { Point p 1 = new Point(); Инициализация Point p 2 = new Point(); конкретными значениями p 1. х = 10; членов-данных обоих экземпляров класса Point p 1. у = 20; p 2. х = 40; p 2. у = 33; System. out. println(“Первый объект: ” + "x =" + р1. х + " у = " + p 1. y); System. out. println(“Второй объект: ” + "x =" + р2. х + " у = " + p 2. y); }}
Сокрытие информации Проблема: My. Date +day : int +month : int +year : int o Клиентский код имеет прямой доступ к внутренним данным: d. day = 32; // неверная дата d. month = 2; d. day = 30; // правдоподобно, но //неправильно d. day = d. day + 1; // нет проверки, возможна ошибка
Сокрытие информации Решение: o Клиентский код должен использовать методы установки (setter) и получения (getter) доступа к внутренним данным: My. Date d = new My. Date(); d. set. Day(32); // если недействительный день, // возвращает false d. set. Month(2); d. set. Day(30); // правдоподобно, // set. Day возвращает false d. set. Day(d. get. Day() + 1); // false
Инкапсуляция o скрывает детали реализации класса o вынуждает пользователя использовать интерфейс для доступа к данным o делает код более легким в обслуживании
Доступ к атрибутам и методам объекта o dot нотация:
Методы o Метод — функциональный элемент класса, реализующий вычисления или другие действия. Методы определяют поведение класса и составляют его интерфейс. o Метод — законченный фрагмент кода, к которому можно обратиться по имени. Он описывается один раз, а вызываться может столько раз, сколько необходимо. o Один и тот же метод может обрабатывать различные данные, переданные ему в качестве аргументов. 14
Объявление методов o Синтаксис метода:
Объявление методов o Спецификатор доступа (public, private, protected или отсутствует) - указание на то, кто и как может использовать данный метод. o static (или его отсутствие) – определяет, каким образом данный метод будет использоваться: без объявления конкретного экземпляра класса (только для объявленного объекта). o Возвращаемый тип это тип значения, которое помещается в память из метода после его вызова. Тип результата может быть любым, в том числе и типом void в тех случаях, когда возвращать результат не требуется. o Список формальных параметров (аргуметов) это последовательность пар тип идентификатор, разделенных запятыми. Если у метода параметры отсутствуют, то после имени метода должны стоять пустые круглые скобки. Список аргументов дает типы и имена, чтобы было понятно, что необходимо передать в этот метод. Имя метода и список аргументов вместе уникально идентифицируют метод. o
Пример Point class Point { // !!!!! В jave все параметры примитивных типов //передаются по значению, т. е нельзя изменить формальный //параметр внутри метода (а или b)!!!! Заменяет инициализацию int х, у; полей экземпляров в void init(int a, int b) { предыдущем примере: х = а; p 1. х = 10; y = b; } p 1. у = 20; p 2. х = 40; p 2. у = 33; public static void main(String args[]) { Point p 1 = new Point(); Point p 2 = new Point(); p 1. init(10, 20); p 2. init(40, 33); System. out. println(“Первый объект: ” + "x = p 1. y); System. out. println(“Второй объект: ” + "x = p 2. y); }} " + р1. х + " у = " + р2. х + " у = " +
Методы в java Скрытие переменных экземпляров класса { int i = 12; /* операторы*/ { int i = 2; }} В языке Java не допускается использование в одной или во вложенных областях видимости двух локальных переменных с одинаковыми именами, Не запрещается объявлять формальные параметры методов, совпадающие с именами переменных представителей класса. Для доступа к одноименным переменным текущего объекта используется ссылка this. class Point { int х, у; Ссылка this интерпретируется как указание: полям void init(int х, int у) { х и y того объекта, который вызовет метод init(x, y), назначить значения, переданные через this. x = х; параметры метода. this. у = у; }} Для нового типа Two. Points. Init class Two. Points. Init { использована композиция объектов public static void main(String args[]) { из класса Point p 1 = new Point(); p 1. init(10, 20); }}
Классификация методов Java o o o o Методы main() и paint(). Вызываются для определения точки начала выполнения приложения. Конструкторы. Вызываются для создания новых экземпляров некоторого класса и инициализации их. Копировщики. Вызываются для копирования содержимого одного экземпляра объекта в другой. Set-методы. Вызываются для присвоения значения переменной класса. Get-методы. Вызываются для считывания значения переменной класса. Методы ввода/вывода. Вызываются для выполнения взаимодействия с внешним устройством. Методы специфические. Создаются для выполнения специфических функций приложения (класса) в соответствии с проектируемой задачей. 19
Ключевое слово static o Создание класса описывает, как выглядит объект класса и как он будет себя вести. Ничего не происходит, пока не будет создан объект (экземпляр) класса с помощью new. Только тогда создается хранилище данных и становятся доступны методы. o static для переменных класса определяет особую неизменяемую часть области данных, существующую независимо от того, сколько объектов создано (или даже ни одного объекта не было создано). o static для методов класса дает возможность иметь метод, который не ассоциируется с конкретным экземпляром класса и работает даже если объект не создан. o static говорит, что данные или метод не привязаны к определенному экземпляру объекта класса. 20
Ключевое слово static o Таким образом, можно вызвать Статический метод или получить доступ к статическим данным класса без объявления экземпляра класса прямо через указание имени класса: Имя_класса. имя_статического метода(…) или Имя_класса. имя_статической_переменной. Пример: Math. Pi o Статические методы не могут получить прямой доступ к нестатическим членам или методам простым вызовом этих методов без указания имени объекта (так как нестатические члены и методы должны быть привязаны к определенному объекту). 21
Пример использования static. Происходит автоматическая переменных инициализация переменных класса для каждого объявленного экземпляра: х = 0; - static-переменная class Point { static int х; инициализируется только первый int y; раз public static void main(String args[]) { y = 0; - каждый раз для обоих Point p 1 = new Point(); экземпляров p 1 и p 2 Point p 2 = new Point(); Point. x++; Так как static-переменная – общая для всех экземпляров, ее можно вызвать через прямое указание имени класса. При этом, p 1. x = 1; p 2. x = 1; // Point. y = 2; Недопустимо! y – динамическая переменная, доступ к ней возможен только через экземпляр класса (p 1 или p 2) p 1. x++; Эквивалентно Point. x++; х – статическая переменная, общая для всех экземпляров. При этом, p 1. x = 2; p 2. x = 2; p 2. y = Point. x + 3; Динамические поля (в нашем случае переменная y) класса разделяются между объектами. Отсюда: p 1. у = 0; p 2. y = 5; p 1. y = 20; }} После этого: p 1. у = 20; p 2. y = 5; Для переменной x по-прежнему: p 1. x = 2; p 2. x = 2; 22
Пример использования static методов class Point { int x, y; Допустимый, но не совсем «внятный» static void prt. Point(Point q) { System. out. println("x =" + q. x + " у = " + q. y); способ использования статического метода. В } обоих случаях public static void main(String args[]) { печатаются координаты Point p 1 = new Point(); первой точки x = 10; y = 20; Point p 2 = new Point(); p 1. x = 10; p 1. y = 20; p 2. x = 40; Более правильный способ p 2. y = 33; использования статического p 1. prt. Point(p 1); метода: печатаются p 2. prt. Point(p 1); координаты второй точки x = 40; y = 33; Point. prt. Point(p 2); 23 }}
Статические члены класса. Резюме o Когда static применяется к полям, это изменяет путь создания данных (одни данные для всего класса, против нестатического: один для каждого объекта) o static инициализация происходит только при необходимости. Если вы не создаете объект класса, в котором определены static члены, то они никогда не будут созданы. Однако они инициализируются, только когда создается первый объект такого класса (или при возникновении первого static доступа). После этого static объекты не инициализируются повторно. o Когда static применяется к методу класса это позволяет вызывать этот метод без создания объекта (экземпляра класса). o Этот эффект используется, в частности, в определении метода main( ), который является точкой входа для запуска приложения. o Как и любой метод, статический метод может создавать или использовать именованные объекты того же типа, так что статический метод часто используется как “пастух” для стада объектов одинакового типа.
Использование конструкторов Конструк тор – это специальный метод, предназначенный для создания и инициализации экзем пляра класса. Особенности применения конструкторов: o Имя конструктора совпадает с именем класса. o Класс может иметь несколько конструкторов. o Конструктор может иметь один или несколько параметров либо не иметь их вовсе. o Конструктор не возвращает никакого значения. o Конструктор всегда вызывается совместно с оператором new.
Использование конструкторов o Синтаксис объявления конструктора: [
Пример Point Конструктор class Point { int х, у; Замена метода init(…) на конструктор Point(int х, int у) { this. x = х; this. у = у; } } class Point. Create { Вызов конструктора при public static void main(String args[]) { создании экземпляра класса Point p = new Point(10, 20); System. out. println("x = " + p. x + " у = " + p. у); } } Когда объект создан: Point p = new Point(10, 20); место хранения зарезервировано (оператор new) и конструктор вызван (переменные класса получили конкретные значения). Это гарантирует то, что объект будет правильно инициализирован прежде, чем будет использован.
Конструктор по умолчанию Если явный конструктор не указан, Java автоматически предоста вит конструктор, используемый по умолчанию: o по умолчанию конструктор без аргументов o тело конструктора по умолчанию пустое По умолчанию можно создавать экземпляры объектов с помощью выражения new без необходимости указывать конструктор.
Конструктор по умолчанию class Bird { int i; } public class Default. Constructor { public static void main(String[] args) { Bird nc = new Bird(); // по умолчанию! }} Строка new Bird() создает новый объект и вызывает конструктор по умолчанию, даже несмотря на то, что он не был явно определен. Переменная класса i автоматически инициализируется нулем. Без этого не было бы способа построения нашего объекта. 29
Конструктор по умолчанию Если в описании класса определен любой конструктор (с аргументами или без них) компилятор не будет синтезировать ничего. class Bush { int i; Bush(int i) { } } Если при создании экземпляра класса сделать: new Bush(); // попытка вызова конструктора по умолчанию компилятор заявит, что он не может найти соответствующий конструктор. 30
Инициализация полей класса Инициализация переменных класса в конструкторе не препятствует их автоматической или явной инициализации, которая происходит в точке определения. class Counter { int i; // или, например, int i = 3; Counter() { i = 7; } //. . . i сначала будет инициализирована 0 ( или 3), а затем в конструкторе 7. Порядок инициализации Объявления переменных класса может быть разбросано между определением конструкторов и обычных методов. Однако инициализация переменных класса происходит прежде, чем может быть вызван любой метод (даже конструктор). 31
Перегрузка конструкторов и методов Ситуация, когда одно и то же слово несет несколько различных смыслов, называется перегрузкой. Java позволяет использовать одно имя для методов, которые можно объединить в рамках одной содержательной концепции. Например собрать под единым именем print() все методы, которые печатают числа всех примитивных числовых типов. Метод называется перегруженным если существует в данном классе метод с тем же именем, но разными сигнатурами. Сигнатурой метода называется совокупность его имени и набора формальных параметров. 32
class Point { int х, у; Point(int х, int у) { this. x = х; Перегрузка конструкторов this. у = у; } Point() { х = 0; у = 0; Объекты класса Point (p 1 и } p 2) создаются разными конструкторами. Решение о public static void main(String args[]) { том, какой конструктор нужно Point p 1 = new Point(); вызвать принимается в System. out. println("x 1 = " + p 1. x + " у1 = " + p 1. y); соответствии с количеством Point p 2 = new Point(10, 20); и типом параметров, указанных в операторе new. System. out. println("x 2 = " + p 2. x + " у2 = " + p 2. y); p 1. x +=p 2. x; p 1. y -=p 2. y; System. out. println("x 1 = " + p 1. x + " у1 = " + p 1. y); }} Вывод программы: х1 = 0 у1 = 0 Недопустимо объявлять в классе методы с одинаковыми x 2 = 10 y 2 = 20 сигнатурами (имя и список формальных параметров). В x 1 = 10 y 1 = -20 сигнатуре метода не учитываются имена формальных параметров, учитываются лишь их типы и количество. 33
Перегрузка конструкторов и методов Перегрузка по возвращаемому значению не допустима в Java Почему не делать различия между методами, основываясь на их возвращаемом значении? ” Например, методы имеют одинаковое имя и список аргументов, но легко отличаются друг от друга: void f() {…} int f() {…} Это работает, когда компилятор может недвусмысленно определить смысл из контекста, как в случае int x = f( ). 1. Различение методов при перегрузке по типу возвращаемого значения недопустимо. 2. Перегруженные методы могут иметь одинаковый или разные типы возвращаемых значений (это не проверяется компилятором). 34
import java. util. *; class Point { static int num. P; int x; int y; String name. P; /* Конструкторы и методы. Перегрузка. * файл Point. Dist. java * Использование возможностей static переменных */ Переменные класса: num. P – количество объявленных экземпляров класса Point; x и y – координаты точки, name. P – строковое имя объекта (точки на плоскости: «Точка 1» и т. п. ) Point() { Point. num. P = 0; name. P = "Начало координат"; } Point(int x, int y) { String s =""; this. x = x; this. y = y; Point. num. P++; name. P = "Точка" + s. value. Of(Point. num. P); } Конструктор по умолчанию. Инициализирует переменные значением 0 и объявляет особую точку «Начало координат» Перегруженный конструктор: инициализирует переменные класса заданными значениями s. value. Of(…) переводит числовой параметр в строковое выражение. 35
double distance(int x, int y) { int dx = this. x - x; int dy = this. y - y; return Math. sqrt(dx*dx + dy*dy); } double distance(Point p) { return distance(p. x, p. y); } Метод вычисляет расстояние по заданным координатам через переменные класса Перегруженный метод вычисляет расстояние по заданным координатам через экземпляр класса, используя вызов первого варианта метода void pr. Coord() { System. out. println("Координаты точки: "); System. out. println(this. name. P + " x = " + this. x + ", y = " + this. y); } Метод печатает имя и координаты точки на плоскости. void pr. Dist(Point p) { System. out. println ("Расстояние между : " + this. name. P + " и " + p. name. P + " ---> " + this. distance(p)); } }// Класс Point закрыт Метод вычисляет и печатает расстояние между объектом, к которому он применяется (this) и объектом, переданным в него в качестве параметра p. 36