Опп программирование. Три основных принципа ооп. Что такое сигнатура метода

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

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

Процедурные языки

C, Pascal, FORTRAN и подобные языки являются процедурными. То есть каждый их оператор приказывает компьютеру что-то сделать: получить данные, сложить числа, разделить на шесть, отобразить результат. Приложение на процедурном языке представляет собой список инструкций. Если он небольшой, никакого другого организационного принципа (часто называемого парадигмой) не требуется. Программист создает список инструкций, и компьютер выполняет их.

Разделение на функции

Когда приложения становятся больше, список получается громоздким. Немногие могут понять более нескольких сотен инструкций, пока они не будут сгруппированы. По этой причине функция стала способом сделать приложения более понятными для своих создателей. В некоторых языках та же концепция может носить название подпрограммы или процедуры.

Приложение разделено на функции, каждая из которых имеет четко определенную цель и интерфейс.

Идея разделения на процедуры может быть расширена их группированием в больший объект, называемый модулем, но принцип аналогичен: группирование компонентов, которые выполняют списки инструкций.

Разделение на функции и модули - один из краеугольных камней структурного программирования, которое в течение нескольких десятилетий до появления ООП являлось довлеющей парадигмой.

Проблемы структурного программирования

Поскольку приложения становились все более крупными, структурное программирование начало испытывать трудности. Проекты становились слишком сложными. Графики сдвигались. Задействовалось большее число программистов. Сложность росла. Затраты взлетали, график сдвигался дальше, и наступал крах.

Анализ причин этих неудач показал недостатки процедурной парадигмы. Независимо от того, насколько хорошо реализован структурированный подход к программированию, крупные приложения становятся чрезмерно сложными.

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

Если рассматривать эти проблемы в контексте программы учета запасов, то одним из важнейших глобальных элементов данных является совокупность учетных единиц. Разные функции могут обращаться к ним для ввода нового значения, его отображения, изменения и т. д.

Неограниченный доступ

В программе, написанной, например, на C, есть два вида данных. Локальные скрыты внутри функции и другими процедурами не используются.

Когда две и более функций должны получить доступ к одним и тем же данным, то последние должны быть глобальными. Такими, например, являются сведения об учитываемых предметах. Глобальные данные могут быть доступны любой процедуре.

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

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

Например, в программе учета кто-то решит, что код учитываемого предмета должен состоять не из 5 цифр, а из 12. Это потребует изменить с short на long. Теперь связанные с кодом функции должны быть изменены для работы с новым форматом.

Когда элементы изменяются в большом приложении, трудно сказать, какие процедуры имеют к ним доступ. Но даже если это выяснить, их изменение может привести к неправильной работе с другими глобальными данными. Все связано со всем остальным, поэтому изменение в одном месте аукнется в другом.

Моделирование реального мира

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

Атрибуты

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

Поведение

Поведение - это то, что объекты реального мира производят в ответ на какое-то воздействие. Если попросить начальство о повышении зарплаты, ответ будет "да" или "нет". Если нажать на тормоз, то автомобиль остановится. Произнесение и остановка являются примерами поведения. Поведение подобно процедуре: его вызывают, чтобы сделать что-то, и оно делает это. Таким образом, данные и функции сами по себе не моделируют объекты реального мира эффективно.

Решение проблемы

Объект в ООП представляется как совокупность данных и функций. Только процедуры, которые называются функциями-членами в C ++, позволяют получить его значения. Данные скрыты и защищены от изменения. Значения и функции инкапсулированы в одно целое. Инкапсуляция и упрятывание - основные термины в описании ОО-языков.

Если требуется изменить данные, точно известно, какие функции взаимодействуют с ними. Никакие другие процедуры не могут получить к ним доступ. Это упрощает написание, отладку и поддержание программы.

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

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

Следует отметить, что так называемые функции-члены в C++ называются методами в некоторых других ОО-языках, таких как Smalltalk. Элементы данных называются атрибутами. Вызов метода объекта является посылкой ему сообщения.

Аналогия

Можно представить объекты отделами компании. В большинстве организаций сотрудники не работают один день с кадрами, на следующий начисляя зарплату, а затем неделю занимаясь розничной торговлей. У каждого отдела есть свой персонал с четко возложенными на него обязанностями. Есть и собственные данные: показатели заработной платы, продаж, учет сотрудников и т. д. Люди в отделах работают со своей информацией. Разделение компании, таким образом, облегчает контроль за ее деятельностью и поддерживает целостность данных. Бухгалтерия отвечает за Если необходимо знать общую сумму заработной платы, выплачиваемой в южном филиале в июле, не нужно рыться в архиве. Достаточно направить записку ответственному лицу, подождать, пока этот человек получит доступ к данным и отправит ответ с требуемой информацией. Это гарантирует соответствие регламенту и отсутствие постороннего вмешательства. Таким же образом объект в ООП обеспечивает организацию приложения.

Следует помнить, что ориентация на объекты не касается подробностей работы программы. Большинство инструкций C++ соответствует операторам процедурных языков, таких как С. Действительно, функции-члены в C++ очень похожи на функции в С. Только более широкий контекст позволит установить, является ли инструкция процедурной или объектно-ориентированной.

Объект в ООП: определение

При рассмотрении задачи программирования на ОО-языке вместо вопросов о ее разделении на отдельные функции возникает проблема разделения на объекты. ООП-мышление намного облегчает разработку приложений. Это происходит в результате сходства программных и реальных объектов.

Какие вещи становятся объектами в ООП? Ниже представлены типичные категории.

Физический объект в ООП - это:

  • транспорт в моделях движения потока;
  • электрические элементы в программах схемотехники;
  • страны в модели экономики;
  • самолет в системе управления воздушным движением.

Элементы среды компьютера пользователя:

  • меню;
  • окна;
  • графика (линия, прямоугольник, круг);
  • клавиатура, мышь, принтер, дисковые накопители.
  • работники;
  • студенты;
  • клиенты;
  • продавцы.
  • книга учета;
  • личное дело;
  • словарь;
  • таблица широт и долгот населенных пунктов.

Связь объектов реального мира и ООП стало результатом сочетания функций и данных: они произвели переворот в программировании. Такого близкого соответствия в процедурных языках нет.

Класс

Объекты в ООП - это члены классов. Что это значит? Языки программирования имеют встроенные типы данных. Тип int, т. е. целое число, предопределен в C++. Можно объявлять сколько угодно переменных int.

Аналогично определяется множество объектов одного класса. Он определяет функции и данные, включаемые в его объекты, не создавая их, так же как int не создает переменные.

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

Наследование

В жизни классы разделены на подклассы. Например, животные делятся на земноводных, млекопитающих, птиц, насекомых и т. д.

Принцип такого рода деления состоит в том, что каждый подкласс имеет общие характеристики с классом, от которого происходит. Все автомобили имеют колеса и двигатель. Это определяющие характеристики транспортных средств. В дополнение к общим характеристикам каждый подкласс обладает своими особенностями. У автобусов много посадочных мест, а грузовики имеют пространство для перевозки тяжелых грузов.

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

Повторное использование

После того как класс создан и отлажен, он может быть передан другим программистам для повторного использования в собственных приложениях. Это похоже на библиотеку функций, которая может входить в разные приложения.

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

Создание новых типов данных

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

position1 = position + origin,

где и origin - пары независимых численных величин. Создание класса, включающего в себя эти два значения, и объявление переменных его объектами создает новый тип данных.

Полиморфизм, перегрузка

Операторы = (равно) и + (плюс), используемые в позиционной арифметике выше, не действуют так же, как с встроенными типами, такими как int. Объекты position и др. не предопределены, а заданы программным путем. Каким образом эти операторы знают, как с ними обращаться? Ответ заключается в том, что для них можно задать новые модели поведения. Эти операции будут функциями-членами класса Position.

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

Книга об ООП «Объектно-ориентированное программирование для чайников» позволит всем желающим ознакомиться с данной темой подробнее.


2. Дайте определение понятию “класс”.
3. Что такое поле/атрибут класса?
4. Как правильно организовать доступ к полям класса?
5. Дайте определение понятию “конструктор”.
6. Чем отличаются конструкторы по-умолчанию, копирования и конструктор с параметрами?
7. Какие модификации уровня доступа вы знаете, расскажите про каждый из них.
8. Расскажите об особенностях класса с единственным закрытым (private) конструктором.
9. О чем говорят ключевые слова “this”, “super”, где и как их можно использовать?
10. Дайте определение понятию “метод”.
11. Что такое сигнатура метода?
12. Какие методы называются перегруженными?
13. Могут ли нестатические методы перегрузить статические?
14. Расскажите про переопределение методов.
15. Может ли метод принимать разное количество параметров (аргументы переменной длины)?
16. Можно ли сузить уровень доступа/тип возвращаемого значения при переопределении метода?
17. Как получить доступ к переопределенным методам родительского класса?
18. Какие преобразования называются нисходящими и восходящими?
19. Чем отличается переопределение от перегрузки?
20. Где можно инициализировать статические/нестатические поля?

21. Зачем нужен оператор instanceof?
22. Зачем нужны и какие бывают блоки инициализации?
23. Каков порядок вызова конструкторов и блоков инициализации двух классов: потомка и его предка?
24. Где и для чего используется модификатор abstract?
25. Можно ли объявить метод абстрактным и статическим одновременно?
26. Что означает ключевое слово static?
27. К каким конструкциям Java применим модификатор static?
28. Что будет, если в static блоке кода возникнет исключительная ситуация?
29. Можно ли перегрузить static метод?
30. Что такое статический класс, какие особенности его использования?
31. Какие особенности инициализации final static переменных?
32. Как влияет модификатор static на класс/метод/поле?
33. О чем говорит ключевое слово final?
34. Дайте определение понятию “интерфейс”.
35. Какие модификаторы по умолчанию имеют поля и методы интерфейсов?
36. Почему нельзя объявить метод интерфейса с модификатором final или static?
37. Какие типы классов бывают в java (вложенные… и.т.д.)
38. Какие особенности создания вложенных классов: простых и статических.
39. Что вы знаете о вложенных классах, зачем они используются? Классификация, варианты использования, о нарушении инкапсуляции.
40. В чем разница вложенных и внутренних классов?
41. Какие классы называются анонимными?
42. Каким образом из вложенного класса получить доступ к полю внешнего класса?

43. Каким образом можно обратиться к локальной переменной метода из анонимного класса, объявленного в теле этого метода? Есть ли какие-нибудь ограничения для такой переменной?
44. Как связан любой пользовательский класс с классом Object?
45. Расскажите про каждый из методов класса Object.
46. Что такое метод equals(). Чем он отличается от операции ==.
47. Если вы хотите переопределить equals(), какие условия должны удовлетворяться для переопределенного метода?
48. Если equals() переопределен, есть ли какие-либо другие методы, которые следует переопределить?
49. В чем особенность работы методов hashCode и equals? Каким образом реализованы методы hashCode и equals в классе Object? Какие правила и соглашения существуют для реализации этих методов? Когда они применяются?
50. Какой метод возвращает строковое представление объекта?
51. Что будет, если переопределить equals не переопределяя hashCode? Какие могут возникнуть проблемы?
52. Есть ли какие-либо рекомендации о том, какие поля следует использовать при подсчете hashCode?
53. Как вы думаете, будут ли какие-то проблемы, если у объекта, который используется в качестве ключа в hashMap изменится поле, которое участвует в определении hashCode?
54. Чем отличается абстрактный класс от интерфейса, в каких случаях что вы будете использовать?
55. Можно ли получить доступ к private переменным класса и если да, то каким образом?
56. Что такое volatile и transient? Для чего и в каких случаях можно было бы использовать default?
57. Расширение модификаторов при наследовании, переопределение и сокрытие методов. Если у класса-родителя есть метод, объявленный как private, может ли наследник расширить его видимость? А если protected? А сузить видимость?
58. Имеет ли смысл объявлять метод private final?
59. Какие особенности инициализации final переменных?
60. Что будет, если единственный конструктор класса объявлен как final?
61. Что такое finalize? Зачем он нужен? Что Вы можете рассказать о сборщике мусора и алгоритмах его работы.
62. Почему метод clone объявлен как protected? Что необходимо для реализации клонирования?

Ответы. Часть 1

1. Назовите принципы ООП и расскажите о каждом.

Объе́ктно-ориенти́рованное программи́рование (ООП) - это методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определенного класса, а классы образуют иерархию наследования.

Основные принципы ООП: абстракция, инкапсуляция, наследование, полиморфизм.

Абстракция — означает выделение значимой информации и исключение из рассмотрения незначимой. С точки зрения программирования это правильное разделение программы на объекты. Абстракция позволяет отобрать главные характеристики и опустить второстепенные.

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

Инкапсуляция — свойство системы, позволяющее объединить данные и методы, работающие с ними, в классе. Для Java корректно будет говорить, что инкапсуляция это «сокрытие реализации». Пример из жизни — пульт от телевизора. Мы нажимаем кнопочку «увеличить громкость» и она увеличивается, но в этот момент происходят десятки процессов, которые скрыты от нас. Для Java: можно создать класс с 10 методами, например вычисляющие площадь сложной фигуры, но сделать из них 9 private. 10й метод будет называться «вычислитьПлощадь()» и объявлен public, а в нем уже будут вызываться необходимые скрытые от пользователя методы. Именно его и будет вызывать пользователь.

Наследование — свойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью. Класс, от которого производится наследование, называется базовым, родительским или суперклассом. Новый класс - потомком, наследником, дочерним или производным классом.

Полиморфизм — свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта. Пример (чуть переделанный) из Thinking in Java:

public interface Shape { void draw(); void erase(); } public class Circle implements Shape { public void draw() { System.out.println("Circle.draw()"); } } public class Triangle implements Shape { public void draw() { System.out.println("Triangle.draw()"); } } public class TestPol { public static void main(String args) { Shape shape1 = new Circle(); Shape shape2 = new Triangle(); testPoly(shape1); testPoly(shape2); } public static void testPoly(Shape shape) { shape.draw(); } } //Вывод в консоль: //Circle.draw() //Triangle.draw()

public interface Shape {

void draw () ;

void erase () ;

public void draw () {

System . out . println ("Circle.draw()" ) ;

public class Triangle implements Shape {

public void draw () {

System . out . println ("Triangle.draw()" ) ;

public class TestPol {

Shape shape1 = new Circle () ;

Shape shape2 = new Triangle () ;

testPoly (shape1 ) ;

testPoly (shape2 ) ;

public static void testPoly (Shape shape ) {

shape . draw () ;

//Вывод в консоль:

//Circle.draw()

//Triangle.draw()

Есть общий интерфейс «Фигура» и две его реализации «Треугольник» и «Круг». У каждого есть метод «нарисовать». Благодаря полиморфизму нам нет нужды писать отдельный метод для каждой из множества фигур, чтобы вызвать метод «нарисовать». Вызов полиморфного метода позволяет одному типу выразить свое отличие от другого, сходного типа, хотя они и происходят от одного базового типа. Это отличие выражается различным действием методов, вызываемых через базовый класс (или интерфейс).
Здесь приведен пример полиморфизма (также называемый динамическим связыванием, или поздним связыванием, или связыванием во время выполнения), в котором продемонстрировано как во время выполнения программы будет выполнен тот метод, который принадлежит передаваемому объекту.

Если бы не было полиморфизма и позднего связывания, то эта же программа выглядела бы примерно так:

public static void testPolyCircle(Circle circle) { circle.draw(); } public static void testPolyTriangle(Triangle triangle) { triangle.draw(); }

public static void testPolyCircle (Circle circle ) {

circle . draw () ;

public static void testPolyTriangle (Triangle triangle ) {

triangle . draw () ;

Т.е. для каждого класса (фигуры) мы бы писали отдельный метод. Здесь их два, а если фигур (классов) сотни?

2. Дайте определение понятию “класс”.

Класс – это описатель общих свойств группы объектов. Этими свойствами могут быть как характеристики объектов (размер, вес, цвет и т.п.), так и поведения, роли и т.п.

3. Что такое поле/атрибут класса?

Поле (атрибут) класса — это характеристика объекта. Например для фигуры это может быть название, площадь, периметр.

public class Circle implements Shape { private String name; private Double area; private String perimeter; }

public class Circle implements Shape {

private String name ;

private Double area ;

private String perimeter ;

4. Как правильно организовать доступ к полям класса?

Модификатор доступа — private. Доступ через методы get\set.

5. Дайте определение понятию “конструктор”.

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

public class Circle implements Shape { public Circle() { } }

public class Circle implements Shape {

public Circle () {

6. Чем отличаются конструкторы по-умолчанию, копирования и конструктор с параметрами?

Конструктор по умолчанию не принимает никаких параметров. Конструктор копирования принимает в качестве параметра объект класса. Конструктор с параметрами принимает на вход параметры (обычно необходимые для инициализации полей класса).

//конструктор по умолчанию public Circle() { } //конструктор копирования public Circle(Circle circle) { this(circle.getName(), circle.getArea(), circle.getPerimeter()); //будет вызван конструктор с параметрами ниже } //конструктор с параметрами public Circle(String name, Double area, String perimeter) { this.name = name; this.area = area; this.perimeter = perimeter; }

//конструктор по умолчанию

public Circle () {

//конструктор копирования

public Circle (Circle circle ) {

this (circle . getName () , circle . getArea () , circle . getPerimeter () ) ; //будет вызван конструктор с параметрами ниже

//конструктор с параметрами

public Circle (String name , Double area , String perimeter ) {

this . name = name ;

this . area = area ;

this . perimeter = perimeter ;

Обращаю внимание, что тема копирования (clone()) достаточно глубокая с возможностью возникновения множества неявных проблем. Немного можно почитать здесь http://habrahabr.ru/post/246993/.

7. Какие модификации уровня доступа вы знаете, расскажите про каждый из них.

  • private (закрытый) — доступ к члену класса не предоставляется никому, кроме методов этого класса. Другие классы того же пакета также не могут обращаться к private-членам.
  • default, package, friendly, доступ по умолчанию, когда никакой модификатор не присутствует — член класса считается открытым внутри своего собственного пакета, но не доступен для кода, расположенного вне этого пакета.Т.е. если package2.Class2 extends package1.MainClass , то в Class2 методы без идентификатора из MainClass видны не будут .
  • protected (защищённый) — доступ в пределах пакета и классов наследников. Доступ в классе из другого пакета будет к методам public и protected главного класса. Т.е. если package2.Class2 extends package1.MainClass , то внутри package2.Class2 методы с идентификатором protected из MainClass будут видны.
  • public (открытый) — доступ для всех из любого другого кода проекта

Модификаторы в списке расположены по возрастающей видимости в программе.

8. Расскажите об особенностях класса с единственным закрытым (private) конструктором.

Невозможно создать объект класса у которого единственный private конструктор за пределами класса. Поэтому нельзя унаследоваться от такого класса. При попытке унаследоваться будет выдаваться ошибка: There is no default constructor available in имяКласса . А при попытке создать объект этого класса: ИмяКласса() has private access in ИмяКласса

9. О чем говорят ключевые слова “this”, “super”, где и как их можно использовать?

super — используется для обращения к базовому классу, а this к текущему. Пример:

public class Animal { public void eat() { System.out.println("animal eat"); } } public class Dog extends Animal { public void eat() { System.out.println("Dog eat"); } public void thisEat() { System.out.println("Call Dog.eat()"); this.eat(); } public void superEat() { System.out.println("Call Animal.eat()"); super.eat(); } } public class Test { public static void main(String args) { Dog dog = new Dog(); dog.eat(); dog.thisEat(); dog.superEat(); } } Dog eat Call Dog.eat() Dog eat Call Animal.eat() animal eat

public class Animal {

public void eat () {

System . out . println ("animal eat" ) ;

public class Dog extends Animal {

public void eat () {

System . out . println ("Dog eat" ) ;

public void thisEat () {

System . out . println ("Call Dog.eat()" ) ;

this . eat () ;

public void superEat () {

System . out . println ("Call Animal.eat()" ) ;

super . eat () ;

public class Test {

public static void main (String args ) {

Dog dog = new Dog () ;

dog . eat () ;

dog . thisEat () ;

dog . superEat () ;

Dog eat

Call Dog . eat ()

Dog eat

Call Animal . eat ()

animal eat

Если написать super(), то будет вызван конструктор базового класса, а если this(), то конструктор текущего класса. Это можно использовать, например, при вызове конструктора с параметрами:

public Dog() { System.out.println("Call empty constructor"); } public Dog(String name) { System.out.println("Call constructor with Name"); this.name = name; } public Dog(String name, Double weight) { this(name); this.weight = weight; System.out.println("Call constructor with Name and Weight"); } } .. public static void main(String args) { Dog dog1 = new Dog("name", 25.0); } //Вывод Call constructor with Name Call constructor with Name and Weight

public Dog () {

System . out . println ("Call empty constructor" ) ;

public Dog (String name ) {

System . out . println ("Call constructor with Name" ) ;

this . name = name ;

public Dog (String name , Double weight ) {

this (name ) ;

this . weight = weight ;

System . out . println ("Call constructor with Name and Weight" ) ;

public static void main (String args ) {

Dog dog1 = new Dog ("name" , 25.0 ) ;

//Вывод

Call constructor with Name

Call constructor with Name and Weight

10. Дайте определение понятию “метод”.

Метод — это последовательность команд, которые вызываются по определенному имени. Можно сказать что это функция и процедура (в случае void метода).

11. Что такое сигнатура метода?

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

Ключевые слова public, protected, private, abstract, static, final, synchronized, native, strictfp в т.ч. аннотации для метода - это модификаторы и не являются частью сигнатуры.

http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.2

12. Какие методы называются перегруженными?

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

public void method() { } public void method(int a) { } public void method(String str) { }

public void method () { }

public void method (int a ) { }

Волею судьбы мне приходится читать спецкурс по паттернам проектирования в вузе. Спецкурс обязательный, поэтому, студенты попадают ко мне самые разные. Конечно, есть среди них и практикующие программисты. Но, к сожалению, большинство испытывают затруднения даже с пониманием основных терминов ООП.

Для этого я постарался на более-менее живых примерах объяснить базовые понятия ООП (класс, объект, интерфейс, абстракция, инкапсуляция, наследование и полиморфизм).

Первая часть, представленная ниже, посвящена классам, объектам и интерфейсам.
Вторая часть иллюстрирует инкапсуляцию, полиморфизм и наследование

Основные понятия ООП

Класс
Представьте себе, что вы проектируете автомобиль. Вы знаете, что автомобиль должен содержать двигатель, подвеску, две передних фары, 4 колеса, и т.д. Ещё вы знаете, что ваш автомобиль должен иметь возможность набирать и сбавлять скорость, совершать поворот и двигаться задним ходом. И, что самое главное, вы точно знаете, как взаимодействует двигатель и колёса, согласно каким законам движется распредвал и коленвал, а также как устроены дифференциалы. Вы уверены в своих знаниях и начинаете проектирование.

Вы описываете все запчасти, из которых состоит ваш автомобиль, а также то, каким образом эти запчасти взаимодействуют между собой. Кроме того, вы описываете, что должен сделать пользователь, чтобы машина затормозила, или включился дальний свет фар. Результатом вашей работы будет некоторый эскиз. Вы только что разработали то, что в ООП называется класс .

Класс – это способ описания сущности, определяющий состояние и поведение, зависящее от этого состояния, а также правила для взаимодействия с данной сущностью (контракт).

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

С точки зрения структуры программы, класс является сложным типом данных.

В нашем случае, класс будет отображать сущность – автомобиль. Атрибутами класса будут являться двигатель, подвеска, кузов, четыре колеса и т.д. Методами класса будет «открыть дверь», «нажать на педаль газа», а также «закачать порцию бензина из бензобака в двигатель». Первые два метода доступны для выполнения другим классам (в частности, классу «Водитель»). Последний описывает взаимодействия внутри класса и не доступен пользователю.

В дальнейшем, несмотря на то, что слово «пользователь» ассоциируется с пасьянсом «Косынка» и «Microsoft Word», мы будем называть пользователями тех программистов, которые используют ваш класс, включая вас самих. Человека, который является автором класса, мы будем называть разработчиком.

Объект
Вы отлично потрудились и машины, разработанные по вашим чертежам, сходят с конвейера. Вот они, стоят ровными рядами на заводском дворе. Каждая из них точно повторяет ваши чертежи. Все системы взаимодействуют именно так, как вы спроектировали. Но каждая машина уникальна. Они все имеют номер кузова и двигателя, но все эти номера разные, автомобили различаются цветом, а некоторые даже имеют литьё вместо штампованных дисков. Эти автомобили, по сути, являются объектами вашего класса.

Объект (экземпляр) – это отдельный представитель класса, имеющий конкретное состояние и поведение, полностью определяемое классом.

Говоря простым языком, объект имеет конкретные значения атрибутов и методы, работающие с этими значениями на основе правил, заданных в классе. В данном примере, если класс – это некоторый абстрактный автомобиль из «мира идей», то объект – это конкретный автомобиль, стоящий у вас под окнами.

Интерфейс
Когда мы подходим к автомату с кофе или садимся за руль, мы начинаем взаимодействие с ними. Обычно, взаимодействие происходит с помощью некоторого набора элементов: щель для приёмки монеток, кнопка выбора напитка и отсек выдачи стакана в кофейном автомате; руль, педали, рычаг коробки переключения передач в автомобиле. Всегда существует некоторый ограниченный набор элементов управления, с которыми мы можем взаимодействовать.

Интерфейс – это набор методов класса, доступных для использования другими классами.

Очевидно, что интерфейсом класса будет являться набор всех его публичных методов в совокупности с набором публичных атрибутов. По сути, интерфейс специфицирует класс, чётко определяя все возможные действия над ним.
Хорошим примером интерфейса может служить приборная панель автомобиля, которая позволяет вызвать такие методы, как увеличение скорости, торможение, поворот, переключение передач, включение фар, и т.п. То есть все действия, которые может осуществить другой класс (в нашем случае – водитель) при взаимодействии с автомобилем.

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

Примером простого интерфейса может служить машина с коробкой-автоматом. Освоить её управление очень быстро сможет любая блондинка, окончившая двухнедельные курсы вождения. С другой стороны, чтобы освоить управление современным пассажирским самолётом, необходимо несколько месяцев, а то и лет упорных тренировок. Не хотел бы я находиться на борту Боинга, которым управляет человек, имеющий двухнедельный лётный стаж. С другой стороны, вы никогда не заставите автомобиль подняться в воздух и перелететь из Москвы в Вашингтон.

Общее представление об объектно-ориентированном программировании и его особенностях были рассмотрены в первом уроке. Здесь обобщим изученный в этом курсе материал.

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

В курсе не было уделено внимание множественному наследованию, когда дочерний класс наследуется от нескольких родительских. Такое наследование поддерживается в Python в полной мере и дает возможность в производном классе сочетать атрибуты двух и более классов. При множественном наследовании следует учитывать определенные особенности поиска атрибутов.

Полиморфизм позволяет объектам разных классов иметь схожие интерфейсы. Он реализуется путем объявления в них методов с одинаковыми именами. К проявлению полиморфизма как особенности ООП также можно отнести методы перегрузки операторов.

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

Классы обычно помещают в модули. Каждый модуль может содержать несколько классов. В свою очередь модули могут объединяться в пакеты. Благодаря пакетам в Python организуются пространства имен.

Преимущества ООП

Особенности объектно-ориентированного программирования наделяют его рядом преимуществ.

Так ООП позволяет использовать один и тот же программный код с разными данными. На основе классов создается множество объектов, у каждого из которых могут быть собственные значения полей. Нет необходимости вводить множество переменных, т. к. объекты получают в свое распоряжение индивидуальные пространства имен. В этом смысле объекты похожи на структуры данных. Объект можно представить как некую упаковку данных, к которой присоединены инструменты для их обработки – методы.

Наследование позволяет не писать новый код, а использовать и настраивать уже существующий за счет добавления и переопределения атрибутов.

Недостатки ООП

ООП позволяет сократить время на написание исходного кода, однако предполагает большую роль предварительного анализа предметной области и проектирования. От правильности решений на этом этапе зависит куда больше, чем от непосредственного написания исходного кода.

Следует понимать, что одна и та же задача может быть решена разными объектными моделями, каждая из которых будет иметь свои преимущества и недостатки. Только опытный разработчик может сказать, какую из них будет проще расширять и обслуживать в дальнейшем.

Особенности ООП в Python

По сравнению со многими другими языками в Python объектно-ориентированное программирования обладает рядом особых черт.

Всё является объектом – число, строка, список, функция, экземпляр класса, сам класс, модуль. Так класс – объект, способный порождать другие объекты – экземпляры.

В Python нет просто типов данных. Все типы – это классы.

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

И напоследок

Python – это все-таки скриптовый интерпретируемый язык. Хотя на нем пишутся в том числе крупные проекты, часто он используется в веб-разработке, системном администрировании для создания небольших программ-сценариев. В этом случае обычно достаточно встроенных средств языка, "изобретать" собственные классы излишне.

Основы объектно-ориентированного программирования

Все основанные на объектах языки (C#, Java, С++, Smalltalk, Visual Basic и т.п.) должны отвечать трем основным принципам объектно-ориентированного программирования (ООП), которые перечислены ниже:

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

Как данный язык скрывает детали внутренней реализации объектов и предохраняет целостность данных?

Наследование

Как данный язык стимулирует многократное использование кода?

Полиморфизм

Как данный язык позволяет трактовать связанные объекты сходным образом?

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

Роль инкапсуляции

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

Т.е. инкапсуляция представляет собой способности языка скрывать излишние детали реализации от пользователя объекта. Например, предположим, что используется класс по имени DatabaseReader , который имеет два главных метода: Open() и Close().

Фиктивный класс DatabaseReader инкапсулирует внутренние детали нахождения, загрузки, манипуляций и закрытия файла данных. Программистам нравится инкапсуляция, поскольку этот принцип ООП упрощает кодирование . Нет необходимости беспокоиться о многочисленных строках кода, которые работают "за кулисами", чтобы реализовать функционирование класса DatabaseReader. Все, что потребуется - это создать экземпляр и отправлять ему соответствующие сообщения (например, "открыть файл по имени AutoLot.mdf, расположенный на диске С:").

С идеей инкапсуляции программной логики тесно связана идея защиты данных. В идеале данные состояния объекта должны быть специфицированы с использованием ключевого слова private (или, возможно, protected ). Таким образом, внешний мир должен вежливо попросить, если захочет изменить или получить лежащее в основе значение. Это хороший принцип, поскольку общедоступные элементы данных можно легко повредить (даже нечаянно, а не преднамеренно).

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

Код и данные, составляющие вместе класс, называют членами . Данные, определяемые классом, называют полями , или переменными экземпляра . А код, оперирующий данными, содержится в функциях-членах , самым типичным представителем которых является метод. В C# метод служит в качестве аналога подпрограммы. (К числу других функций-членов относятся свойства, события и конструкторы.) Таким образом, методы класса содержат код, воздействующий на поля, определяемые этим классом.

Роль наследования

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

Т.е. наследование представляет собой процесс, в ходе которого один объект приобретает свойства другого объекта. Это очень важный процесс, поскольку он обеспечивает принцип иерархической классификации. Если вдуматься, то большая часть знаний поддается систематизации благодаря иерархической классификации по нисходящей.

Если не пользоваться иерархиями, то для каждого объекта пришлось бы явно определять все его свойства. А если воспользоваться наследованием, то достаточно определить лишь те свойства, которые делают объект особенным в его классе. Он может также наследовать общие свойства своего родителя. Следовательно, благодаря механизму наследования один объект становится отдельным экземпляром более общего класса.

Роль полиморфизма

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

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