Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
0RBst7D3nn.doc
Скачиваний:
14
Добавлен:
30.04.2022
Размер:
694.78 Кб
Скачать

11.1. Инкапсуляция

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

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

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

final, public, private, protected, abstract и static.

Вложенные классы Java. Концепция вложенных, локальных и анонимных классов не была реализована в первой версии языка Java. Однако, начиная с версии 1.1, эта возможность становится доступной. Данные механизмы являются значительным шагом вперед по сравнению с возможностями С++. Вложенный класс в Java - это нестатический класс описанный внутри другого класса. Он может быть объявлен как private, protected или final abstract и не может иметь статических членов и инициализаторов, а также вложенных интерфейсов. Важно понимать, что ключевое слово static в языке Java определяет конструкцию верхнего уровня, которая включает в себя переменные класса (class variables), методы класса (class methods), а также классы верхнего (top level) уровня. Таким образом, для создания, например, переменной класса во вложенном классе ее описание необходимо разместить в объемлющем классе.

Имя вложенного класса недоступно за пределами объемлющей области, за исключением синтаксиса квалификации. Код вложенного класса имеет доступ (без синтаксиса квалификации) как к членам объемлющего класса, так и к членам объемлющей реализации (в данном случае член класса - это статический член класса, то есть имеющий отношение только к классу, а не к объекту этого класса; член реализации это нестатический член класса, определенный в рамках реализации).

Если класс определен как static внутри класса верхнего уровня, то он сам становится классом верхнего уровня. Данная конструкция позволяет организовать вторичные классы верхнего уровня по принципу логически связанных групп (такая организация во многом похожа на пакетирование). Вложенные классы верхнего уровня не имеют специального доступа к членам объемлющей реализации.

public class Collection {

Object array [ ] ;

int count = 0 ;

Collection (int size) {

array = new Object [size] ;

}

public void add (Object item) {

array [count++] = item ;

}

class Enumerator implements Enumeration {

int curr = count ;

}

public Enumerator elements ( ) {

return new Enumerator ( ) ;

}

}

Локальные классы Java.

Класс, описанный внутри блока или метода, также называется локальным. Его код имеет доступ ко всем локальным переменным этого блока и/или к параметрам метода. Например:

Enumeration getEnumeration (Object array[ ] ) {

int count = 0 ;

class M implements Enumeration {

public boolean hasMoreElements ( ) {

return count < array.length ;

}

}

return new M ( ) ;

}

Несмотря на кажущуюся ошибку, пример абсолютно верен. Дело в том, что в соответствии с правилами области действия объявлений языка Java любая переменная существует ровно до тех пор, пока активна хотя бы одна область действия, где она используется. Следовательно, переменная count будет доступна и сохранит свое значение в объекте класса M даже при выходе из метода getEnumeration.

Основным инструментом скрытия и инкапсуляции информации в обоих языках является класс. Однако в С++ это лишь один из возможных вариантов, поскольку классы можно вообще не использовать. В противоположность этому Java не оставляет выбора, так как программа может состоять только из классов.

Наследование в С++ представлено механизмом множественного наследования, модификаторами доступа для суперклассов, а также виртуальными и абстрактными суперклассами. В Java оно осуществляется за счет механизма одинарного наследования, интерфейсов и абстрактных классов.

Модификаторы доступа Java.

Система управления доступом в Java значительно проще, чем в С++. В Java отсутствуют модификаторы доступа для суперклассов и не поддерживается механизм уточнения доступа к члену суперкласса. Подход к управлению доступом в языке Java более последователен. Для этого используется модификаторы public, protected и private для описания классов верхнего уровня, вложенных классов, методов и данных. Модификатор public означает, что класс, метод или данные доступны объектам других классов в любой точке программы. В противоположность модификатору public модификатор private разрешает доступ к данным и методам только из текущего класса. Модификатор protected обеспечивает доступ к имени в субклассах данного класса, а также в классах, принадлежащих данному пакету. При отсутствии в описании модификатора доступа класс также становится доступным только для классов из того же пакета. Это относится и к методам и данным. Например:

public class wideScope { // wideScope доступен

// из любой части программы

protected int a; // переменная a доступна

// в hidden

}

class hidden extends wideScope { // hidden

// доступен только в рамках текущего пакета

private byte b; // b доступно только в hidden

}

Одинарное наследование и интерфейсы в Java.

Подход к созданию иерархии классов в языке Java значительно проще и последовательней (при разработке Java были учтены все проблемы С++). В Java отсутствует понятие виртуальных суперклассов и существует только одинарное наследование, которое, при отсутствии в языке каких-либо модификаторов доступа для суперклассов, выполняет роль именно расширения своего суперкласса. Другими словами, иерархия классов в Java представляет собой цепочку классов, где каждый класс расширяет свой непосредственный суперкласс, а вся информация распределена по всей цепочке наследования.

Помимо одинарного наследования, класс Java может реализовать один или более интерфейсов (множественное исполнение). Интерфейс - это набор констант и методов без реализации, которые должен реализовать класс, исполняющий данный интерфейс. Интерфейсу доступно множественное наследование других интерфейсов (исполнять их он не может). Под этим понимается то, что субинтерфейс наследует все методы и константы своих суперинтерфейсов. Класс, имплементирующий интерфейс, должен предоставить реализацию для всех методов и переменных, принадлежащих суперинтерфейсам данного интерфейса. Например:

interface Window {

void show ();

}

interface PanelWindow extends Window {

boolean eventHandler (Event evt);

}

public class Panel implements PanelWindow {

void show () {

}

boolean eventHandler (Event evt) {

...

}

};

Множественное имплементирование в сочетании с динамической проверкой типов представляет собой простую альтернативу множественному наследованию и виртуальным суперклассам в С++. Концепция одинарного наследования и множественного исполнения значительно упрощает процесс объектно-ориентированного проектирования, что приводит к повышению надежности кода и уменьшению времени разработки.

Абстрактные классы Java.

Понятие абстрактного класса в языке Java имеет много общего с аналогичным понятием в С++. Абстрактный класс - это класс, содержащий хотя бы один абстрактный метод, то есть метод без реализации. Этот метод может быть унаследован от абстрактного суперкласса или быть нереализованным методом одного из исполняемых интерфейсов. Объект абстрактного класса нельзя создать с помощью операции new или метода newinstance класса Class. Однако ссылку на такой объект можно использовать в качестве параметра или возвращаемого значения для метода, а также как тип при явном приведении.

Абстрактные классы во многом похожи на интерфейсы, но имеют несколько важных отличий. Абстрактный класс помимо абстрактных методов может иметь и неабстрактные. С интерфейсами это невозможно. Однако для интерфейсов доступно множественное исполнение, а абстрактные классы связаны одинарным наследованием (как и все другие классы). Важно понимать, что интерфейс предоставляет услугу, тогда как класс, даже абстрактный, является абстракцией некоторого объекта. Например:

abstract public Shape implements ShapeAPI {

abstract public void draw ();

private int x,y;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]