ВАЖНЫЕ пояснения к заданиям на лабы

Л.р.1 Ввод-вывод, циклы, массивы

1. Целиком прочитайте 3-ю главу Хорстманна. Начиная с "Hello, World!" на стр.60. При первом прочтении можно пропустить следующее:
  • подробности преобразования типов;
  • обсуждение кодировок символов;
  • strictfp;
  • кучу методов класса String;
  • приоритеты операторов;
  • форматы вывода для printf;
  • import javax.swing.*, JOptionPane и прочие графические штуковины;
  • BigInteger.
2. Особое внимание обратите на операцию конкатенации ("+") строк (очень полезно для вывода на экран).
3. Для ввода проще всего использовать класс Scanner (стр. 86).
4. if-ы и циклы описаны, начиная со стр.94. По примерам программ вполне можно понять, что к чему.
5. Все массивы в Java - динамические. См. стр. 112.
6. Не беспокойтесь о формате ввода чисел с плавающей точкой (через точку '.' или запятую ','). Этот формат зависит от настроек системы. Если у Вас программа нормально работает с запятой - на сервере она будет нормально работать с точкой.

Л.р.2 Инкапсуляция

1. Тщательно уясните для себя, чем отличаются простые и ссылочные типы, в каких операциях они ведут себя по-разному. Запомните эти примеры, чтобы потом не допускать ошибок.
2. Чаще всего различия между простыми и ссылочными типами проявляются при работе с массивами и передаче параметров в функции. Поэтому в задании на "массив праздников" используйте обычные Java-вские массивы, а не классы из библиотеки коллекций (ArrayList и т.п.).
3. Помните об инкапсуляции! Любая "операция с объектом" должна быть реализована в виде метода соответствующего класса. (универсальный совет)
4. Не пишите по 2 или 3 раза один и тот же код! Вынесите его в отдельную функцию! (универсальный совет)
5. По техническим причинам при отправке на сервер ваш класс должен находиться в "дефолтном" пакете. Т.е., если в начале отсылаемого файла стоит строка "package имя_пакета;" - то этот код не сможет быть скомпилирован!

Л.р.3 Полезный класс: вектор

1. Четко уясните для себя те 3 шага, которые должна сделать программа при попытке добавить еще один элемент в массив, который уже полностью заполнен. Когда вас просят проиллюстрировать "механизм перевыделения памяти" - это как раз оно. При этом проверка, что место закончилось, а также само добавление еще одного элемента (после перевыделения) к этому не имеют никакого отношения.
2. Убедитесь, что Вы правильно понимаете назначение каждого поля Вашего класса Vector, а также в том, что все эти поля являются необходимыми, и среди них нет "лишних" (без которых можно обойтись).
3. Поля класса, безусловно, должны быть private. Но как же тогда получить к ним доступ "снаружи" класса?
4. Если в конструкторе по умолчанию Вы выделяете память сразу под многомегабайтный массив - это неправильно.При таком подходе у нас никак не получится создать, скажем, 1000000 объектов класса Vector на 10 элементов каждый. А такая возможность должна быть!
5. При "перевыделении памяти" увеличивать массив внутри Vector'а всего на 1 элемент - неправильно. Это будет ужасающе медленно работать. Увеличение каждый раз в 2 раза подойдет.

Л.р.4 Открытое наследование

1. Четко уясните для себя цель наследования: Bus и Truck сделаны наследниками Vehicle потому, что мы хотим унаследовать от Vehicle реализацию (чтобы не писать по нескольку раз один и тот же код) или интерфейс? (чтобы наш Bus или Truck мог быть подставлен на место Vehicle согласно принципу подстановки)

Л.р.5 "Наследование" реализации посредством композиции

1. Если класс Stack (или Queue) "extends" Vector - то каждый объект этого класса содержит в себе как бы объект класса Vector (содержит все его поля + поддерживает все его методы). Если же он содержит поле типа Vector - то опять: каждый объект класса Stack содержит в себе объект класса Vector (уже реально, а не "как бы"). Писать в программе и то, и другое одновременно - бессмысленно! (тогда в объекте класса Stack будет прятаться одновременно целых два Vector'а!)

2. Обратите внимание, что в этой задаче композиция используется для целей делегирования (обязанностей Stack'а Vector'у), а не для моделирования отношения "часть-целое", как это обычно принято.

Л.р.6 Полиморфизм

1. Полиморфизм, позднее связывание, динамическое связывание, полиморфное поведение - если не вдаваться в тонкие детали теории, можно считать эти слова синонимами.

2. Вообще полиморфизм - это "единообразная обработка разнотипных данных". Другой вариант: успешное пользование классом (вызов его методов) без знания, из какого именно класса методы при этом вызываются. Постарайтесь понять эти определения: они Вам неоднократно пригодятся при более близком ознакомлении с этим понятием.

3. Запомните раз и навсегда: полиморфный вызов - это вызов переопределенного метода через ссылку на суперкласс (или интерфейсную ссылку). Кстати, что в этом такого "полиморфного"? (с точки зрения определений, приведенных в п.2)

4. В ООП часто применяется понятие "интерфейс класса". Под этим имеется ввиду набор его public-методов. И это не имеет никакого отношения к ключевому слову "interface", которое мы пишем в исходном коде на Java! Обычно интерфейс класса противопоставляется его реализации. Это очень важно понимать, чтобы правильно определиться с целью наследования (см. п.1 л.р.4!). См. наследование интерфейса и наследование реализации.

Л.р.7 Внутренние классы

1. Четко осознайте цель, с которой разработчики языка Java придумали две разновидности вложенных классов: static и обычные. Если Вы считаете, что разница между ними только в том, что статические имеют доступ только к статическим членам своего "внешнего" класса - то это неправда. Вспомните, что объекты этих двух категорий классов даже создаются по-разному! (как?) Подумайте над вопросом, объект какого класса будет больше по размеру при прочих равных условиях: вложенного статического или нестатического ("внутреннего")?

2. Выучите хотя бы наизусть конструкцию объявления (и создания экземпляра) локального безымянного класса - этот прием очень часто используется при программировании оконных приложений!

3. Лучше всего для освоения внутренних/вложенных классов подходит Хорстманн (Шилдт освещает их очень плохо).

Инд.з. Полиморфизм

  1. Делайте поиск разумным. Например, искать человека по точному значению его веса - вряд ли имеет смысл.
  2. Обращайте внимание на возможно возникающее у Вас дублирование кода. Например, если как при добавлении записи, так и при ее редактировании надо задать пользователю одну и ту же кучу вопросов - стоит задуматься над тем, чтобы вынести это в отдельную фцнкцию. То же касается "общих" вопросов - которые одинаковые доя обоих классов.
  3. Хотя более разумно при редактировании - не вводить все заново, в предлагать пользователю менять отдельные поля.
  4. Если одна и та же операция в разных классах делается по-разному - это полиморфизм. Не надо писать: if(obj instanceof MyClass1) ... else ... Просто поместите этот код в методы соответствующих классов и вызывайте их полиморфно!
  5. Класс Vector желательно специально под цели данной задачи не модифицировать (за исключением, разумеется, имени класса, который хранится). Идея в том, что Vector - это универсальный класс, и его нелогично подстаривать под задачу!
Comments