"Магия" программирования

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

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

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

Волшебство ООП

Объектно-ориентированное программирование — мощнейший инструмент разработчика. Писать на современных языках гораздо удобнее, чем, допустим, на языке C. Например, для того чтобы вывести пользователю целое число, а не дробь, которая «крутилась» в уравнении, мне пришлось немного подумать. И написал я вот что:

Допустим, у нас есть некая переменная y, куда мы передали дробное значение:
float y = 2.0  
Проверить, целое это число или нет мы должны простыми средствами. Для этого создадим пустую переменную x, инициализируем её нулем и напишем такой код:
float a = y;
int x = 0;
x = (int)y;
y--=x;

if (x == 0) {
printf (“Наша переменная равна  %d”, x);
}
else {
printf (“Наша переменная равна %f”, a);
}

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

 

Объектно-ориентированное программирование избавлено от этих хлопот. Там чаще всего большинство технологий представлено в готовом виде. Так, например, в языке Java легко проверить корректность ввода методом parseInt из класса Integer пакета Java.lang. При вводе нецелого числа или вообще чего угодно, программа выдаст ошибку (исключение), которую программисту необходимо обработать должным образом — поместить туда фразу «вы допустили ошибку», перебросить пользователя обратно к окну ввода или даже дать ему ещё несколько пробных попыток. Но, собственно, мы сегодня не об этом, а о «волшебстве».

Магические классы

Самым настоящим чудом в ООП является тот факт, что программу можно писать не одним бесконечным листингом, как в C, а разбить её на файлы и блоки — классы и методы. Это просто здорово. Ведь в одном классе мы можем хранить запускающую функцию main, в других — методы нашей программы, в третьих — данные или интерфейс соединения с БД. Но как же нам реализовать наше волшебство? Не волнуйтесь — сейчас придумаем вместе.
Создадим, например, класс OneClass:
public class OneClass {
}
И поместим туда наши данные — несколько переменных.
public class OneClass {
int x = 9;
int y = 10;
int z = 11;
}

По умолчанию эти переменные имеют пакетный доступ — т. е – все классы (файлы) нашего пакета могут ими воспользоваться — скопировать, изменить, переопределить. Но как же это сделать? А очень просто — создать экземпляр нашего класса OneClass в другом классе или после метода main.
OneClass cl = new OneClass();

Теперь мы получили возможность пользоваться всеми методами и полями класса (так называются наши переменные, которые написаны сразу после имени класса и поэтому видны во всем OneClass). Скопируем их себе – создадим свои переменные и перебросим туда нужные значения:
public class TwoClass {
OneClass cl = new OneClass();
int x = cl.x;
int y = cl.y;
int z = cl.z;
}

Не стоит бояться одинаковых имен — в другом классе они не перепутаются с изначальными. И теперь у нас есть данные из класса OneClass. 

Но с ними нужно быть очень осторожными. Ведь мы не только можем взять их из первого класса, но и переписать их значения. И хорошо, если мы сделаем это обдуманно. А если просто? Непорядок. Что же делать? Волшебство нуждается в защите от ошибки.

Защитное волшебство

Речь, конечно, пойдёт не о заклятьях Гарри Поттера и не о «Властелине колец». Я хочу рассказать об удивительных методах — геттерах и сеттерах.

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

Чтобы этого избежать, мы сделаем вот что: припишем к каждой переменной идентификатор, который запретит её использование везде, кроме собственного класса.
private x = 9;
private y = 10;
private z = 11;

Теперь никто со стороны не сможет наши данные изменить. Это называется инкапсуляцией. Ну а для нас пока это — волшебство. Попробуем в нём разобраться.
Чтобы создать новый объект, нам самим, другим программистам или иным частям программы, всё равно потребуется получить данные из нашего класса. И что же тогда делать? Ведь они закрыты? Именно для этих случаев и нужны геттеры. Но это волшебство мы должны создавать сами, прописав всю логику этих методов. Get — значит «читать». Чтобы прочитать наши данные в другом классе, нужно их скопировать и передать.

В классе OneClass напишем, например, для переменной x метод-геттер следующего содержания:
public int getX () {
return x;
}
В классе TwoClass вызываем этот метод:
class cl = new class();
cl. getX ();
Можем напечатать наше выражение и убедиться, что получена именно наша переменная.
System.out.println (cl. getX ());
Можно и записать что-то нужное в переменную класса. Для этого потребуется сеттер.
public void setY (newY) {
y =  newY;
}
Надпись, private int y = 10; останется на своем месте. Но получить из недр класса можно будет только то значение, которое записано в newY. Магия – да и только!
С помощью сеттеров мы можем, например, легко «приструнить» пользователя, принимая лишь числа больше нуля и меньше 10. Для этого в сеттер нужно записать несложную логику:
public void setY (newY) {
if (newY>0&& newY<10) {
y =  newY;
}

Магический конструктор

Конструктор — ещё одна магическая единица ООП. Его видно при создании нового объекта класса — например, OneClass cl = new OneClass(); Круглые скобки как раз и скрывают конструктор. Правда, в нашем случае он не имеет параметров, поскольку создается автоматически. Значит, что переменных у нашего объекта может быть любое количество всех типов. Но если мы напишем свой конструктор, то объект не только будет привязан к каким-то параметрам, которые нельзя изменить, но и может получить начальные значения.
Допустим, игровой юнит «дракон» по нашей задумке должен обладать скоростью, высотой полета, временем нахождения в воздухе и должен иметь несколько абстрактных единиц силы. Создадим соответствующий класс и конструктор:

public class Dragon {
Dragon(){
int speed = 120;
int flight_altitude = 1000;
int timeAir = 7;
int power = 10;
}
}

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

Волшебная перегрузка

Но и это — ещё не всё. И конструкторы, и методы поддерживают так называемую перегрузку — то ещё волшебство. Допустим, нам нужно создать из нашего класса Dragon не только дракона, а ещё и «берсеркера». У него не будет высоты и времени полёта — а скорость и сила останутся. Второй конструктор будет таким:
Dragon(int v, int c){
}

В классе, где будет расположен метод main для всех игровых юнитов,  инициализируем новые переменные другими значениями и добавим их в новый объект:
int speed = 60;
    int power = 7;
    Dragon berserker = new Dragon(speed, power);

Ап! У нас появился берсеркер!
Ещё одно маленькое чудо «на закуску». Если у нас в классе уже есть поля x, y, z, то в своем конструкторе или методе мы вполне можем создать такие же переменные с теми же именами и передать им значения полей. Причем наши переменные не перепутаются. Для этого только нужно вставить перед ними маленькое слово  с точкой, вот так:  this.
int x = 4;
int y = 6;
int z = 12;
Dragon(int v, int c, int z){
this.x = x;
this.y = y;
this.z = z;
}

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

Эдуард Трошин

Версия для печатиВерсия для печати

Рубрики: 

  • 1
  • 2
  • 3
  • 4
  • 5
Всего голосов: 0
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!

Читайте также

 

Комментарии

Страницы

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

Вот! "Объект это то, что заключено в фигуристые скобочки" (C)

brat-0 > А так приходится делать всё самому: писать программы, штудировать буржуазных недоучек, вроде Кнута, Кернигана и Гослинга и довольствоваться скупыми и малоинформативными комментариями отечественных мэтров программирования

А потом вам приходится просто написать код где от ООП ничего и нет?

Surprised

Аватар пользователя zabanen

Для брата-zero. Влом сочинять программки для школоты. Один гинеколог после рабочего дня убил девку в подъезде. Она: "Дай рубль, 3,14зду покажу!"

Аватар пользователя Brat

Она: "Дай рубль, 3,14зду покажу!"

Ответ вполне понятен и принимается:-). 

Аватар пользователя leo3

Влом сочинять программки для школоты.

Ок, :) Я не гинеколог, поэтому постараюсь написАть, пожалуй... Между прочим, писАть для "школоты" - это сложней, чем просто писАть, имхо:)

штудировать буржуазных недоучек, вроде Кнута

:) Из разряда шуток юмора:) - У меня на столе на работе как-то долгое время валялась книжка Кнута  "Конкретная математика". Один из моих тогдашних сотрудников (с зелеными волосами, больше фрилансер, на работу появлялся "живьем" редко) нарисовался в дверях (вернулся с Гоа - сказал, что зиму пережидал:), кинул взгляд на стол и выдал комент - "конкретная математика для конкретных пацанов"

Аватар пользователя leo3

Два моих опуса, кстати, лежат в редакции. Правда они не про ООП...

Аватар пользователя Brat

Вот! "Объект это то, что заключено в фигуристые скобочки" (C)

Ничего подобного. В ЖабаСкрипте - вообще, скобочек нет: 

numX1 = objResult.x1; 

В Objective-C скобки квадратные:-)

MyClass *myObject = [[MyClass alloc] init];

Неправда ваша, Логик!:-)

Два моих опуса, кстати, лежат в редакции. Правда они не про ООП...

Не оправдывайтесь. 

Аватар пользователя leo3

Сейчас у меня на столе лежит Даглас Ховштадтер "ГЭБ"... очень рекомендую. Она не про ООП, скорее про ИИ. В частности на стр. 318 он пишет "С ПОЯВЛЕНИЕМ компьютеров люди начали работать над созданием «думающих машин», при этом они стали свидетелями престранных вариаций на тему мысли. Были созданы программы, чье мышление так же походило на человеческое, как движение заводной куклы — на движение человека". Это я к тому, что мы пока в этой фазе и ООП, хоть и немного ближе к мыслительным процессам, но все еще крайне примитивная органопроекция... Нам еще учиться и учиться у природы....

Аватар пользователя Brat

К слову о школоте. Цитата из предисловия: "Книга раскрывает тайну одного феномена американского образования - как превращать малограмотных школьников в прекрасных математиков".

Аватар пользователя leo3

В ЖабаСкрипте - вообще, скобочек нет:


в каком смысле?

Страницы