- •1. Понятие информационной системы (ис). Корпоративные ис. Структура ис.
- •2. Понятие информационной системы (ис). Корпоративные ис. Классификация ис.
- •3. История развития ис.
- •4. .Net Framework. Общеязыковая среда исполнения (clr). Управляемые модули и сборки.
- •5. .Net Framework. Общая система типов (cts) и Общеязыковая спецификация (cls).
- •6. .Net Framework. Механизм сборки мусора.
- •7. C#. Объявление класса.
- •8. Java. Объявление класса.
- •9. C#. Делегаты.
- •10. C#. События.
- •11. C#. Наследование: правила, синтаксис. Сокрытие имен.
- •12. Java. Наследование: правила, синтаксис. Сокрытие имен.
- •13. Правила наследования типов. Принцип «Open-Closed Principle».
- •14. Правила наследования типов. Принцип «Liskov Substitution Principle».
- •15. C#. Приведение типов. Операторы as и is.
- •16. C#. Виртуальные и невиртуальные методы. Статические методы.
- •17. C#. Абстрактные и конечные методы.
- •310 Часть I. Язык с#
- •18. Java. Абстрактные, виртуальные, конечные и статические методы.
- •19. C# и Java. Интерфейсы.
- •20.C#. Структуры.
- •21. C#. Перечисления.
- •22.C#. Упаковка и распаковка объектов значимых типов.
- •23.C# и Java. Исключения. Механизм исключений.
- •24.C# и Java. Исключения. Классы исключений.
- •25.C# и Java. Исключения. Основные принципы использования механизма
- •26.C#. Обобщения: понятие и синтаксис. Ограничения обобщений.
- •27. Java. Обобщения: понятие и синтаксис.
- •28.C#. Коллекции.
- •29.Java. Коллекции.
- •30.C#. Dispose Pattern.
- •31. .Net Framework 3.0, 3.5, 3.5 sp1: общая характеристика.
- •32. C# 3.0, linq: обзор.
- •Источники данных
- •SqlMetal
- •33. Понятие жизненного цикла ис (жц ис). Каскадная модель жц ис.
- •34. Понятие жизненного цикла ис (жц ис). Спиральная модель жц ис.
- •35. Анализ требований. Функциональные и нефункциональные требования.
- •36 Требования и прецеденты. Формат описания прецедента. Структура прецедента.
- •37 Требования и прецеденты. Взаимосвязь прецедентов.
- •38 Модель предметной области. Концептуальные классы. Ассоциации и атрибуты.
- •39 Язык uml. Способы использования. Model Driven Architecture. Executable uml. ДиаграммыUml.
- •40 Диаграмма прецедентов.
- •41. Диаграмма классов. Обозначение классов. Отношение ассоциации.
- •42.Диаграмма классов. Обозначение интерфейсов. Отношение обобщения и зависимости.
- •43.Диаграмма объектов.
- •44.Диаграмма пакетов.
- •45.Диаграмма состояний.
- •46.Диаграмма развертывания.
- •49.Диаграмма коммуникации.
- •50.Паттерн: понятие, структура, классификация.
- •1) Понятие паттерна
- •2) Структура и Классификация паттернов
- •51. Проектирование на основе обязанностей. Принципы grasp.
- •52.Grasp: принцип Low Coupling.
- •53.Grasp: принцип High Cohesion.
- •54.Grasp: принцип Information Expert.
- •55. Grasp: принцип Creator.
- •56.Grasp: принцип Pure Fabrication.
- •57. Grasp: принцип Indirection.
- •59.Grasp: принцип Protected Variations.
- •60.Grasp: принцип Controller.
12. Java. Наследование: правила, синтаксис. Сокрытие имен.
Наследование (inheritance) - это процесс, посредством которого один объект может приобретать свойства другого. Точнее, объект может наследовать основные свойства другого объекта и добавлять к ним черты, характерные только для него. Наследование позволяет поддерживать концепцию иерархии классов. Применение иерархии классов делает управляемыми большие потоки информации.
Без использования иерархии классов, для каждого объекта пришлось бы задать все характеристики, которые бы полностью его определяли. Однако при использовании наследования можно описать объект путём определения того общего класса (или классов), к которому он относится, с теми специальными чертами, которые делают объект уникальным.
Основные принципы наследования классов:
Подкласс всегда наследует все свойства и методы, определенные в его надклассе.
Подкласс может переопределять наследуемые свойства и методы, а также создавать новые — и это никак не должно отражаться на одноименных свойствах и методах надкласса.
Подкласс должен иметь возможность вызывать родные методы надкласса даже в том случае, если переопределяет их.
Объекты подкласса должны инициализироваться только в момент своего создания.
Модификаторы доступа Модификаторы доступа можно рассматривать как с позиции инкапсуляции так и наследования. Если рассматривать с позиции наследования, то модификаторы доступа позволяют путем установки доступа указать члены класса, которые будут наследоваться классом наследником автоматически, а какие нет. Например, переменная или метод, объявленная как public в данном классе будет автоматически перениматься в классе потомке.
Модификатор доступа |
Область доступа |
public |
Без ограничений |
private |
Только из данного класса |
protected |
Из данного класса и его потомков |
Без модификатора |
Для всех классов данного пакета |
Классы-адаптеры и внутренние классы как альтернатива множественному наследованию.
Большинство интерфейсов имеет больше, чем один метод. Даже если необходимо использовать только один метод, он все равно должен определить (пустыми) все остальные. Это загромождает программу и делает ее плохо читаемой. Для сокращения кода используются адаптеры и внутренние классы. Классы-адаптеры удобны для интерфейсов, имеющих более одного метода, поскольку определение всех функций для интерфейсов не относится к классам.
Как известно, в Java запрещено множественное наследование от классов, в отличие от интерфейсов. Что же делать, если пользователь хочет наследовать класс-адаптер и какой-то другой класс одновременно, например, Applet ? Решение этой проблемы состоит в применении внутреннего класса, расширяющего адаптер. Ниже приведен фрагмент кода с внутренним классом:
public class MyClass extends Applet
{ ...
// Конструктор MyClass()
{
addMouseListener(new MyAdapter());
} ...
// Внутренний класс, расширяющий адаптер. class MyAdapter extends MouseAdapter
{ public void mouseClicked(MouseEvent e)
{ ...//Код обработки события. } } }
Можно еще больше сократить код, если использовать анонимное (без имени) определение внутреннего класса следующим образом.
public class MyClass extends Applet
{ ... // Конструктор MyClass() { addMouseListener(new MouseAdapter()
{ public void mouseClicked(MouseEvent e)
{ ...//Код обработки события } }); } ... }
Наследование через понижающее и повышающее преобразования типов
Наследования классов предусматривает возможности преобразования типов между суперклассом и подклассом. Различаются два вида преобразований типов — upcasting и downcasting. Повышающее преобразование (upcasting) — это преобразование от типа порожденного класса (от подкласса) к базовому (суперклассу). Такое преобразование допустимо всегда. На него нет никаких ограничений и для его проведения не требуется применять никаких дополнительных синтаксических конструкций. Это связано с тем, что объект подкласса всегда в себе содержит как свою часть объект суперкласса.
Понижающее преобразование (downcasting) — это преобразование от суперкласса к подклассу. Такое преобразование имеет ряд ограничений. Во-первых, оно может задаваться только явно при помощи операции преобразования типов, например,
B b1 = (B) a;
Во вторых, при преобразовании должен использоваться соответствующий тип. Если это не так, то возникает исключение ClassCastException в процессе выполнения программы.
При понижающем преобразовании часто применяется операция instanceof. Эта операция проверяет, имеет ли ее левый операнд класс, заданный правым операндом. Например,
if ( a instanceof B ) b1 = (B)a;
Пример, сочетающий в себе преобразования типов и instanceof:
Рассмотрим иерархию классов Issue — печатное издание, Book — книга, Newspaper - газета, Journal — журнал, где Book, Newspaper и Journal являются наследниками класса Issue.
public class Issue
{
String name;
public Issue(String name)
{
this.name = name;
}
public void printName(PrintStream out)
{
out.println("Наименование:");
out.println(name);
}
. . .
}
public class Book extends Issue
{
String authors;
public Book(String name, String authors)
{
super(name);
this.authors = authors;
}
public void printAuthors(PrintStream out)
{
out.println("Авторы:");
out.println(authors);
}
. . .
}
А где-то в программе присутствует такой фрагмент:
Issue[] catalog = new Issue[]
{
new Journal("Play Boy"),
new Newspaper("Спид Инфо"),
new Book("Война и мир", "Л.Толстой")
};
. . .
for(int i = 0; i < catalog.length; i++)
{
if ( catalog[i] instanceof Book )
((Book) catalog[i]).printAuthors(System.out);
catalog[i].printName(System.out);
}
Порождается каталог (массив печатных изданий), причем каждое из печатных изданий каталога может быть как книгой, так и газетой или журналом. При построении массива выполняется приведение к базовому типу (upcasting). Далее в цикле мы печатаем информацию из каталога. Причем, для книг кроме наименования печатается еще и список авторов. Для этого с использованием операции instanceof проверяется тип печатного издания, а при самой печати списка авторов элемент каталога преобразуется к типу Book. Если этого не сделать, транслятор выдаст ошибку, т.к. метод printAuthors(...) есть только в классе Book, но не в классе Issue.
Запрет наследования или переопределения с помощью ключевого слова final
Если нужно запретить переопределение (overriding) метода во всех порожденных классах, то этот метод можно описать как final. Кроме того, ключевое слово final может применяться к классам. Это означает, что данный класс не может быть унаследован другим классом.
Множественное наследование интерфейсов
Интерфейсы допускают множественное наследование. Один класс при этом может удовлетворять нескольким интерфейсам сразу. В этом состоит серьезное отличие интерфейсов от обычных классов и от абстрактных классов. Интерфейсы не порождают проблем с множественным наследованием, поскольку они не содержат полей.
После этого может следовать ключевое слово extends и список интерфейсов, от которых будет наследоваться объявляемый интерфейс. Родительских типов может быть много, главное, чтобы не было повторений, и чтобы отношение наследования не образовывало циклической зависимости.
Наследование интерфейсов действительно очень гибкое. Так, если есть два интерфейса A и B, причем B наследуется от A, то новый интерфейс C может наследоваться от них обоих. Указание наследования от A является избыточным, все элементы этого интерфейса и так будут получены по наследству через интерфейс B.
public interface Drawble extends Colorable, Resizable
{
}
Класс наследует от прямых суперклассов и прямых суперинтерфейсов все методы (abstract или нет) этих суперклассов и суперинтерфейсов, которые доступны для кода класса и которые не перегружены и не скрыты в объявлении данного класса.
Если объявление метода перегружает или скрывает объявление другого метода, тогда происходит ошибка времени компиляции, если они имеют различные типы возвращения или если один имеет тип возвращения, а другой не возвращает никаких данных (т.е. в его объявлении содержится слово "void"). Более того, объявление метода не должно содержать предложение throws, которое противоречит с этим методом, и которое его замещает или скрывает; иначе происходит ошибка времени компиляции. В этом аспекте замещение методов отличается от сокрытия полей для него допустимо для поля скрыть поле другого типа.
Модификатор доступа замещенного или скрытого метода должен обеспечивать максимальный доступ к замещенным или скрытым методам, иначе происходит ошибка времени компиляции. Более подробно:
Если замещаемый или скрываемый метод объявлен как public, тогда замещение или сокрытие метода должно быть public; иначе происходит ошибка времени компиляции.
Если замещемый или скрываемый метод объявлен как protected, тогда замещение или сокрытие метода должно быть protected или public; иначе происходит ошибка времени компиляции.
Если замещенный или скрытый метод имеет доступ по умолчанию (пакета), тогда замещение или сокрытие метода не должно быть private; иначе присходит ошибка времени компиляции.
Заметьте, что private-метод никогда не доступен для подклассов и поэтому не может быть скрытым или замещенным в техническом смысле этого понятия. Такой способ, что подкласс может объявлять метод с той же самой сигнатурой как private-метод в одном из суперклассов, и не существует ограничения, чтобы тип возвращения или метод throws такого метода имел какую-либо взаимосвязь с private-методами в суперклассе.
