Java se сервлеты и jsp паттерны Gof junit Log4j ant



Pdf көрінісі
бет6/22
Дата11.12.2019
өлшемі8,99 Mb.
#53432
1   2   3   4   5   6   7   8   9   ...   22
Байланысты:
JAVA Methods Programming v2.march2015 (2)


КЛАССЫ И ОБЪЕКТЫ
73
своего generic-класса. Причем такому методу разрешено быть статическим, так 
как параметризацию обеспечивает сам метод, а не класс, в котором он объяв-
лен. Метасимволы применимы и к generic-методам.
/* # 14 # параметризованные конструкторы и методы # SimpleActionCourse.java */
package
 by.bsu.genericmethod;
public
 class SimpleActionCourse {
       public
 extends Course> SimpleActionCourse(T1 course) { // конструктор
         // реализация
       
}
       public
  SimpleActionCourse() { // конструктор
         // реализация
       
}
       public
 extends Course> float calculateMark(T3 course) {
         // реализация
       
}
       public
  boolean printReport(T4 course) {
         // реализация
       
}
       public
  void check() {
         // реализация
       
}
}
Создание экземпляра с параметром и вызов параметризованного метода с па-
раметром выглядят следующим образом:
SimpleActionCourse sap = new SimpleActionCourse(new Course());
sap.printReport(new Course(7112));
Создание экземпляра с использованием параметризованного конструктора без 
параметров требует указания типа параметра перед именем конструктора
SimpleActionCourse sa = new SimpleActionCourse();
Аналогично для метода без параметров
sa.check();
Методы с переменным числом параметров
Возникают  ситуации,  когда  заранее  неизвестно  количество  передаваемых 
экземпляров класса в метод. В обычной ситуации пришлось бы создавать не-
сколько  перегруженных  методов  с  разным  числом  параметров  одного  типа. 
Другим решением будет один метод с параметром в виде массива или коллек-
ции, что потребует предварительной организации соответствующего объекта 
массива или коллекции.

ОСНОВЫ JAVA
74
Начиная с версии Java 5, появилась возможность передачи в метод нефикси-
рованного числа параметров, что позволяет отказаться от предварительного со-
здания сложного объекта для его последующей передачи в метод. Набор объек-
тов, переданный в такой метод, преобразуется в массив с типом и именем, кото-
рые указаны в качестве параметров метода. Метод printf() с переменным числом 
аргументов уже применялся неоднократно в примерах предыдущих глав.
Список параметров метода выглядит в общем случае:
(Тип... args)
а в случае необходимости передачи параметров других типов
(Тип1 t1, Тип2 t2, ТипN tn, Тип... args)
/* # 15 # определение количества параметров метода # DemoVarargs.java */
package
 by.bsu.varargs;
public
 class DemoVarargs {
          public static int defineArgCount(Integer... args) {
                    if (args.length == 0) {
                                System.out.print("No arg ");
                    } else {
                                for (int element : args) {
                                           System.out.printf("arg:%d ", element);
                                }
                    }
                    return args.length;
          }
          public static void main(String … args) {
            System.out.println("N=" + defineArgCount(7, 71, 555));
            Integer[] arr = { 1, 2, 3, 4, 5, 6, 7 };
            System.out.println("N=" + defineArgCount(arr));
            System.out.println(defineArgCount());
            // defineArgCount(arr, arr); // ошибка компиляции
            // defineArgCount(71, arr); // ошибка компиляции
          }
}
В результате выполнения этой программы будет выведено:
arg:7  arg:71  arg:555  N=3
arg:1  arg:2  arg:3  arg:4  arg:5  arg:6  arg:7  N=7
No
 arg 0
В примере приведен простейший метод с переменным числом параметров. 
Метод defineArgCount() выводит все переданные ему аргументы и возвраща-
ет их количество. При передаче параметров в метод из них автоматически со-
здается массив. Второй вызов метода в примере позволяет передать в метод 
массив. Метод может быть вызван и без аргументов.

КЛАССЫ И ОБЪЕКТЫ
75
Чтобы передать несколько массивов в метод по ссылке, следует использо-
вать следующее объявление:
methodName(Тип[ ]... args) { }
Методы с переменным числом аргументов могут быть перегружены:
void 
methodName(Integer...args) { }
void
 methodName(int x1, int x2) { }
Недопустимый способ:
void 
methodName(Integer ... args) { }
void 
methodName(Integer[ ] args) { }
В следующем примере приведены три перегруженных метода и несколько ва-
риантов их вызова. Отличительной чертой является возможность метода с аргу-
ментом Object… args принимать не только объекты, но и массивы:
/* # 16 # передача массивов # DemoOverload.java */
package
 by.bsu.overload;
public
 class DemoOverload {
          public static void printArgCount(Object... args) { // 1
                    System.out.println("Object args: " + args.length);
          }
          public static void printArgCount(Integer[ ]...args){ // 2
                    System.out.println("Integer[ ] args: " + args.length);
          }
          public static void printArgCount(int... args) { // 3
                    System.out.print("int args: " + args.length);
          }
          public static void main(String[ ] args) {
                    Integer[] i = { 1, 2, 3, 4, 5 };
                    printArgCount(7, "No", truenull);
                    printArgCount(i, i, i);
                    printArgCount(i, 4, 71);
                    printArgCount(i); // будет вызван метод 1
                    printArgCount(5, 7);
                    // printArgCount(); // неопределенность при перегрузке!
          }
}
В результате будет выведено:
Object args: 4
Integer[] args: 3
Object args: 3
Object args: 5
int args: 2

ОСНОВЫ JAVA
76
При передаче в метод printArgCount() единичного массива i компи лятор 
отдает предпочтение методу с параметром Object… args. Так как имя массива 
является  объектной  ссылкой,  указанный  параметр  будет  ближайшим.  Метод 
с параметром Integer[]…args не вызывается, потому что ближайшей объектной 
ссылкой для него будет Object[]…args. Метод с параметром Integer[]…args бу-
дет вызван для единичного массива только в случае отсутствия метода с пара-
метром Object…args.
При вызове метода без параметров возникает неопределенность из-за не-
возможности однозначного выбора.
Не существует также ограничений и на переопределение подобных методов.
Единственным ограничением является то, что параметр вида Тип… args 
должен быть единственным и последним в объявлении списка параметров метода, 
то есть записи вида: (Тип1… args, Тип2 obj) и (Тип1… args, Тип2… args) при-
ведут к ошибке компиляции.
Перечисления
Типобезопасные перечисления (typesafe enums) в Java представляют собой 
классы и являются подклассами абстрактного класса java.lang.Enum. Вместо 
слова class при описании перечисления используется слово enum. При этом объ-
екты перечисления инициализируются прямым объявлением без помощи опера-
тора new. При инициализации хотя бы одного перечисления происходит иници-
ализация всех без исключения оставшихся элементов данного перечисления.
В качестве простейшего применения перечисления можно рассмотреть сле-
дующий код:
/* # 17 # применение перечисления # MusicStyle.java # MelomanRunner.java */
package 
by.bsu.enums;
public
 enum MusicStyle {
          JAZZCLASSICROCKBLUES
}
package 
by.bsu.enums;
public
 class MelomanRunner {
          public static void main(String[ ] args) {
                    MusicStyle ms = MusicStyle.CLASSIC// инициализация
                    System.out.print (ms);
                    switch (ms) {
                      case JAZZ:
                              System.out.println(" is Jazz");
                              break;
                      case CLASSIC:
                              System.out.println(" is Classic");
                              break;

КЛАССЫ И ОБЪЕКТЫ
77
                      case ROCK:
                              System.out.println(" is Rock");
                              break;
                      default:
                              System.out.println(" Unknown music style: " + ms);
                    }
          }
}
В операторах case используются константы без уточнения типа перечисле-
ния, так как его тип определен в switch.
Перечисление как подкласс класса Enum может содержать поля, конструкто-
ры  и  методы,  реализовывать  интерфейсы.  Каждый  элемент  enum  может 
использо вать методы:
static enumType[] values() — возвращает массив, содержащий все элемен-
ты перечисления в порядке их объявления;
static > T valueOf(Class enumType, String arg) — 
создает элемент перечисления, соответствующий заданному типу и значению 
передаваемой строки;
static enumType valueOf(String arg) — создает элемент пере числения, со-
ответствующий значению передаваемой строки;
int ordinal() — возвращает позицию элемента перечисления;
String name() — возвращает имя элемента;
int compareTo(T obj) — сравнивает элементы на больше-меньше либо равно.
А именно:
MusicStyle ms = MusicStyle.valueOf("RocK".toUpperCase());
Класс перечисления может содержать методы, и, следовательно, экземпляры 
перечисления могут к этим методам обращаться.
/* # 18 # объявление перечисления с методом # Shape.java */
package 
by.bsu.enums;
public
 enum Shape {
         RECTANGLETRIANGLECIRCLE;
         // метод класса перечисления
         public double defineSquare(double ... x) {
                  // проверка параметров
                  switch (this) {
                    case RECTANGLE:
                           return x[0] * x[1];
                    case TRIANGLE:
                           return x[0] * x[1] / 2;
                    case CIRCLE:

ОСНОВЫ JAVA
78
 
return
 Math.pow(x[0], 2) * Math.PI
default
:
 
throw
 new EnumConstantNotPresentException(this.getDeclaringClass(),this.name());
}
}
}
/* # 19 # применение перечисления # ShapeRunner.java */
package 
by.bsu.enums;
public
 class ShapeRunner {
public
 static void main(String args[ ]) {
double
 x = 2, y = 3;
Shape sh;
sh = Shape.RECTANGLE;
System.out.printf("%10s = %5.2f%n", sh, sh.defineSquare (x, y));
sh = Shape.TRIANGLE;
System.out.printf("%10s = %5.2f%n", sh, sh.defineSquare (x, y));
sh = Shape.CIRCLE;
System.out.printf("ё %10s = %5.2f%n", sh, sh.defineSquare (x));
}
}
В результате будет выведено:
RECTANGLE = 6,00
    TRIANGLE = 3,00
       CIRCLE = 12,57
Каждый из элементов перечисления в данном случае содержит арифметиче-
скую операцию, ассоциированную с методом defineSquare(). Без throw дан-
ный код не будет компилироваться, так как компилятор не исключает появле-
ния неизвестного элемента. Данная инструкция позволяет указать на возмож-
ную ошибку при появлении необъявленной фигуры. Поэтому и при введении 
нового элемента желательно добавлять соответствующий ему case.
Перечисление является классом, поэтому в его теле можно объявлять кроме 
методов также поля и конструкторы. Все конструкторы вызываются автомати-
чески при инициализации любого из элементов. Конструктор не может быть 
объявлен со спецификаторами public и protected, так как не вызывается явно 
и перечисление не может быть суперклассом. Поля перечисления используют-
ся для сохранения дополнительной информации, связанной с его элементом.
/* # 20 # конструкторы и члены перечисления # TaxiStation.java # TaxiRunner.java */
package 
by.bsu.enums;
public
 enum TaxiStation {
MERCEDES(10), TOYOTA(7), VOLVO;

КЛАССЫ И ОБЪЕКТЫ
79
          private int freeCabs; // поле класса перечисления
          TaxiStation() { // конструктор класса перечисления
          }
          TaxiStation(int cabs) { // конструктор класса перечисления
                    freeCabs = cabs;
          }
          public int getFreeCabs() {
                    return freeCabs;
          }
          public void setFreeCabs(int cabs) {
                    freeCabs = cabs;
          }
          @Override
          public String toString() {
                    return String.format("%s : free cabs = %d", name(), freeCabs); 
          }
}
package
 by.bsu.enums;
public
 class TaxiRunner {
          public static void main(String[ ] args) {
                 TaxiStation ts = TaxiStation.valueOf(TaxiStation.class,"Volvo".toUpperCase());
                 System.out.println(ts + " : ordinal -> " + ts.ordinal());
                 ts.setFreeCabs(3);
                 TaxiStation[ ] station = TaxiStation.values();
                 for (TaxiStation element : station) {
                           System.out.println(element);
                 }
          }

В результате будет выведено:
VOLVO
: free cabs = 0: ordinal -> 2
MERCEDES: free cabs = 10
TOYOTA: free cabs = 7
VOLVO
: free cabs = 3
Метод  toString()  реализован  в  классе  Enum  для  вывода  элемента  в  виде 
строки. Если переопределить метод toString() в конкретной реализации пере-
числения, то можно выводить не только значение элемента, но и значения его 
полей, то есть предоставить полную информацию об объекте, как и определя-
ется контрактом метода.
Однако на перечисления накладывается целый ряд ограничений.
Им запрещено:
•  быть суперклассами;
•  быть подклассами;
•  быть абстрактными;
•  создавать экземпляры, используя ключевое слово new.

ОСНОВЫ JAVA
80
Immutable
Если в системе необходим объект, внутреннее состояние которого нельзя 
изменить, то процедура реализации такой задачи представляется в виде:
/* # 21 # класс для создания неизменяемых объектов # ImmutableObject.java */
package
 by.bsu.immutable;
public
 class ImmutableObject {
    private String name;
    private int id;
    public ImmutableObject (String name, int id) {
        this.name = name;
        this.id = id;
    }
    public int getName() {
        return name;
    }
    public int getId() {
        return id;
    }
}
Такой объект от создания и до уничтожения не может быть изменен, что 
уменьшает затраты на безопасность при использовании в конкурирующих опе-
рациях. Классов с неизменяемым внутренним состоянием в стандартной реа-
лизации Java достаточно много. Следует вспомнить класс String.
Класс с поведением Immutable, тем не менее, может содержать методы для 
создания объекта того же типа с внутренним состоянием, отличающимся от ис-
ходного, что оправданно с точки зрения ресурсов, только если такие изменения 
происходят не слишком часто.
Декомпозиция
Корпоративные  информационные  системы  предоставляют  пользователю 
огромное количество сервисов и манипулируют очень большим количеством 
самой разнообразной информации. В разработке таких сложных и многообраз-
ных  систем  участвуют  зачастую  сотни  программистов-разработчиков.  Такие 
системы состоят из большого количества подсистем и программных модулей, 
которые взаимодействуют между собой через ограниченное число интерфей-
сов (методов). Главное же заключается в том, что система состоит из сотен ты-
сяч (миллионов) строк кода, не может создаваться, существовать, развиваться 
и поддерживаться, если при ее разработке не использовались принципы объ-
ектно-ориентированного программирования, в частности, декомпозиция.

КЛАССЫ И ОБЪЕКТЫ
81
Под  декомпозицией  следует  понимать  определение  физических  и  логиче-
ских  сущностей,  а  также  принципов  их  взаимодействия  на  основе  анализа 
предметной области создаваемой системы.
Все  системы  состоят  из  классов.  Все  классы  системы  взаимодействуют 
с теми или иными классами этой же системы.
Объяснение принципов декомпозиции можно рассмотреть на простейшем 
примере. Пусть требуется решить следующую задачу: создать систему, позво-
ляющую умножать целочисленные матрицы друг на друга.
Начинающий программист, знающий о том, что существуют классы, кон-
структоры  и  методы,  может  предложить  решение  поставленной  проблемы 
в следующем виде:
/* # 22 # произведение двух матриц # Matrix.java */
public
 class Matrix {
     private int[ ][ ] a;
     private int n;
     private int
 m;
  public
 Matrix(int nn, int mm) {
     n = nn;
     m = mm;
     // создание и заполнение случайными значениями
     a = new int[n][m];
     for (int i = 0; i < n; i++) {
         for (int j = 0; j < m; j++) {
             a[i][j] = (int)(Math.random() * 5);
         }
    }
    show();
  }
  public
 Matrix(int nn, int mm, int k) {
     n = nn;
     m = mm;
     a = new int[n][m];
     for (int i = 0; i < n; i++) {
         for (int j = 0; j < m; j++) {
             a[i][j] = k;
         }
     }
     if(k != 0) { 
     show();
     }
  }
  public
 void show() {
     System.out.println("Maтрица : " + a.length + " на " + a[0].length);
     for (int i = 0; i < a.length; i++) {
         for (int j = 0; j < a[0].length; j++) {
             System.out.print(a[i][j] + " ");

ОСНОВЫ JAVA
82
        }
              System.out.println();
    }
}
public
 static void main(String[ ] args) {
   int n = 2, m = 3, l = 4;
   Matrix p = new Matrix(n, m);
   Matrix q = new Matrix(m, l);
   Matrix r = new Matrix(n, l, 0);
     for (int i = 0; i < p.a.length; i++) {
        for (int j = 0; j < q.a[0].length; j++) {
            for (int k = 0; k < p.a[0].length; k++) {
              r.a[i][j] += p.a[i][k] * q.a[k][j];
            }
        }
    }
   System.out.println("Произведение матриц: "); 
   r.show();
  }
}
Программа полностью работоспособна, но следует взглянуть на нее внима-
тельнее:
•  создан только один класс; маловато, но и задача невелика;
•  класс  обладает  лишними  полями,  значения  которых  зависят  от  значений 
других полей;
•  в классе объявлены два конструктора, оба выделяют память под матрицу 
и заполняют ее элементами, переданными или сгенерированными. Оба кон-
структора решают похожие задачи и не проверяют на корректность входные 
значения и решают слишком обширные задачи;
•  определен метод show() для вывода матрицы на консоль, что ограничивает 
способы общения класса с внешними для него классами;
•  задача умножения решается в методе main(), и класс является одноразовым, 
т. е. для умножения двух других матриц придется код умножения копиро-
вать в другое место;
•  реализован  только  основной  положительный  сценарий,  например,  не  вы-
полняется проверка размерности при умножении, и, как следствие, отсутст-
вует реакция приложения на некорректные данные.
Ниже приведена попытка переработки (рефакторинга) созданного приложе-
ния таким образом, чтобы существовала возможность поддержки и расшире-
ния возможности системы при возникновении сопутствующих задач.
/* # 23 # класс хранения матрицы # Matrix.java */
package
 by.bsu.task.entity;
import
 by.bsu.task.exceptions.MatrixException;
public
 class Matrix {

КЛАССЫ И ОБЪЕКТЫ
83
    private int[ ][ ] a;
    public Matrix(int n, int m) throws MatrixException {
           // проверка на отрицательные значения размерности матрицы
           if ((n < 1) || (m < 1)) {
                       throw new MatrixException();
           }
           a = new int[n][m];
    }
    public int getVerticalSize() {
           return a.length;
    }
    public int getHorizontalSize() {
           return a[0].length;
    }
    public int getElement(int i, int j) throws MatrixException {
       if (checkRange(i, j)) { // проверка i и j 
           return a[i][j];
       }
           throw new MatrixException();
    }
    public void setElement(int i, int j, int value) throws MatrixException {
       if (checkRange(i, j)) { // проверка i и j 
          a[i][j] = value;
       }
           throw new MatrixException();
    }
    @Override
    public String toString() {
      StringBuilder s = new StringBuilder("\nMatrix : " + a.length + "x" + a[0].length + "\n");
      for (int [ ] row : a) {
          for (int value : row) {
              s.append(value + " ");
          }
          s.append("\n");
      }
      return s.toString();
    }
    // проверка возможности выхода за пределы матрицы 
    private boolean checkRange(int i, int j) {
        if ( i < 0 || i > a.length - 1 || j < 0 || j > a[0].length - 1) {
            return false;
        } else {
            return true;
        }
    }
}
В классе Matrix объявлен private-метод checkRange(int i, int j) для проверки 
параметров на предельные допустимые значения во избежание невынужденных 

ОСНОВЫ JAVA
84
ошибок.  Однако  условный  оператор  if  в  этом  методе  выглядит  запутанным, 
во-первых, нарушая правило положительного сценария, то есть разумно ожи-
дать, что параметры метода с индексами элемента матрицы будут корректными, 
и, исходя из этого, строить условие, а в представленном варианте все наоборот; 
во-вторых, при значении true в условии оператора метод возвращает значение 
false, что выглядит противоречивым.
Метод следует переписать в виде
private
 boolean checkRange(int i, int j) {
          if ( i >= 0 && i < a.length && j >= 0 && j < a[0].length ) {
                      return true;
          } else {
                      return false;
          }
}
заменив условие в операторе на противоположное и возвращая непротиворе-
чащее результате значение.
/* # 24 # класс-создатель матрицы # MatrixCreator.java */
package
 by.bsu.task.creator;
import
 by.bsu.task.entity.Matrix;
import
 by.bsu.task.exceptions.MatrixException;
public
 class MatrixCreator {
    public void fillRandomized(Matrix t, int start, int end) {
           int v = t.getVerticalSize();
           int h = t.getHorizontalSize();
      for(int i = 0; i < v; i++) {
         for(int j = 0; j < h; j++) {
           try {
                        int value = (int)(Math.random() * (end - start) + start));
                        t.setElement(i, j, value); 
           } catch (MatrixException e) {
                    /* в данном случае exception невозможен, поэтому обработка отсутствует */
           }
       }
    }
  }
           // public void fillFromFile(Matrix t, File f) { /* код*/ }
           // public void fillFromStream(Matrix t, InputStream input) { /* код*/ }
           // public void fillFromDataBase(Matrix t, Connection conn) { /* код*/ }
}
Инициализация элементов матрицы различными способами вынесена в от-
дельный  класс,  методы  которого  могут  в  зависимости  от  условий  извлекать 
значения для инициализации элементов из различных источников.

КЛАССЫ И ОБЪЕКТЫ
85
/* # 25 # произведение двух матриц # Multiplicator.java */
package
 by.bsu.task.action;
import
 by.bsu.task.entity.Matrix;
import
 by.bsu.task.exceptions.MatrixException;
public
 class Multiplicator {
    public Matrix multiply(Matrix p, Matrix q) throws MatrixException {
        int v = p.getVerticalSize();
        int h = q.getHorizontalSize();
        int temp = p.getHorizontalSize();
// проверка возможности умножения
        if (temp != q.getVerticalSize()) {
throw
 new MatrixException(); // Incompatible matrices
        }
// создание матрицы результата
        Matrix result = new Matrix(v, h);
        try {   
// умножение
for
 (int i = 0; i < v; i++) {
for
 (int j = 0; j < h; j++) {
int
 value = 0;
for
 (int k = 0; k < temp; k++) {
value += p.getElement(i, k) * q.getElement(k, j);
}
result.setElement(i, j, value);
}
}    
        } catch (MatrixException e) {
// exception невозможен по логике кода, 
// поэтому обработка опущена
        }
 return result;
    }
}
Все манипуляции взаимодействия объектов-матриц между собой и другими 
объектами должны быть сгруппированы и вынесены в отдельные логические 
классы, что повышает возможность другому разработчику быстро разобраться 
в смысле класса и модернизировать его.
/* # 26 # исключительная ситуация при индексировании объекта-матрицы # 
MatrixException.java */
package
 by.bsu.task.exceptions;
public
 class MatrixException extends Exception {}
Создание собственных исключений позволяет разработчику при их возник-
новении быстро локализовать и исправить ошибку.

ОСНОВЫ JAVA
86
/* # 27 # класс, запускающий приложение # Runner.java */
package
 by.bsu.task;
import
 by.bsu.task.action.Multiplicator;
import
 by.bsu.task.creator.MatrixCreator;
import
 by.bsu.task.entity.Matrix;
import
 by.bsu.task.exceptions.MatrixException;
public
 class Runner {
    public static void main(String[ ] args) {
        try {
            Matrix p = new Matrix(2, 3);
            MatrixCreator.fillRandomized(p, 2, 8);
            System.out.println("Matrix first is: " + p);
            Matrix q = new Matrix(3, 4);
            MatrixCreator.fillRandomized(q, 2, 7);
            System.out.println("Matrix second is: " + q);
            Multiplicator mult = new Multiplicator();
            System.out.println("Matrices product is " + mult.multiply(p, q));
        } catch (MatrixException ex) {
            System.err.println("Error of creating matrix " + ex);
        }
    }
}
Так  как  значения  элементам  матрицы  присваиваются  при  помощи  метода  
Math.random(), то одним из вариантов выполнения кода может быть следующий:
Matrix first is:
Matrix: 2x3
3 4 7
4 7 2
Matrix second is:
Matrix: 3x4
3 3 6 6
5 6 5 5
4 3 3 4
Matrices product is
Matrix: 2x4
57 54 59 66
55 60 65 67
Выше был приведен пример простейшей декомпозиции. При разработке при-
ложений любой сложности всегда следует производить анализ предметной обла-
сти, определять абстракции и разделять задачу на логические взаимодействую-
щие части. Тем не менее границы, отделяющие хороший дизайн приложения 
от посредственного, достаточно размыты и зависят от общего уровня компе-
тентности команды разработчиков и правил, принятых в проекте.

КЛАССЫ И ОБЪЕКТЫ
87
Рекомендации при проектировании классов
При создании класса следует давать ему такое имя, чтобы его пользователю 
была понятна роль класса.
Класс должен быть разработан так, чтобы внесение в него изменений было 
относительно простой задачей.
Каждый класс должен иметь простое назначение.
Код  конструктора  должен  заниматься  только  инициализацией  объекта. 
Следует  избегать  вызовов  из  конструктора  других  методов,  за  исключением  
final. Метод может быть переопределен в подклассе и исказить процесс иници-
ализации объекта.
Если класс отвечает за хранение информации, то функциональность работы 
с этой информацией должна быть базовой. Манипулированием информацией через 
объект должны заниматься другие классы, которых может оказаться очень много.
Использовать инкапсуляцию нестатических и неконстантных полей.
Применять для доступа к полям классов, хранящих информацию, коррект-
ные методы типа getset, is, а также желательно реализовать методы equals(), 
hashCode(), clone(), toString() и имплементировать интерфейсы Comparable 
и Serializable.
Если разрабатываемый класс кажется сложным, следует разбить его на не-
сколько простых.
По возможности избегать слишком длинных методов. От тридцати строк — 
длинный  метод.  Следует  разбить  метод  на  несколько,  или  даже  создать  для 
этой цели новый класс.
Если метод используется только другими методами этого класса, следует 
объявлять его как private.
Определить и распределить по разным классам функциональности, которые 
могут изменяться в процессе разработки, от тех, которые будут постоянными.
Хороший дизайн кода отличается высоким уровнем декомпозиции.
Если в разных участках класса или нескольких классов востребован один 
и тот же фрагмент кода, следует выделить его в отдельный метод.
Избегать длинного списка аргументов. Приближаясь к числу семь, список 
аргументов  становится  не  воспринимаемым  при  чтении.  Возможно,  следует 
объединить группы аргументов в новый тип данных.
Не использовать «волшебные числа», «волшебные строки». Логичнее выне-
сти их за пределы кода, например, в файл.
Задания к главе 3
Вариант А
Создать классы, спецификации которых приведены ниже. Определить кон-
структоры и методы setТип(), getТип(), toString(). Определить дополнительно 

ОСНОВЫ JAVA
88
методы в классе, создающем массив объектов. Задать критерий выбора данных 
и вывести эти данные на консоль. В каждом классе, обладающем информацией, 
должно быть объявлено несколько конструкторов.
1.  Student:  id,  Фамилия,  Имя,  Отчество,  Дата  рождения,  Адрес,  Телефон, 
Факультет, Курс, Группа.
  Создать массив объектов. Вывести:
a)  список студентов заданного факультета;
b)  списки студентов для каждого факультета и курса;
c)  список студентов, родившихся после заданного года;
d)  список учебной группы.
2.  Customer: id, Фамилия, Имя, Отчество, Адрес, Номер кредитной карточки, 
Номер банковского счета.
  Создать массив объектов. Вывести:
a)  список покупателей в алфавитном порядке;
b)  список  покупателей,  у  которых  номер  кредитной  карточки  находится 
в заданном интервале.
3.  Patient: id, Фамилия, Имя, Отчество, Адрес, Телефон, Номер медицинской 
карты, Диагноз.
  Создать массив объектов. Вывести:
a)  список пациентов, имеющих данный диагноз;
b)  список пациентов, номер медицинской карты которых находится в за-
данном интервале.
4.   Abiturient: id, Фамилия, Имя, Отчество, Адрес, Телефон, Оценки. 
Создать массив объектов. Вывести:
a)  список абитуриентов, имеющих неудовлетворительные оценки;
b)  список абитуриентов, у которых сумма баллов выше заданной;
c)  выбрать  заданное  число  n  абитуриентов,  имеющих  самую  высокую 
сумму баллов (вывести также полный список абитуриентов, имеющих 
полупроходную сумму).
5.   Book: id, Название, Автор (ы), Издательство, Год издания, Количество стра-
ниц, Цена, Тип переплета.
Создать массив объектов. Вывести:
a)  список книг заданного автора;
b)  список книг, выпущенных заданным издательством;
c)  список книг, выпущенных после заданного года.
6.  House:  id,  Номер  квартиры,  Площадь,  Этаж,  Количество  комнат,  Улица, 
Тип здания, Срок эксплуатации.
Создать массив объектов. Вывести:
a)  список квартир, имеющих заданное число комнат;
b)  список  квартир,  имеющих  заданное  число  комнат  и  расположенных 
на этаже, который находится в заданном промежутке;
c)  список квартир, имеющих площадь, превосходящую заданную.

КЛАССЫ И ОБЪЕКТЫ
89
7.  Phone:  id,  Фамилия,  Имя,  Отчество,  Адрес,  Номер  кредитной  карточки, 
Дебет, Кредит, Время городских и междугородных разговоров.
Создать массив объектов. Вывести:
a)  сведения об абонентах, у которых время внутригородских разговоров 
превышает заданное;
b)  сведения об абонентах, которые пользовались междугородной связью;
c)  сведения об абонентах в алфавитном порядке.
8.  Car: id, Марка, Модель, Год выпуска, Цвет, Цена, Регистрационный номер.
Создать массив объектов. Вывести:
a)  список автомобилей заданной марки;
b)  список автомобилей заданной модели, которые эксплуатируются боль-
ше n лет;
c)  список автомобилей заданного года выпуска, цена которых больше ука-
занной.
9.  Product:  id,  Наименование,  UPC,  Производитель,  Цена,  Срок  хранения, 
Количество.
Создать массив объектов. Вывести:
a)  список товаров для заданного наименования;
b)  список товаров для заданного наименования, цена которых не превос-
ходит заданную;
c)  список товаров, срок хранения которых больше заданного.
10. Train: Пункт назначения, Номер поезда, Время отправления, Число мест 
(общих, купе, плацкарт, люкс).
Создать массив объектов. Вывести:
a)  список поездов, следующих до заданного пункта назначения;
b)  список поездов, следующих до заданного пункта назначения и отправ-
ляющихся после заданного часа;
c)  список  поездов,  отправляющихся  до  заданного  пункта  назначения 
и имеющих общие места.
11. Bus:  Фамилия  и  инициалы  водителя,  Номер  автобуса,  Номер  маршрута, 
Марка, Год начала эксплуатации, Пробег.
Создать массив объектов. Вывести:
a)  список автобусов для заданного номера маршрута;
b)  список автобусов, которые эксплуатируются больше заданного срока;
c)  список автобусов, пробег у которых больше заданного расстояния.
12. Airline: Пункт назначения, Номер рейса, Тип самолета, Время вылета, Дни 
недели.
Создать массив объектов. Вывести:
a)  список рейсов для заданного пункта назначения;
b)  список рейсов для заданного дня недели;
c)  список  рейсов  для  заданного  дня  недели,  время  вылета  для  которых 
больше заданного.

ОСНОВЫ JAVA
90
Вариант В
Реализовать методы сложения, вычитания, умножения и деления объектов (для 
тех классов, объекты которых могут поддерживать арифметические действия).
1.  Определить класс Дробь (Рациональная Дробь) в виде пары чисел m и n
Объявить и инициализировать массив из k дробей, ввести/вы вести значе-
ния для массива дробей. Создать массив/список/множество объектов и пе-
редать его в метод, который изменяет каждый элемент массива с четным 
индексом путем добавления следующего за ним элемента.
2.  Определить класс Комплекс. Создать массив/список/множество размерно-
сти n из комплексных координат. Передать его в метод, который выполнит 
сложение/умножение его элементов.
3.  Определить класс Квадратное уравнение. Реализовать методы для поиска 
корней, экстремумов, а также интервалов убывания/возрастания. Создать 
массив/список/множество объектов и определить наибольшие и наимень-
шие по значению корни.
4.  Определить класс Полином степени n. Объявить массив/список/множество 
из m полиномов и определить сумму полиномов массива.
5.  Определить  класс  Интервал  с  учетом  включения/невключения  концов. 
Создать методы по определению пересечения и объединения интервалов, 
причем  интервалы,  не  имеющие  общих  точек,  пересекаться/объединятся 
не могут. Объявить массив/список/множество и n интервалов и определить 
расстояние между самыми удаленными концами.
6.  Определить  класс  Точка  на  плоскости  (в  пространстве)  и  во  времени. 
Задать  движение  точки  в  определенном  направлении.  Создать  методы 
по  определению  скорости  и  ускорения  точки.  Проверить  для  двух  точек 
возможность пересечения траекторий. Определить расстояние между дву-
мя точками в заданный момент времени.
7.  Определить класс Треугольник на плоскости. Определить площадь и пе-
риметр треугольника. Создать массив/список/множество объектов и подсчи-
тать количество треугольников разного типа (равносторонний, равнобедрен-
ный, прямоугольный, произвольный). Определить для каждой группы наи-
больший и наименьший по площади (периметру) объект.
8.  Определить класс Четырехугольник на плоскости. Определить площадь 
и периметр четырехугольника. Создать массив/список/множество объектов 
и подсчитать количество четырехугольников разного типа (квадрат, прямоу-
гольник, ромб, произвольный). Определить для каждой группы наибольший 
и наименьший по площади (периметру) объект.
9.  Определить класс Окружность на плоскости. Определить площадь и пери-
метр.  Создать  массив/список/множество  объектов  и  определить  группы 
окружностей,  центры  которых  лежат  на  одной  прямой.  Определить  наи-
больший и наименьший по площади (периметру) объект.

КЛАССЫ И ОБЪЕКТЫ
91
10. Определить класс Прямая на плоскости (пространстве). Определить точки 
пересечения прямой с осями координат. Определить координаты пересече-
ния двух прямых. Создать массив/список/множество объектов и определить 
группы параллельных прямых.
Вариант С
1.  Определить  класс  Полином  c  коэффициентами  типа  Рациональная 
Дробь. Объявить массив/список/множество из n полиномов и определить 
сумму полиномов массива.
2.  Определить класс Прямая на плоскости (в пространстве), параметры кото-
рой задаются с помощью Рациональной Дроби. Определить точки пересе-
чения  прямой  с  осями  координат.  Определить  координаты  пересечения 
двух  прямых.  Создать  массив/список/множество  объектов  и  определить 
группы параллельных прямых.
3.  Определить класс Полином с коэффициентами типа Комплексное число
Объявить массив/список/множество из m полиномов и определить сумму 
полиномов массива.
4.  Определить  класс  Дробь  в  виде  пары  (m,  n)  с  коэффициентами  типа 
Комплексное число. Объявить и инициализировать массив из k дробей, вве-
сти/вы вести значения для массива дробей. Создать массив/список/множест-
во объектов и передать его в метод, который изменяет каждый элемент мас-
сива с четным индексом путем добавления следующего за ним элемента.
5.  Определить  класс  Комплекс,  действительная  и  мнимая  часть  которой 
представлены в виде Рациональной Дроби. Создать массив/список/мно-
жество размерности n из комплексных координат. Передать его в метод, ко-
торый выполнит сложение/умножение его элементов.
6.  Определить класс Окружность на плоскости, координаты центра которой 
задаются с помощью Рациональной Дроби. Определить площадь и пери-
метр.  Создать  массив/список/множество  объектов  и  определить  группы 
окружностей,  центры  которых  лежат  на  одной  прямой.  Определить  наи-
больший и наименьший по площади (периметру) объект.
7.  Определить  класс  Точка  в  пространстве,  координаты  которой  задаются 
с помощью Рациональной Дроби. Создать методы по определению рас-
стояния между точками и расстояния до начала координат. Проверить для 
трех точек возможность нахождения на одной прямой.
8.  Определить  класс  Точка  в  пространстве,  координаты  которой  задаются 
с помощью Комплексного числа. Создать методы по определению рассто-
яния между точками и расстояния до начала координат.
9.  Определить  класс  Треугольник  на  плоскости,  вершины  которого  имеют 
тип Точка. Определить площадь и периметр треугольника. Создать массив/
список/множество объектов и подсчитать количество треугольников разного 

ОСНОВЫ JAVA
92
типа  (равносторонний,  равнобедренный,  прямоугольный,  произвольный). 
Определить для каждой группы наибольший и наименьший по площади (пе-
риметру) объект.
10. Определить класс Четырехугольник на плоскости, вершины которого имеют 
тип Точка. Определить площадь и периметр четырехугольника. Создать мас-
сив/список/множество объектов и подсчитать количество четырехугольников 
разного типа (квадрат, прямоугольник, ромб, произвольный). Определить для 
каждой группы наибольший и наименьший по площади (периметру) объект.
11. Определить класс Вектор. Реализовать методы инкремента, декремента, ин-
дексирования. Определить массив из m объектов. Каждую из пар векторов 
передать  в  методы,  возвращающие  их  скалярное  произведение  и  длины. 
Вычислить и вывести углы между векторами.
12. Определить  класс  Вектор.  Реализовать  методы  для  вычисления  модуля 
вектора,  скалярного  произведения,  сложения,  вычитания,  умножения 
на константу. Объявить массив объектов. Написать метод, который для за-
данной пары векторов будет определять, являются ли они коллинеарными 
или ортогональными.
13. Определить класс Вектор в R
3
. Реализовать методы для проверки векторов 
на  ортогональность,  проверки  пересечения  неортогональных  векторов, 
сравнения  векторов.  Создать  массив  из  m  объектов.  Определить  компла-
нарные векторы.
14. Определить класс Булева матрица (BoolMatrix). Реализовать методы для 
логического  сложения  (дизъюнкции),  умножения  и  инверсии  матриц. 
Реализовать методы для подсчета числа единиц в матрице и упорядочения 
строк в лексикографическом порядке.
15. Построить класс Булев вектор (BoolVector). Реализовать методы для вы-
полнения  поразрядных  конъюнкции,  дизъюнкции  и  отрицания  векторов, 
а также подсчета числа единиц и нулей в векторе.
16. Определить класс Множество символов. Реализовать методы для опре-
деления  принадлежности  заданного  элемента  множеству;  пересечения, 
объединения, разности двух множеств. Создать методы сложения, вычи-
тания, умножения (пересечения), индексирования, присваивания. Создать 
массив объектов и передавать пары объектов в метод другого класса, ко-
торый  строит  множество,  состоящее  из  элементов,  входящих  только 
в одно из заданных множеств.
17. Определить  класс  Нелинейное  уравнение  для  двух  переменных. 
Реализовать метод определения корней методом биекции.
18. Определить  класс  Определенный  интеграл  с  аналитической  подынтег-
ральной функцией. Создать методы для вычисления значения по формуле 
левых прямоугольников, по формуле правых прямоугольников, по формуле 
средних  прямоугольников,  по  формуле  трапеций,  по  формуле  Симпсона 
(параболических трапеций).

КЛАССЫ И ОБЪЕКТЫ
93
19. Определить класс Массив. Создать методы сортировки: об менная сорти-
ровка (метод пузырька); обменная сортировка «Шейкер-сортировка», сор-
тировка посредством выбора (метод простого выбора), сортировка вставка-
ми:  метод  хеширования  (сортировка  с  вычислением  адреса),  сортировка 
вставками (метод простых вставок), сортировка би нарного слияния, сорти-
ровка Шелла (сортировка с убывающим шагом).
Тестовые задания к главе 3
Вопрос 3.1.
Какие  описания  класса  содержат  синтаксическую  ошибку?  Код  написан 
в файле Quest1.java (3)
1)  public class Quest1 {}
2)  public static class Quest1 {}
3)  public abstract final class Quest1 {}
4)  private class Quest1 {}
5)  final class Quest1 {}
Вопрос 3.2.
Выберите  правильное  утверждение,  подходящее  для  окончания  фразы 
«Константное поле может быть проинициализировано …» (3):
1)  только один раз;
2)  один раз при объявлении, а затем в конструкторе класса;
3)  в логическом блоке инициализации;
4)  в статическом блоке инициализации;
5)  при объявлении или в конструкторе класса.
Вопрос 3.3.
Дан код:
public class Quest3 {
 
public static int method () {
 
 
final int loc;
 
 
System.out.println (loc);//1
 
 
loc=4;//2
 
 
return loc+1;//3
 
}
 
public static void main (String [] args) {
 
 
method (); method (); method ();
 
 
System.out.println (method ());
 
}
}

ОСНОВЫ JAVA
94
Каким будет результат компиляции и запуска программы (1)?
1)  на консоль выведется число 4
2)  на консоль выведется число 0
3)  ошибка компиляции в строке 1
4)  ошибка компиляции в строке 2
5)  ошибка компиляции в строке 3
Вопрос 3.4.
Выберите утверждения, корректно характеризующие модификаторы досту-
па (2):
1)  статические  private-члены  класса  доступны  только  статическим  методам 
этого класса;
2)  статические public-члены классы доступны всем методам этого класса;
3)  protected-члены класса доступны подклассам другого пакета;
4)  поле  —  член  класса,  объявленное  без  модификатора  доступа,  доступно 
в классах другого пакета.
Вопрос 3.5.
Дан код:
public class Quest5 {
 
public Quest5 () {}
 
public Quest5 (int i) {this (i, i);}
 
public Quest5 (int i, int j) {this ();}
 
public static void main (String [] args) {
 
 
Quest5 q = new Quest5 (2,3); //1
 
}
}
Сколько конструкторов вызовется при создании объекта в строке 1 (1)?
1)  один;
2)  два;
3)  три;
4)  ошибка компиляции.
Вопрос 3.6.
Дан код (1):
public class Quest6 {
 
public void meth (Number obj) {System.out.print ("1");}
 
public void meth (Character obj) {System.out.print ("2");}
 
private static void meth (Integer obj) {System.out.print ("3");}

КЛАССЫ И ОБЪЕКТЫ
95
 
public void meth (int i) {System.out.print ("4");}
 
public void meth (double d) {System.out.print ("5");}
 
public static void main (String [] args) {
 
 
Quest6 q = new Quest6 ();
 
 
Number n = 67;
 
 
Integer i = 78;
 
 
q.meth (n);
 
 
q.meth (i);
 
}
}
Что выведется на консоль после компиляции и запуска этой программы?
1)  14
2)  11
3)  33
4)  44
5)  13
6)  ошибка компиляции
7)  ошибка выполнения
Вопрос 3.7.
Дан код:
public class Quest7 {
 
private T pole;
 
public Quest7 (T pole) {this.pole = pole;} //1
 
public void setPoleDefault () {pole.setTime (1000);} //2
 
public static void main (String [] args) {
 
 
Quest7 obj = new Quest7 (new Date ());//3
 
 
obj.setPoleDefault ();
 
}
}
Каким будет результат компиляции и запуска программы (1)?
1)  компиляция и запуск пройдут без ошибок
2)  ошибка компиляции в строке 1
3)  ошибка компиляции в строке 2
4)  ошибка компиляции в строке 3
Вопрос 3.8.
Укажите корректый способ создания экземпляра класса
public class Quest8 {}? (2)

ОСНОВЫ JAVA
1)  Quest8 obj = new Quest8 ()
2)  Quest8 obj = new Quest8 ()
3)  Quest8 obj = new Quest8 ()
4)  Quest8<…, Object> obj = new Quest8<…, Object> ()
5)  Quest8 obj = new Quest8 ()
6)  Quest8 obj = new Quest8 ()
Вопрос 3.9.
Дан код:
enum Numbers {ONETWOTHREEFOURFIVE}
public class Quest9 {
 
public static void main (String [] args) {
 
 
Numbers n1 = Numbers.ONE;
 
 
Numbers n2 = Numbers.ONE;//1
 
 
if (n1 == n2) {System.out.print ("true");}
 
 
else {System.out.print ("false");}
 
 
System.out.println (Numbers.FIVE.ordinal ());//2
 
}
}
Что выведется на консоль в результате компиляции и запуска приложения (1)?
1)  false4
2)  true4
3)  false5
4)  true5
5)  произойдет ошибка компиляции в строке 1
6)  произойдет ошибка компиляции в строке 2
Вопрос 3.10.
Выберите неправильные утверждения (3):
1)  перечисление является классом
2)  при объявлении перечисления его необходимо явно наследовать от класса 
java.lang.Enum
3)  в теле перечисления можно объявлять только методы
4)  конструктор перечисления может быть объявлен со спецификатором public

97


Достарыңызбен бөлісу:
1   2   3   4   5   6   7   8   9   ...   22




©engime.org 2024
әкімшілігінің қараңыз

    Басты бет