Я нашел, что простые примеры
Я нашел, что простые примеры исключительно полезны для окончательного понимания объясненного материала во время семинаров, поэтому в конце включено несколько заданий. Большинство из разработанных примеров просты, чтобы их можно выполнить за короткий промежуток времени на семинаре, в то время как инструктор проверят все ли студенты в достаточной степени поняли материал. Некоторые примеры более сложны чтобы не вызвать скуку у наиболее продвинутых студентов. В основном, цель большинства примеров решить их в короткое время, чтобы проверить и укрепить свои знания. Некоторые достаточно интересны, хотя и не вызывают всеобщего интереса. (Вероятнее что вы сами найдете их - либо они вас найдут). Выборочные решения могут быть найдены в электронном документации The Thinking in Java Annotated Solution Guide доступной на сайте www.BruceEckel.com за небольшую плату.
Решения для выбранных упражнений могут быть найдены в электронной документации The Thinking in Java Annotated Solution Guide, доступной за малую плату на www.BruceEckel.com.
Следуя примеру HelloDate.java из этой главы, создайте программу “hello, world”, которая просто печатает выражение. Вам необходим один метод в вашем классе (метод “main” принимает выполнение, когда программа начинается). Не забудьте сделать его статическим и включить список аргументов, даже если вы не используете его, скомпилируйте программу с помощью javac и запустите ее, используя java. Если вы используете другую среду разработки, отличную от JDK, выучите, как скомпилировать и запустит программу в этой среде. Найдите фрагмент кода, вводящий ATypeName, и включите его в программу, затем скомпилируйте и запустите. Включите фрагмент кода DataOnly в программу, затем скомпилируйте и запустите. Измените упражнение 3 так, чтобы значение данных в DataOnly назначалось и печаталось в main( ). Напишите программу, которая включает и вызывает метод storage( ), определенный как фрагмент кода в этой главе. Включите фрагмент кода StaticFun в работающую программу. Напишите программу, которая печатает три аргумента, принимаемые из командной строки. Чтобы сделать это, вам нужно ввести индекс в массив командной строки Strings. Включите AllTheColorsOfTheRainbow пример в программу, затем скомпилируйте и запустите. Найдите код для второй версии HelloDate.java, который является просто примером документации. Запустите javadoc для файла и просмотрите результат в вашем Web броузере. Включите docTest в файл, затем скомпилируйте и пропустите его через javadoc. проверьте результат в вашем Web броузере. Добавьте HTML список элементов в документацию упражнения 10. Возьмите программу в упражнении 1 и добавьте в нее комментарии-документацию. Выберите эту документацию в HTML файл, используя javadoc и просмотрите его в вашем Web броузере.
[20] Это может быть озарением. Есть те, кто может сказать: “понятно, это указатель”, но это, предположительно, лежащая в основе реализация. Также, ссылки Java во многом похожи на ссылки C++, чем на указатели с их синтаксисом. В первой редакции книги я изобрел новый термин “handle”, потому что ссылки C++ и ссылки Java имеют некоторое важное различие. Я пришел из C++ и не хочу смущать программистов C++, которые будут составлять самую большую аудиторию для Java. Во второй редакции я решил, что “ссылка” будет наиболее часто используемым термином, и тот, кто переходит с C++ будет иметь много больше для копирования с этой терминологией ссылок, так что они могут прыгнуть сразу на обе ноги. Однако есть люди, которые не согласны даже с термином “ссылка”. Я читал в одной книге, где было “абсолютно неправильно сказано, что Java поддерживает передачу по ссылке”, потому что идентификаторы объектов Java (в соответствии с авторами) реально являются ссылками на объект”. И все реально передается по значению. Так что вы не передаете по ссылке. Вы “передаете ссылку объекта по значению”. Можно было приводить доводы в пользу точности таких замысловатых объяснений, но я думаю, что мой подход упрощает понимание концепции без того, чтобы повредить чему-нибудь (адвокаты языка могут утверждать, что я лгу вам, но я скажу, что я обеспечиваю подходящую абстракцию).
Решения для выбранных управжнений могут быть найдены в электронной документации The Thinking in Java Annotated Solution Guide, доступной за малую плату на www.BruceEckel.com.
Есть два примера в разделе, озаглавленном “Предшествование” в начале этой главы. Соберите эти примеры в программу и посмотрите почему они дают разный результат. Поместите методы ternary( ) и alternative( ) в работающую программу. Из разделов, озаглавленных “if-else” и “return”, поместите методы test( ) и test2( ) в работающую программу. Напишите программу, которая печатает значения от одного до 100. Измените упражнение 4 так, чтобы программа выходила при использовании ключавого слова break на значении 47. Попробуйте вместо этого использовать return. Напишите функцию, получающую два аргумента String и использующую все логические сравнения для сравнения двух строк и печати результата. Для == и != также выполните проверку equals( ). В main( ) вызовите вашу функцию с несколькими разными объектами String. Напишите программу, которая генерирует 25 случайных значений. Для каждого значения используйте инструкцию if-then-else, чтобы узнать, является ли число больше, меньше или равным другому случайному числу. Измените упражнение 7 так, чтобы ваш код был окружен “бесконечным” циклом while. Она будет работать до тех пор, пока вы не прервете ее с клавиатуры (обычно при нажатии Control-C).
Напишите программу, которая использует два вложенных цикла for и оператор остатка от деления (%) для определения простых чисел для печати (целых чисел, которые не точно делятся на любое число за исключением себя и 1). Создайте инструкцию switch, которая напечатает сообщение для каждого варианта, и помесите switch в цикл for, который опробует каждый случай. Поместите break после каждого случая и проверьте это, затем уберите break и посмотрите, что случится.
[25] John Kirkham пишет: Я начал заниматься компьютерами в 1962, испоьзуя FORTRAN II для IBM 1620. В то время и на протяжении 1960-х и до 1970-х FORTRAN был языком с буквами верхнего регистра. Это, вероятно, произошло потому, что многие вводные устройства были старыми терминальными устройствами, которые использовали 5-ти битный код Боде, в котором не было маленьких букв. ‘E’ в экспоненциальной записи было также всегда в верхнем регистре и никогда не путалось с основанием натурального логарифма ‘e’, которое всегда в нижнем регистре. ‘E’ просто оставили для экспоненты, которая используется в обычной системе счисления — обычно это 10. В то время восмеричная система также широко использовалась программистами. Хотя я никогда не видел ее использования, если я видел восмеричное число в экспоненциальной записи, я рассматривал его с основанием 8. Первое время, помня вид экспоненциального использования ‘e’ в нижнем регистре, позднее 1970 я также находил это запутывающим. Проблема возникла, поскольку нижний регистр пришел в FORTRAN не с самого начала. Мы на самом деле имели функции, в которых можно было использовать натуральный логарифм, но они все были в верхнем регистре.
Решения для выбранных упражнений могут быть найдены в электронной документации The Thinking in Java Annotated Solution Guide, доступной за малую плату на www.BruceEckel.com.
Создайте класс с конструктором по умолчанию (который не принимает аргументов), печатающий сообщение. Создайте объект этого класса.
Добавьте перегруженный конструктор к Упражнению 1, который принимает аргумент типа String и печатает его наряду с вашим сообщением.
Создайте массив ссылок на объекты вашего класса из Упражнения 2, но не создавайте объекты для помещения их ссылок в массив. Когда вы запустите программу, обратите внимание, есть ли сообщения об инициализации, которые печатаются при вызове конструктора.
Завершите Упражнение 3, создав объекты, и присоедините их к ссылкам в массиве.
Создайте массив из объектов String и присоедините строку к каждому элементу. Распечатайте массив, используя цикл for.
Создайте класс с названием Dog с перегруженным методом bark( ). Этот метод должен перегружаться, основываясь на различных примитивных типах данных, и печатать различные типы лая, завывания и т.п., в зависимости от того, какая перегруженная версия вызвана. Напишите main( ), который вызывает различные версии. Измените Упражнение 6 так, чтобы два разных перегруженных метода имели два аргумента (двух различных типов), но в разном порядке. Проверьте как это работает.
Создайте класс без конструктора, а затем создайте объект этого класса в main( ) для проверки того, что конструктор по умолчанию синтезируется автоматически.
Создайте класс с двумя методами. В первом методе вызовите второй дважды: первый раз без использования this, а второй раз, используя this.
Создайте класс с двумя (перегруженными) конструкторами. Используя this, вызовите второй конструктор внутри первого.
Создайте класс с методом finalize( ), который печатает сообщение. В main( ) создайте объект вашего класса. Объясните поведение вашей программы.
Измените Упражнение 11 так, чтобы ваш finalize( ) вызывался всегда.
Создайте класс, называемый Tank, который может быть заполнен и опустошен, и имеет смертельное состояние, при котором он должен быть опустошен во время очистки объекта. Напишите finalize( ), который проверяет смертельное состояние. В main( ) проверьте возможные сценарии, которые возникают при использовании вашего Tank.
Решения к избранным упражнениям находятся в электронном документе The Thinking in Java Annotated Solution Guide, доступном за небольшую плату на www.BruceEckel.com.
Напишите программу создающую объект ArrayList без явного импорта java.util.*.
В разделе “package: модуль библиотеки,” перепишите фрагменты кода, относящиеся к mypackage в компилируемый и запускаемый набор файлов Java.
В разделе “Коллизии,” возьмите фрагменты кода и перепишите их в программу, и проверьте, что коллизии действительно происходят. Обобщите класс P определенный в этой главе добавлением перегруженных версий rint( ) и rintln( ) необходимыми для управления всеми основными типами Java.
Измените выражение import в TestAssert.java для включения или выключения механизма контроля.
Создайте класс с публичными, приватными, защищенными, и “дружественными” методами и данными. Создайте объект этого класса и посмотрите какие ошибки компилятора Вы получите, пытаясь получить доступ ко всем членам этого класса. Убедитесь, что классы в одном каталоге являются частью пакета по умолчанию. Создайте класс с защищенными(protected) данными. Создайте второй класс в том же файле с методом, который манипулирует с защищенными данными в первом классе.
Измените класс Cookie как указано в разделе “protected: ‘тип дружественного доступа.’” Проверьте что метод bite( ) не публичный.
В разделе “Доступ класса” Вы найдете фрагменты кода описывающие mylib и Widget. Создайте эту библиотеку, и затем создайте Widget в классе не являющемся частью пакета mylib.
Создайте новый каталог и отредактируйте переменную CLASSPATH чтобы включить туда новый каталог. Скопируйте файл P.class (после компиляции com.bruceeckel.tools.P.java) в Ваш новый каталог и затем измените имена файла, класс P внутри и имена методов. (Вы можете также захотеть добавить дополнительный вывод, чтобы видеть как это работает.) Создайте еще одну программу в другом каталоге которая использует Ваш новый класс. Следуя форме примера Lunch.java, создайте класс с именем ConnectionManager, который управляет фиксированным массивом объектов Connection. Клиентский программист не должен иметь возможности явного создания объектов Connection, а может только получить их из статического метода в ConnectionManager. Когда в ConnectionManager параметр выходит за пределы объектов, он возвращает ссылку на null. Проверьте классы в main( ). Создайте следующий файл в каталоге c05/local (доступном по CLASSPATH):
Решения этих упражнений могут быть найдены в электронном документе The Thinking in Java Annotated Solution Guide, доступном с www.BruceEckel.com.
Создайте два класса, A и B, с конструкторами по умолчанию (пустой список аргументов), которые объявляют сами себя. Наследуйте новый класс C от A, и создайте объект класса B внутри C. Не создавайте конструктор для C. Создайте объект класса C и наблюдайте за результатами. Модифицируйте упражнение 1 так, что A и B получат конструкторы с аргументами взамен конструкторов по умолчанию. Напишите конструктор для C и осуществите инициализацию с конструктором C.
Создайте простой класс. Внутри второго класса создайте объект первого класса. Используйте ленивую инициализацию для создания экземпляра этого объекта. Наследуйте новый класс от класса Detergent. Переопределите scrub( ) и добавьте новый метод называемый sterilize( ). Возьмите файл Cartoon.java и закомментируйте конструктор для класса Cartoon. Объясните, что случилось. Возьмите файл Chess.java и закомментируйте конструктор для класса Chess. Объясните, что произошло. Докажите, что конструктор по умолчанию создается компилятором. Докажите, что конструктор базового класса вызывается всегда и он вызывается до вызова конструктора дочернего класса. Создайте базовый класс с конструктором не по умолчанию и наследуйте от него класс с конструктором по умолчанию и не по умолчанию. В конструкторах дочернего класса вызовите конструктор базового класса. Создайте класс Root, который содержит экземпляр каждого из классов (которые Вы так же должны создать) Component1, Component2, и Component3. Наследуйте класс Stem от Root который будет так же содержать экземпляры каждого компонента. Каждый класс должен содержать конструктор по умолчанию, который печатает сообщение о этом классе. Измените, упражнение 10, так, что бы каждый класс имел только конструкторы не по умолчанию. 12. Добавьте в существующую иерархию методы cleanup( ) во все классы в упражнении 11. Создайте класс с методом, который перегружен три раза. Наследуйте новый класс, добавьте новую перегрузку метода и посмотрите на то, что все четыре метода доступны в дочернем классе. В Car.java добавьте метод service( ) в Engine и вызовите этот метод в main( ). Создайте класс внутри пакета. Ваш класс должен иметь один метод с модификатором protected. Снаружи пакета попытайтесь вызвать метод и затем объясните результаты. После этого наследуйте новый класс и вызовите этот метод уже из него. Создайте класс Amphibian. От него наследуйте класс Frog. Поместите соответствующие методы в базовый класс. В main( ), создайте Frog и приведите его к базовому типу Amphibian и покажите то, что все методы работают. Измените, упражнение 16 так, что бы Frog переопределял определения методов из базового класса (предоставьте новые определения, используя те же самые обозначения методов). Заметьте, что случилось в main( ). Создайте новый класс с полем static final и полем final, а затем покажите разницу между ними. Создайте класс с пустой final ссылкой на объект. Осуществите ее инициализацию внутри метода (не конструктора) сразу после того, как вы его определили. Покажите то, что final должна быть инициализирована до использования и после этого ее нельзя изменить. Создайте класс, содержащий final метод. Наследуйте от этого класса и попытайтесь переопределить этот метод. Создайте класс с модификатором final и попытайтесь наследовать от него. Докажите, что загрузка класса имеет место быть только один раз. Докажите, что загрузка может быть вызвана созданием первого экземпляра этого класса или доступом к static
элементу. В Beetle.java, наследуйте специфический тип beetle от класса Beetle, следуйте тому же самому формату, как в существующих классах. Проследите и объясните вывод.
[ Предыдущая глава ] [ Краткое оглавление ] [ Оглавление ] [ Список ] [ Следующая глава ]
Last Update:04/24/2000
Решения к выбранным упражнениям могут быть найдены в электронном документе The Thinking in Java Annotated Solution Guide, доступном с www.BruceEckel.com.
Добавьте новый метод в базовый класс Shapes.java, который печатает сообщение, но не переопределяйте его в дочерних классах. Объясните, что происходит. Теперь переопределите его в одном из дочерних классов, но не в остальных, и посмотрите, что произошло. В конце переопределите его во всех классах. Добавьте новый тип Shape в Shapes.java и проверьте в main( ), что полиморфизм работает для ваших новых типов, как если бы он были старых типов. Измените Music3.java, так что бы what( ) стал корневым методом объекта Object метода toString( ). Попробуйте напечатать объект Instrument используя System.out.println( ) (без любых приведений). Добавьте новый тип Instrument к Music3.java и проверьте, что полиморфизм работает для вашего нового типа. Измените Music3.java, так, что бы он случайным образом создавал объекты Instrument так же, как это делает Shapes.java. Создайте иерархию наследования Rodent: Mouse, Gerbil, Hamster, и т.д. В базовом классе, создайте метод общий для всех Rodent и переопределите их в дочерних классах для осуществления различного поведения в зависимости от типа Rodent. Создайте массив из Rodent, заполните его различными типами Rodent и вызовите ваш метод базового класса, что бы посмотреть, что случилось. Измените упражнение 6, так, что бы Rodent стал abstract классом. Сделайте методы Rodent абстрактными, где только возможно. Создайте класс как abstract без включения любых abstract методов и проверьте, что Вы не можете создать ни одного экземпляра этого класса. Добавьте класс Pickle к Sandwich.java. Измените упражнение 6, так что бы оно демонстрировало порядок инициализации базовых и дочерних классов. Теперь добавьте участников объектов в оба, в базовый и в дочерний классы и покажите порядок в каком происходит инициализация при создании объекта. Создайте трех уровневую иерархию наследования. Каждый из классов должен иметь метод finalize( ) и он должен правильно вызывать версию finalize( ) из базового класса. Покажите, что ваша иерархия работает правильно. Создайте базовый класс с двумя методами. В первом методе, вызовите второй метод. Наследуйте класс и переопределите второй метод. Создайте объект дочернего класса и приведите его к базовому типу, затем вызовите первый метод. Объясните, что произошло. Создайте базовый класс с методом abstract print( ), который переопределяется в дочернем классе. Переопределенная версия метода печатает значение переменной int, определенной в дочернем классе. В точке определения этой переменной, присвойте ей не нулевое значение. В конструкторе базового класса вызовите этот метод. В main( ), создайте объект дочернего типа и затем вызовите его print( ). Объясните результат. Следуйте примеру в Transmogrify.java, создайте класс Starship содержащий ссылку AlertStatus, которая может отображать три различных состояния. Включите в класс методы изменяющие это состояние. Создайте abstract класс без методов. Наследуйте класс и добавьте метод. Создайте static метод, который получает ссылку на базовый класс, приведите ее к дочернему типу и вызовите этот метод. В main( ), покажите, что это работает. Теперь поместите abstract объявление для метода в базовый класс, это уничтожит потребность в приведении к дочернему типу.
[37]
Для программистов C++, это аналог C++ pure virtual function.
[ Предыдущая глава ] [ Короткое оглавление ] [ Содержание ] [ Индекс ] [ Следующая глава ]
Решения для этих упражнений доступны в электронном документе The Thinking in Java Annotated Solution Guide, доступном за небольшую плату с www.BruceEckel.com.
Докажите, что поля в интерфейсе полностью static и final. Создайте интерфейс, содержащий три метода, в его собственном пакете. Реализуйте этот интерфейс в другом пакете. Докажите, что все методы в интерфейсе автоматически public. В c07:Sandwich.java, создайте интерфейс с именем FastFood (с соответствующими методами) и изменит Sandwich так, что бы он также реализовывал FastFood. Создайте три интерфейса, каждый с двумя методами. Наследуйте новый интерфейс от этих трех, добавьте новый метод. Создайте класс реализующий этот новый интерфейс и так же наследующий от конкретного класса. Теперь напишите четыре метода, каждый из которых получают один из четырех интерфейсов в качестве аргумента. В main( ), создайте объект вашего класса и передайте его каждому из методов. Измените упражнение 5, создайте abstract класс и наследуйте его в дочернем классе. Измените Music5.java, добавьте в него интерфейс Playable. Удалите объявление play( ) из Instrument. Добавьте Playable в дочерний класс, путем добавления его в список implements. Измените tune( ) так, что бы он получал Playable вместо Instrument. Измените упражнение 6 в главе 7, так что бы Rodent был бы интерфейсом. В Adventure.java добавьте интерфейс CanClimb, такой же, как и другие. Напишите программу, которая импортирует и использует Month2.java. Следуя примеру в Month2.java, создайте список дней недели. Создайте интерфейс с не менее, чем одним методом, в своем собственном пакете. Создайте класс в другом пакете. Добавьте protected внутренний класс, который реализует этот интерфейс. В третьем пакете, наследуйте от вашего класса и внутри метода возвратите объект protected внутреннего класса, приведите к базовому типу во время возврата. Создайте интерфейс с не менее, чем одним методом и реализуйте его определением во внутреннем классе методом, который возвращает ссылку на этот интерфейс. Повторите упражнение 13, но определите внутренний класс внутри контекста метода. Повторите упражнение 13 используя анонимный внутренний класс. Создайте private внутренний класс, который реализует public интерфейс. Напишите метод, возвращающий ссылку на экземпляр private
Решения для выбранных упражнений могут быть найдены в электронной документации "The Thinking in Java Annotated Solution Guide", доступной за малую плату на www.BruceEckel.com.
Создайте массив double и заполните его (fill( )), используя RandDoubleGenerator. Результат напечатайте. Создайте новый класс, называемый Gerbil с полем int gerbilNumber, которое инициализируется конструктором (аналогично примеру Mouse в этой главе). Создайте метод, называемый hop( ), который печатает номер и какое это обращение. Создайте ArrayList и добавьте группу объектов Gerbil в List. Теперь, используйте метод get( ) для прохода по списку и вызова hop( ) для каждого Gerbil.
Измените Упражнение 2 так, чтобы вы использовали Iterator для обхода List и вызова hop( ).
Возьмите класс Gerbil из Упражнения 2 и поместите его в Map, ассоциируя имя каждого Gerbil, как строку (ключ) для каждого Gerbil (значение), поместите их в таблицу. Получите Iterator для keySet( ) и используйте его для прохода Map, поиска Gerbil для каждого ключа и печать ключа и вызова hop( ) для Gerbil. Создайте List (попробуйте и ArrayList, и LinkedList) и заполните их, используя Collections2.countries. Отсортируйте список и напечатайте его, затем примените Collections.shuffle( ) к списку несколько раз, печатайте каждый раз, чтобы увидеть, как вызовы метода shuffle( ) смешивает список по новому каждый раз. Продемонстрируйте, что вы не можете ничего добавить в MouseList, кроме Mouse.
Измените MouseList.java так, чтобы он наследовался от ArrayList вместо использования композиции. Покажите проблему, которая при этом возникает.
Восстановите CatsAndDogs.java, создав контейнер Cats (использующий ArrayList), который принимает и возвращает только объекты Cat.
Создайте контейнер, который инкапсулирует массив String, и который добавляет только String, и возвращает только String, так чтобы не нужно было приведение типов при использовании. Если ваш внутренний массив недостаточно велик для добавления следующего элемента, ваш контейнер автоматически мог бы изменять размер. В main( ) сравните производительность вашего контейнера и ArrayList, хранящего String.
Решения для выбранных упражнений могут быть найдены в электронной документации The Thinking in Java Annotated Solution Guide, доступной за малую плату на www.BruceEckel.com.
Создайте класс с main( ), который выбрасывает объект, класса Exception внутри блока try. Передайте конструктору Exception аргумент String. Поймайте исключение внутри предложение catch и напечатайте аргумент String. Добавьте предложение finally и напечатайте сообщение, чтобы убедится, что вы были там. Создайте ваш собственный класс исключений, используя ключевое слово extends. Напишите конструктор для этого класса, который принимает аргумент String, и хранит его внутри объекта в ссылке String. Напишите метод, который печатает хранящийся String. Создайте предложение try-catch для наблюдения своего собственного исключения. Напишите класс с методом, который выбрасывает исключение типа, созданного в Упражнении 2. Попробуйте откомпилировать его без спецификации исключения, чтобы посмотреть, что скажет компилятор. Добавьте соответствующую спецификацию исключения. Испытайте ваш класс и его исключение в блоке try-catch. Определите ссылку на объект и инициализируйте ее значением null. Попробуйте вызвать метод по этой ссылке. Не окружайте код блоком try-catch, чтобы поймать исключение.
Создайте класс с двумя методами f( ) и g( ). В g( ) выбросите исключение нового типа, который вы определили. В f( ) вызовите g( ), поймайте его исключение и, в предложении catch, выбросите другое исключение (второго определенного вами типа). Проверьте ваш код в main( ). Создайте три новых типа исключений. Напишите класс с методом, который выбрасывает все три исключения. В main( ) вызовите метод, но используйте только единственное предложение catch, которое будет ловить все три вида исключений.
Напишите код для генерации и поимки ArrayIndexOutOfBoundsException.
Создайте свое собственное поведение по типу возобновления, используя цикл while, который будет повторяться, пока исключение больше не будет выбрасываться.
Решения для выбранных упражнений могут быть найдены в электронной документации The Thinking in Java Annotated Solution Guide, доступной за малую плату на www.BruceEckel.com.
Откройте текстовый файл так, чтобы вы смогли прочесть его построчно. Читайте каждую строку, как String, и поместите этот объект String в LinkedList. Распечатайте все строки из LinkedList в обратном порядке. Измените Упражнение 1 так, чтобы имя читаемого фала принималось из командной строки.
Измените Упражнение 2, чтобы была возможность открывать текстовый файл, в который вы могли бы писать. Запишите строки из ArrayList вместе с номерами строк (не пробуйте использовать класс “LineNumber”), в файл.
Измените Упражнение 2, чтобы происходил перевод всех строк из ArrayList в верхний регистр, а результат пошлите в System.out.
Измените Упражнение 2, чтобы оно получало дополнительные аргументы из командной строки: слова, которые необходимо найти в файле. Напечатайте строки, в которых есть эти слова.
Измените DirList.java так, чтобы FilenameFilter на самом деле открывал каждый файл и принимал файлы, основываясь на том, существует ли любой из аргументов командной строки в этом файле.
Создайте класс, называемый SortedDirList с конструктором, который принимает информацию о пути к файлу и строит хранящийся список директории из файлов по этому пути. Создайте два перегруженных метода list( ), которые будут производить либо полный список, или подмножество из списка, основываясь на аргументе. Добавьте метод size( ), который принимает имя файла и возвращает размер этого файла. Измените WordCount.java так, чтобы она производила алфавитную сортировку, используя инструмент из Главы 9.
Измените WordCount.java так, чтобы она использовала классы, содержащие String и подсчитывающие число хранящихся различных слова, а множество (Set) этих объектов содержало список этих слов.
Измените IOStreamDemo.java так, чтобы она использовала LineNumberInputStream для хранения истории числа строк. Обратите внимание, что гораздо легче хранить историю программно.
Решения к выбранным упражнениям могут быть найдены в электронном документе The Thinking in Java Annotated Solution Guide, доступном за небольшую плату на www.BruceEckel.com.
Добавьте Rhomboid в Shapes.java. Создайте Rhomboid, сделайте восходящее приведение к Shape, затем нисходящее к Rhomboid. Попробуйте нисходящее приведение к Circle и посмотрите, что случится.
Измените Упражнение 1 так, чтобы оно использовало instanceof для проверки типа перед выполнением нисходящего приведения.
Измените Shapes.java так, чтобы можно было подсвечивать (устанавливать флаг) во всех формах Shape конкретного типа. Метод toString( ) для каждого объекта унаследованного из Shape должен показывать подсвечен ли Shape.”
Измените SweetShop.java так, чтобы каждый тип создания объекта контролировался аргументом из командной строки. Т.е, если в командной строке набрать“java SweetShop Candy,” то создаются только объекты Candy. Обратите внимание, что Вы можете контролировать какие объекты Class загружаются через аргументы командной строки.
Добавьте новый тип класса Pet в PetCount3.java. Проверьте, что он создается и корректно считается в методе main( ).
Напишите метод, который берет объект и рекурсивно печатает все классы в иерархии объектов.
Измените Упражнение 6 так, чтобы оно использовало метод Class.getDeclaredFields( ) для отображения информации о полях класса.
В ToyTest.java, закоментируйте конструктор по умолчанию для Toy и объясните, что случится.
Включите новый тип интерфейса interface в ToyTest.java и проверьте, что это определяется и отображается корректно.
Создайте новый тип контейнера, который использует приватный private ArrayList для хранения объектов. Сохраните тип первого объекта, который Вы туда положите, затем дайте возможность пользователю вставлять объекты только этого типа.
Напишите программу, проверяющую, является ли масисив char примитивным типом, либо настоящим объектом.
Реализуйте clearSpitValve( ) как описано в резюме.
Решения для выбранных упражнений могут быть найдены в электронной документации The Thinking in Java Annotated Solution Guide, доступной за малую плату на www.BruceEckel.com.
Создайте апплет/приложение, используя класс Console, как показано в этой главе. Включите текстовое поле и три кнопки. Когда вы нажимаете каждую кнопку, сделайте, чтобы разный текст появлялся в текстовом поле.
Добавьте checkBox-элемент в апплет, созданный в Упражнении 1, перехватите событие, и вставляйте разный текст в текстовое поле.
Создайте апплет/приложение, используя Console. В HTML документации с java.sun.com, найдите JPasswordField и добавьте его в программу. Если пользователь печатает правильный пароль, используйте Joptionpane для выдачи пользователю информации об успехе.
Создайте апплет/приложение, используя Console, и добавьте все компоненты, имеющие метод addActionListener( ). (Найдите их в HTML документации с java.sun.com. Совет: используйте индекс.) Захватите события и отобразите соответствующее сообщение для каждого из них в текстовом поле.
Создайте апплет/приложение, используя Console, с элементами JButton и JTextField. Напишите и присоедините соответствующие слушатели, чтобы если кнопка имела фокус, символы, напечатанные на ней, появлялись в JTextField.
Создайте апплет/приложение, используя Console. Добавьте в главный фрейм все компоненты, описанные в этой главе, включая меню и диалоги.
Измените TextFields.java так, чтобы символы в t2 сохраняли свой регистр, в котором они были набраны, вместо принудительного автоматического перевода в верхний регистр.
Найдите и загрузите один или несколько бесплатных сред разработки GUI, доступных в Internet, или купите коммерческие продукты. Исследуйте, что необходимо для добавления BangBean в эту среду и сделайте это.
Добавьте Frog.class в файл манифеста, как показано в этой главе, и запустите jar для создания JAR файла, содержащего и Frog и BangBean. Теперь либо загрузите и установите BDK от Sun, или используйте свой собственный компонент-ориентированный построитель программ, и добавьте JAR файл в свою среду, так, чтобы вы могли проверить оба компонента (Beans).
Решения отдельных заданий можно посмотреть в электронной книжке The Thinking in Java Annotated Solution Guide, доступную за небольшую плату на сайте www.BruceEckel.com.
Наследуйте класс от Thread и переопределите метод run( ). Внутри run() напечатайте сообщение и вызовите sleep(). Повторите это три раза и выйдете (return) из run(). Поместите приветственное сообщение в конструктор и переопределите finalaize() чтобы вывести прощальное сообщение. Создайте отдельный вызов процесса, назовите его System.gc() и System.runFinalization() внутри run(), напечатав сообщение, так как они выполняются. Создайте несколько объектов от процессов обоих типов и запустите их чтобы посмотреть, что произойдет.
Измените Sharing2.java добавив блок synchronized внутрь метода run( ) для TwoCounter вместо синхронизации всего run( ) метода.
Создайте два подкласса Thread, один, использующий run( ) для запуска, и перехватывающий ссылку на второй процесс Thread, а затем вызывающий wait( ). Вызов run() второго класса должен вызывать notifyAll( ) для первого процесса после нескольких секунд ожидания, так, чтобы первый процесс при этом вывел сообщение.
В Counter5.java внутри Ticker2, удалите yield( ) и объясните результат работы. Потом замените yield( ) на sleep( ) и объясните этот результат.
В ThreadGroup1.java, замените вызов sys.suspend( ) на вызов wait( ) для группы процессов, установив для них ожидание в две секунды. Для того чтобы это работало корректно необходимо установить блокировку для sys внутри блока synchronized.
Измените Daemons.java так, чтобы main( ) был sleep( ) вместо readLine( ). Поэкспериментируйте с различным значением времени засыпания чтобы увидеть что произойдет.
В Главе 8 найдите пример GreenhouseControls.java, состоящий их трех файлов. В Event.java, класс Event основан на наблюдении времени. Замените Event так, чтобы оно стало процессом Thread, и замените весь пример так, чтобы он работал с новым, основанным на Thread событием Event.
Измените Exercise 7 так, чтобы для запуска системы использовался класс java.util.Timer из JDK 1.3.
Содержание раздела