Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

java / java-intro_part_2_ibm-developerworks

.pdf
Скачиваний:
55
Добавлен:
11.05.2015
Размер:
4.53 Mб
Скачать

02.09.13Введениев Java-программирование: Часть 2. Конструкцииреальныхприложений

IBM

Русский

Войти (или Регистрация)

Техническиематериалы ПробноеПО Сообщество

Введение в Java-программирование: Часть 2. Конструкции реальных приложений

Дополнительные возможности языка Java

Дж. Стивен Перри, главный консультант, Makoto Consulting Group, Inc.

Описание: В Части 1 этого руководства профессиональный Java™-программист Дж. Стивен Перри рассказал о синтаксисе языка Java и библиотеках, требуемых для написания простых Java-приложений. Часть 2 по-прежнему ориентирована на программистов, осваивающих разработку приложений Java, и вводит болеесложныеконструкции программирования, необходимыедля построения Java-приложений, рассчитанных на практическоеприменение. Еетематика охватывает обработку исключений, наследованиеи абстракции, регулярныевыражения, родовыетипы, операции ввода/вывода Java и Java-сериализацию.

Дата: 26.10.2011

Уровеньсложности: простой

Активность: 91195 просмотров

Средний показатель рейтинга (основанный на 55 голосов)

Преждечем начать

Чего ожидать от этого руководства и как получить от него максимальную отдачу.

Об этом циклестатей

Руководство из двух частей "Введениев Java-программирование" предназначено для программистов, незнакомых с Javaтехнологией, и учит объектно-ориентированному программированию (ООП) и разработкепрактических приложений с использованием языка и платформы Java.

Об этом руководстве

Эта вторая половина руководства "Введениев Java-программирование" знакомит читателя с болеесложными средствами языка Java, чем те, которыерассматривались в Части 1.

Цели обучения

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

обработка исключений;

наследованиеи абстракция;

интерфейсы;

вложенныеклассы;

регулярныевыражения;

родовыетипы;

перечислимыетипы;

операции ввода/вывода; сериализация.

Предварительныезамечания

Содержаниеэтого учебника ориентировано на программистов, осваивающих язык Java, которыенезнакомы с его тонкостями. Предполагается, что вы изучили Введениев Java-программирование. Часть 1: Основы языка Java и, следовательно:

www.ibm.com/developerworks/ru/edu/j-introtojava2/index.html

1/2

02.09.13Введениев Java-программирование: Часть 2. Конструкцииреальныхприложений

получили представлениеоб основах объектно-ориентированного программирования на платформеJava;

настроили среду разработки для выполнения примеров; начали проект программирования, который будет продолжаться во второй части.

Требования к системе

Для выполнения упражнений из этого руководства требуется среда разработки в составе:

JDK 6 от Sun/Oracle;

EclipseIDE for Java Developers.

Инструкции по загрузкеи установкетого и другого приведены в Части 1.

Рекомендуемая конфигурация системы:

система, поддерживающая Java SE 6, с минимальным объемом оперативной памяти 1 ГБ. Java 6 поддерживается на

Linux®, Windows® и Solaris®;

по крайней мере, 20 МБ свободного дискового пространства для установки программных компонентов и примеров.

1 из 14 | следующая

Печатьстраницы

Сделать этустраницуобщей

 

 

Помощь

 

Ленты

Конфиденциальность

Портал для студентов

Запрос на использование

Сообщить о нарушениях

Доступность (Английский)

Бизнес-партнеры IBM

материалов developerWorks

Условия использования

 

 

 

 

 

 

 

 

 

 

 

www.ibm.com/developerworks/ru/edu/j-introtojava2/index.html

2/2

02.09.13Введениев Java-программирование: Часть 2. Конструкцииреальныхприложений

IBM

Русский

Войти (или Регистрация)

Техническиематериалы ПробноеПО Сообщество

Введение в Java-программирование: Часть 2. Конструкции реальных приложений

Дополнительные возможности языка Java

Дж. Стивен Перри, главный консультант, Makoto Consulting Group, Inc.

Описание: В Части 1 этого руководства профессиональный Java™-программист Дж. Стивен Перри рассказал о синтаксисе языка Java и библиотеках, требуемых для написания простых Java-приложений. Часть 2 по-прежнему ориентирована на программистов, осваивающих разработку приложений Java, и вводит болеесложные конструкции программирования, необходимыедля построения Java-приложений, рассчитанных на практическоеприменение. Еетематика охватывает обработку исключений, наследованиеи абстракции, регулярныевыражения, родовыетипы, операции ввода/вывода Java и Java-сериализацию.

Дата: 26.10.2011

Уровень сложности: простой

Активность: 91195 просмотров

Средний показатель рейтинга (основанный на 55 голосов)

Дальнейшиедействия с объектами

В первой части этого руководства мы остановились на объектеPerson, достаточно полезном, но ненастолько, как хотелось бы. Теперь мы приступим к изучению методов совершенствования объекта Person, начиная со следующих:

перегрузка методов;

переопределениеметодов;

сравнениеодного объекта с другим; как сделать кодболееудобным для отладки.

Перегрузка методов

При создании двух методов с одинаковыми именами, но с разными списками аргументов (то есть разными по количеству или типу параметрами) получается перегруженный (overloaded) метод. Перегруженныеметоды всегда находятся в одном и том жеклассе. Во время выполнения программы среда исполнения Java (Java RuntimeEnvironment - JRE, или Java Runtime) решает, какой вариант перегруженного метода вызвать, в зависимости от переданных ему аргументов.

Предположим, что объекту Personтребуется несколько методов распечатки отчета о своем текущем состоянии. Назовем эти методы printAudit(). Вставьтетакой перегруженный метод, показанный в листинге1, в окно редактора Eclipse.

Листинг 1. printAudit(): перегруженныйметод

public void printAudit(StringBuilder buffer) { buffer.append("Name="); buffer.append(getName()); buffer.append(","); buffer.append("Age="); buffer.append(getAge());

buffer.append(","); buffer.append("Height="); buffer.append(getHeight()); buffer.append(","); buffer.append("Weight="); buffer.append(getWeight()); buffer.append(","); buffer.append("EyeColor="); buffer.append(getEyeColor()); buffer.append(","); buffer.append("Gender="); buffer.append(getGender());

}

public void printAudit(Logger l) { StringBuilder sb = new StringBuilder(); printAudit(sb);

l.info(sb.toString());

}

В этом случаепоявляются двеперегруженныеверсии printAudit(), и одна из них фактически использует другую. Предлагая двеверсии, вы предоставляетевызывающему методу возможность выбора способа распечатки отчета о классе. Java Runtime вызовет нужный методв зависимости от переданных параметров.

Два правила перегрузкиметодов

www.ibm.com/developerworks/ru/edu/j-introtojava2/section2.html

1/11

02.09.13Введениев Java-программирование: Часть 2. Конструкцииреальныхприложений

Запомнитедва важных правила работы с перегруженными методами:

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

При нарушении этих правил компилятор выдаст сообщениеоб ошибке.

Переопределениеметодов

Если подкласс другого класса создает свою собственную реализацию метода, определенного в родительском классе, это называется переопределением метода. Чтобы увидеть, насколько полезно переопределениеметода, давайтепроделаем какую-нибудь операцию с классом Employee. На нем мы покажем, для чего может понадобиться переопределениеметода.

Employee: подкласс класса Person

Как говорилось в Части 1 этого руководства, Employeeможет быть подклассом (или дочерним классом) класса Person, наделенным некоторыми дополнительными атрибутами:

кодналогоплательщика,

табельный номер;

дата приема на работу, заработная плата.

Чтобы объявить такой класс в файлес именем Employee.java, щелкнитеправой кнопкой мыши на пакете com.makotogroup.introв Eclipse. Выберите New >Class...; откроется диалоговоеокно создания нового класса Java, как показано на рисунке1.

Рисунок 1. Диалоговое окно New Java Class

ВведитеEmployeeв качествеимени класса и Personв качествесуперкласса, затем нажмитекнопку Finish. Вы увидитекласс Employeeв окнередактирования. Явно объявлять конструктор ненужно, просто двигайтесь дальше, и оба конструктора будут реализованы. Убедитесь, что фокус находится в окнередактирования класса Employee, и выберитеSource >Generate Constructors from Superclass...; вы увидитедиалоговоеокно, показанноена рисунке2.

Рисунок 2. Создание конструкторов в диалоговом окне Superclass

www.ibm.com/developerworks/ru/edu/j-introtojava2/section2.html

2/11

02.09.13Введениев Java-программирование: Часть 2. Конструкцииреальныхприложений

Отметьтеоба конструктора (как показано на рисунке2) и нажмитекнопку OK. Eclipse сгенерирует конструкторы. Теперь класс Employeeдолжен выглядеть, как в листинге2.

Листинг 2. Новый, усовершенствованныйкласс Employee

package com.makotogroup.intro;

public class Employee extends Person {

public Employee() { super();

// Заглушка автоматически сгенерированного конструктора TODO

}

public Employee(String name, int age, int height, int weight, String eyeColor, String gender) {

super(name, age, height, weight, eyeColor, gender);

// Заглушка автоматически сгенерированного конструктора TODO

}

}

Employeeнаследует свойства Person

Как видно в листинге3, Employeeнаследует атрибуты и поведениесвоего родителя Person, а такжеимеет некоторые собственныесвойства.

Листинг 3. Класс Employeeс атрибутамиPerson

package com.makotogroup.intro; import java.math.BigDecimal;

public class Employee extends Person {

private String taxpayerIdentificationNumber; private String employeeNumber;

private BigDecimal salary;

public Employee() { super();

}

public String getTaxpayerIdentificationNumber() { return taxpayerIdentificationNumber;

}

public void setTaxpayerIdentificationNumber(String taxpayerIdentificationNumber) { this.taxpayerIdentificationNumber = taxpayerIdentificationNumber;

}

// Другие геттеры/сеттеры...

}

www.ibm.com/developerworks/ru/edu/j-introtojava2/section2.html

3/11

02.09.13

Введениев Java-программирование: Часть 2. Конструкцииреальныхприложений

Переопределение метода: printAudit()

Теперь, как и было обещано, можно приступить к переопределению методов. Мы переопределим методprintAudit()(см. листинг 1), который использовался для форматирования текущего состояния экземпляра класса Person. Employeeнаследует поведениеPerson, и если создать экземпляр Employee, установить его атрибуты и вызвать один из перегруженных методов printAudit(), то вызов будет успешным. Однако полученный отчет небудет в полной мереотражать класс Employee.

Проблема в том, что он неможет форматировать атрибуты, специфичныедля Employee, так как Personничего незнает о них.

Решениезаключается в том, чтобы переопределить перегрузку printAudit(), которая в качествепараметра принимает StringBuilder, и добавить коддля печати атрибутов, специфичных для Employee.

Для этого в EclipseIDE выберитеSource >Override/Implement Methods..., и вы увидитедиалоговоеокно, как на рисунке3.

Рисунок 3. Диалоговое окно Override/Implement Methods

Выберитеперегрузку StringBuilderметода printAudit, как показано на рисунке3, и нажмитекнопку OK. Eclipseсгенерирует заглушку метода, и вы сможетепросто заполнить остальное, вот так:

@Override

public void printAudit(StringBuilder buffer) {

//Сначала вызывается суперкласс этого метода для получения значений его атрибутов super.printAudit(buffer);

//Теперь форматируются значения для этого экземпляра buffer.append("TaxpayerIdentificationNumber="); buffer.append(getTaxpayerIdentificationNumber()); buffer.append(","); buffer.append("EmployeeNumber="); buffer.append(getEmployeeNumber()); buffer.append(","); buffer.append("Salary=");

buffer.append(getSalary().setScale(2).toPlainString());

}

Обратитевниманиена вызов метода super.printAudit(). Мы просим суперкласс (Person) представить поведениесвоего метода printAudit(), а затем добавляем к нему поведениеметода printAudit()для Employee.

Вызов super.printAudit()необязательно должен быть первым, просто полезно распечатать сначала эти атрибуты. На самом деле, вообщененужно вызывать super.printAudit(). Если его невызывать, нужно либо отформатировать атрибуты из Personсамостоятельно (в методеEmployee.printAudit (), либо исключить их совсем. Созданиевызова super.printAudit()в данном случаеещепроще.

Члены класса

Переменныеи методы, полученныедля Personи Employee, - это экземпляры переменных и методов. Чтобы ими воспользоваться, нужно либо создать необходимый экземпляр класса, либо иметь ссылку на такой экземпляр. Каждый экземпляр объекта имеет переменныеи методы, и для каждого из них точноеповедение(например, порожденноевызовом printAudit() будет отличаться, потому что оно основано на состоянии экземпляра объекта.

Сами классы тожемогут иметь переменныеи методы, которыеназываются членами класса. Члены класса декларируются с помощью ключевого слова static, о котором говорилось в Части 1 этого руководства. Различия между членами класса и

www.ibm.com/developerworks/ru/edu/j-introtojava2/section2.html

4/11

02.09.13Введениев Java-программирование: Часть 2. Конструкцииреальныхприложений

членами экземпляров:

каждый экземпляр класса разделяет общую копию переменной класса;

методы класса можно вызвать в самом классе, несоздавая экземпляр;

методы экземпляра могут обращаться к переменным класса, а методы класса немогут обращаться к переменным экземпляра; методы класса могут обращаться только к переменным класса.

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

Когда имеет смысл добавлять переменныеи методы класса? Золотоеправило: делать это редко, незлоупотребляя. Тем не менее, использовать переменныеи методы класса бывает полезно:

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

для отслеживания "счетчиков" экземпляров класса;

для класса с утилитарными методами, когда экземпляр класса непонадобится (например, Logger.getLogger().

Переменныекласса

Чтобы создать переменную класса, при ееобъявлении используется ключевоеслово static:

accessSpecifier static variableName [= initialValue];

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

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

Например, мы определили атрибут Genderкласса Personкак переменную типа String, но несделали для него никаких ограничений. В листинге4 показан общий подходк использованию переменных класса.

Листинг 4. Использование переменных класса

public class Person { //. . .

public static final String GENDER_MALE = "MALE"; public static final String GENDER_FEMALE = "FEMALE";

// . . .

public static void main(String[] args) {

Person p = new Person("Joe Q Author", 42, 173, 82, "Brown", GENDER_MALE); // . . .

}

//. . .

}

Объявление констант

Как правило, константы:

имеют имена, записанныепрописными буквами;

имеют имена из нескольких слов, разделенных знаками подчеркивания;

объявляются как final(то есть их значения немогут быть изменены);

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

В листинге4, чтобы использовать константу MALEпри вызовеконструктора Person, достаточно просто указать ееимя. Для использования константы внекласса нужно предварить ееименем класса, в котором она объявлена:

String genderValue = Person.GENDER_MALE;

www.ibm.com/developerworks/ru/edu/j-introtojava2/section2.html

5/11

02.09.13Введениев Java-программирование: Часть 2. Конструкцииреальныхприложений

Методы класса

Те, кто следит за примерами, начиная с Части 1, уженесколько раз вызывали статический методLogger.getLogger()- всякий раз при получении экземпляра Loggerдля вывода каких-нибудь записей на консоль. Однако для этого ненужен экземпляр Logger; вместо него можно ссылаться на сам класс Logger. Это синтаксис вызова метода класса. Как и в случаепеременных класса, ключевоеслово staticопределяет Logger(в данном примере) как методкласса. По этой причинеметоды класса иногда ещеназывают статическими методами.

Использование методов класса

Теперь используем все, что вы узнали о статических переменных и методах, для создания статического метода Employee. Объявим переменную private static finalдля хранения Logger, который будут совместно использовать всеэкземпляры и который будет доступен по вызову getLogger()по отношению к классу Employee. В листинге 5 показано, как это делается.

Листинг 5. Создание метода класса (илистатического метода)

public class Employee extends Person {

private static final Logger logger = Logger.getLogger(Employee.class.getName()); //. . .

public static Logger getLogger() { return logger;

}

}

В листинге5 происходят двеважныевещи:

объявляется экземпляр Loggerс доступом private, так что ни один класс внеEmployeeнеможет получить доступ напрямую;

Logger инициализируется при загрузкекласса; это происходит потому, что для придания ему значения используется синтаксис инициализации Java.

Чтобы получить объект Loggerкласса Employee, нужно выполнить следующий вызов:

Logger employeeLogger = Employee.getLogger();

Сравнениеобъектов

Язык Java предоставляет два способа сравнения объектов:

оператор ==;

методequals().

Сравнение объектов с помощью оператора ==

Оператор ==сравнивает объекты на равенство, так что выражениеa == bвозвращает значениеtrue, только если аи bимеют одно и то жезначение. Для объектов это означает, что оба ссылаются на один и тот жеэкземпляр объекта. Для примитивов это означает, что значения идентичны. Рассмотрим в качествепримера Листинг 6.

Листинг 6. Сравнение объектов с помощью оператора ==

int int1 = 1; int int2 = 1;

l.info("Q: int1 == int2? A: " + (int1 == int2));

Integer integer1 = Integer.valueOf(int1); Integer integer2 = Integer.valueOf(int2);

l.info("Q: Integer1 == Integer2? A: " + (integer1 == integer2));

integer1 = new Integer(int1); integer2 = new Integer(int2);

l.info("Q: Integer1 == Integer2? A: " + (integer1 == integer2));

Employee employee1 = new Employee();

Employee employee2 = new Employee();

www.ibm.com/developerworks/ru/edu/j-introtojava2/section2.html

6/11

02.09.13Введениев Java-программирование: Часть 2. Конструкцииреальныхприложений

l.info("Q: Employee1 == Employee2? A: " + (employee1 == employee2));

Если выполнить кодлистинга 6 внутри Eclipse, результат будет:

Apr 19, 2010 5:30:10 AM com.makotogroup.intro.Employee main

INFO: Q: int1 == int2? A: true

Apr 19, 2010 5:30:10 AM com.makotogroup.intro.Employee main

INFO: Q: Integer1 == Integer2? A: true

Apr 19, 2010 5:30:10 AM com.makotogroup.intro.Employee main

INFO: Q: Integer1 == Integer2? A: false

Apr 19, 2010 5:30:10 AM com.makotogroup.intro.Employee main

INFO: Q: Employee1 == Employee2? A: false

В первом случаев листинге6 значения примитивов одни и теже, так что оператор ==возвращает значениеtrue. Во втором случаеобъекты Integerссылаются на один и тот жеэкземпляр, так что ==опять возвращает значениеtrue. В третьем случае, хотя объекты Integerсодержат одно и то жезначение, ==возвращает результат false, потому что integer1и integer2 относятся к разным объектам. Отсюда должно быть ясно, почему employee1 == employee2 возвращает false.

Сравнение объектов с помощью equals()

equals()- это метод, который каждый объект языка Java получает "бесплатно", потому что он определяется как метод экземпляра java.lang.Object(от которого наследует каждый объект Java).

equals()вызывается точно так же, как любой другой метод:

a.equals(b);

Этот оператор вызывает методequals()объекта а, передавая ему ссылку на объект b. По умолчанию Java-программа просто проверяет, что два объекта одинаковы, с помощью синтаксиса ==. Однако так как equals()- это метод, его можно переопределить. Рассмотрим пример из листинга 6, измененный в листинге7 для сравнения двух объектов с помощью

метода equals().

Листинг 7. Сравнение объектов с помощью метода equals()

Logger l = Logger.getLogger(Employee.class.getName());

Integer integer1 = Integer.valueOf(1); Integer integer2 = Integer.valueOf(1);

l.info("Q: integer1 == integer2? A: " + (integer1 == integer2)); l.info("Q: integer1.equals(integer2)? A: " + integer1.equals(integer2));

integer1 = new Integer(integer1); integer2 = new Integer(integer2);

l.info("Q: integer1 == integer2? A: " + (integer1 == integer2)); l.info("Q: integer1.equals(integer2)? A: " + integer1.equals(integer2));

Employee employee1 = new Employee(); Employee employee2 = new Employee();

l.info("Q: employee1 == employee2? A: " + (employee1 == employee2)); l.info("Q: employee1.equals(employee2)? A: " + integer1.equals(integer2)); Running this code produces:

Apr 19, 2010 5:43:53 AM com.makotogroup.intro.Employee main

INFO: Q: integer1 == integer2? A: true

Apr 19, 2010 5:43:53 AM com.makotogroup.intro.Employee main

INFO: Q: integer1.equals(integer2)? A: true

Apr 19, 2010 5:43:53 AM com.makotogroup.intro.Employee main

INFO: Q: integer1 == integer2? A: false

Apr 19, 2010 5:43:53 AM com.makotogroup.intro.Employee main

INFO: Q: integer1.equals(integer2)? A: true

Apr 19, 2010 5:43:53 AM com.makotogroup.intro.Employee main

INFO: Q: employee1 == employee2? A: false

Apr 19, 2010 5:43:53 AM com.makotogroup.intro.Employee main

INFO: Q: employee1.equals(employee2)? A: false

Примечание о сравнениизначенийInteger

Нет ничего удивительного в том, что в листинге7 методequals()в применении к Integerвозвращает true, если == возвращает true; но заметьте, что происходит во втором случае, когда создаются отдельныеобъекты, содержащиеодно и то жезначение1: ==возвращает false, потому что integer1и integer2относятся к разным объектам; но equals()возвращает

www.ibm.com/developerworks/ru/edu/j-introtojava2/section2.html

7/11

02.09.13Введениев Java-программирование: Часть 2. Конструкцииреальныхприложений

true.

Создатели JDK решили, что для Integerзначениеequals()должно отличаться от стандартного (когда сравниваются ссылки на объект, чтобы определить, относятся ли они к одному и тому же объекту), возвращая значениеtrue, когда внутренние значения intсовпадают.

Для Employeeequals()непереопределяется, поэтому поведениепо умолчанию (использование==) возвращает то, что следует ожидать, учитывая, что employee1и employee2на самом делеотносятся к разным объектам.

Как правило, это означает, что для любого объекта можно определить, что значит equals(), в соответствии с создаваемым приложением.

Переопределение equals()

Переопределив поведениеметода Object.equals()по умолчанию, можно определить, что именно equals()будет означать для объектов вашего приложения. Опять же, для этого можно использовать Eclipse. Убедитесь, что в окнеEclipse IDE Source Employeeнаходится в фокусе, и выберитеSource >Override/Implement Methods. Появится диалоговоеокно, изображенноена рисунке4.

Рисунок 4. Диалоговое окно Override/Implement Methods

Мы ужеиспользовали этот диалог, но в данном случаенам нужно реализовать методсуперкласса Object.equals(). Найдите в спискеобъект Object, отметьтеметодequals(Object)и нажмитекнопку OK. Eclipse сгенерирует правильный коди разместит его в исходном файле.

Логично, что два объекта Employee, если состояниеэтих объектов одинаково. То есть, они равны, если их атрибуты - фамилия, имя, возраст –одни и теже.

Автоматическое создание метода equals()

Eclipseможет генерировать методequals()на основепеременных экземпляра (атрибутов), определиенных для класса. Так как Employee- это подкласс класса Person, сначала сгенерируем методequals()для Person. В окнеEclipseProject Explorer щелкнитеправой кнопкой мыши на Personи выберитеGenerate hashCode() and equals(), чтобы вызвать диалоговоеокно, показанноена рисунке5.

Рисунок 5. Диалоговое окно длясозданияhashCode() иequals()

www.ibm.com/developerworks/ru/edu/j-introtojava2/section2.html

8/11

Соседние файлы в папке java