Чудесное введение в программирование
Хотел бы преподнести на суд общественности перевод одной чудесной статьи, в которой описаны базовые принципы программирования. Пару слов о том — зачем собственно это все и кому это надо? Отвечаю — последние несколько месяцев я, сам начинающий программист, активно пытаюсь обучать ребят из других сфер. В этом нелегком труде мне приходится шерстить интернет в поисках в первую очередь интересных материалов, чтобы разбить их стереотипы насчет того что код — это скучно и нудно. К моему глубокому сожалению, таких материалов не так уж много. Я уверен, есть огромное количество новичков, которые регулярно читают хабр и эта статья будет им крайне интересна и полезна.
Итак, оригинал здесь, автор Song Zheng.
Основы программирования
Часть 1. Простые примеры кода.
Возможно вы считаете, что программирование — это очень сложно. Но это не так. В действительности каждый из нас имеет навыки программирования. Не ожидали?
Давайте представим, что мы ведем машину и перед нами появляется знак «СТОП». И что вы сделаете? Вы остановитесь!
Глубоко в глубине нашего мозга, в сплетениях нейронов запрограммированны (На Ruby) примерно такие команды:
if self.saw(stopSign) self.stopCar() end
Чтобы вам было проще понять значение слова » self «, вы можете смело заменить его на » Я «, смысл останется прежним. В целом большинство языков программирования придерживается для своего синтаксиса следующего стиля:
существительное.глагол(предмет)
Разбираем этот пример
Существительное в этом примере называется Объектом. Объект умеет делать разные полезные действия.
Глагол из примера называется Методом или Функцией. Метод содержит пару строчек кода и это код выполняется каждый раз, когда вы его вызываете.
Например, где-то внутри вашей головы метод, отвечающий за остановку машины мог бы выглядеть вот так:
def stopCar() self.stepOnBrakes() self.lookLeft() self.lookRight() end
«Предмет» находящийся в скобках называется параметром. Это просто какие-то данные, которые мы хотели бы передать в наш метод.
Теперь представим что вы учитель и вы решили проявить акцию невиданной щедрости и раздать всем своим ученикам по конфетке (в оригинале » fabulous teacher», неприменимо для наших широт). Каждому своему ученику вы раздаете по Ферреро.
Если бы вы были компьютером, то в вашей голове выполнился бы примерно такой код:
for e in students self.giveChocolateTo( e ) end
В этом коде вместо «е» подставляется по очереди каждый из ваших учеников, которому вы даете конфетку.
Как вы думаете, как можно было бы описать в коде то, как вы занимаетесь спортом? Например вот так:
while ( self.amStillAlive() ) self.keepRunning() end
Стоит заметить, что 90% логики в программировании приходится на выражения ‘ if ‘ — для управления ходом выполнения задачи и циклов ‘for’ и ‘while’.
Прежде чем идти дальше, я хотел бы показать вам пару строк кода, который вы можете запустить и посмотреть что из этого выйдет:
x = 0 while (x > -1) x = x+1 end
Разберем пример.
Сначала мы сохраняем в переменную x значение равное 0. Затем, в течении того времени, пока x больше -1, мы увеличиваем значение в переменной x на 1.
Ожидаемый результат в этом примере — это бесконечный цикл, который будет раз за разом увеличивать значение переменной на единицу. Это приведет к тому что процессор вашего компьютера начнет усердно работать, согревая вас своими теплыми потоками воздуха. Идеально в качестве грелки в холодный зимний день =)
Знание циклов и условных операторов позволяет вам начать программировать прямо сейчас. Стоит теперь научиться правильно с ними работать. Вы должны уметь создавать объекты всегда, когда это потребуется.
Часть 2. Основы.
Представьте что вы Б-г и в 6-й день создания мира. Вы все 5 дней трудились в поте лица, а теперь предстоит создать миллионы людей за 1 день. Как это реализовать? Возможно стоит просто сесть и делать людей один за одним? Нет, все что вам надо так это макет, который описывает, как должен выглядеть человек, и затем с этого макета можно создать столько людей, сколько вы успеете до конца дня.
Собственно этот «макет» — есть один из базовых концептов программирования и зовется он — Класс. Каждый раз, когда вы чувствуете себя неловко при упоминании слова «Класс» — просто замените его на «Макет», это облегчит ваше восприятие.
Давайте представим, что вы — разработчик игр и вы хотели бы создать в этой игре множество разных персонажей. Для начала вам стоит создать класс с теми свойствами, которые вы хотели бы видеть в созданном из класса объекте:
class Character def initialize(nameVariable, intelligenceVariable) @name = nameVariable @intelligence = intelligenceVariable end end
Метод ‘initialize’ выполняется каждый раз, когда создается новый объект и наделяет его теми свойствами, который вы описали в базовом классе. В методе мы задаем имя персонажа «nameVariable» и его уровень его интеллекта «intelligenceVariable» ( префикс » @ » является приставкой «self» для свойств персонажа ). Когда персонаж создан, создаются и его свойства. Давайте создадим 2-х персонажей — персонажа «А» и персонажа «Б»:
a = Character.new( "aperson", 10 ) b = Character.new( "bperson", 10 )
Для персонажа А мы задали 2 значения “aperson” и “10”, которые стали свойствами этого персонажа ( потому-что каждый раз при создании объекта выполняется метод «initialize» ).
В результате у нас есть 2 персонажа, одного из них зовут “aperson” и “bperson”, у которых уровень интеллекта равен 10.
Вы заметили как легко мы создали персонаж, всего лишь раз описав класс? Вы можете создавать объекты еще и еще, всего лишь вызывая Character.new(…). Например вот так:
Вот таким образом и было создано 5 миллиардов Адамов и Ев, которым постепенно увеличивали значение интеллекта. Примерно вот так:
Теперь давайте представим, что каждый наш персонаж обладает способностью смотреть известное телешоу «Джерси Шоур». Т.к. эта способность касается всех персонажей, то стоит это указать в нашем макете-классе:
class Character def initialize(nameVariable, intelligenceVariable) . end def watchJerseyShore() @intelligence = @intelligence - 2 end end
С этого момента, каждый раз, когда персонаж будет использовать ‘watchJerseyShore’ метод, уровень его интеллекта будет снижаться. Например вот так:
a.watchJerseyShore() a.watchJerseyShore()
Персонаж А посмотрел шоу 2 раза, соответственно уровень его интеллекта снизился до 6.
Возможно это не очевидно, но единственным способом как-то изменить значение интеллекта у персонажа — это вызвать метод watchJerseyShore(). Данная жесткость предотвращает возможность изменения значений у персонажа, в данном случае уровень интеллекта персонажа. Уровень интеллекта не может быть изменен случайно, его можно изменить только намеренно вызвав метод watchJerseyShore(). Эта важная концепция называется Инкапсуляцией, идея сводится к тому, чтобы доступ к свойствам объекта был ограничен. Например, если однажды, выпив лишнего, вы попытаетесь выполнить метод a.intelligence = 100000 — вы получите ошибку.
Ко всему прочему, если вы заходите создать класс «Тинейджер», у которого будут такие свойства как «имя», «интеллект» и который так-же смотрит шоу «Джерси Шоур», стоит ли вам слепо копировать весь тот код, который вы писали, описывая класс Персонаж? Нет! Все что вам необходимо сделать — унаследовать от базового класса его свойства. Если расширить класс Тинейджер классом Персонаж, то все свойства Персонажа унаследуются классом Тинейджер.
Дальше можно просто создать объект Тинейджер:
teeny = Teenager.new( "teeny", 10)
Teeny — это объект класса Тинейджер с именем «Teeny» и уровнем интеллекта равным 10. Для того чтобы снизить уровень интеллекта нашего Teeny стоит просто посмотреть шоу Джерси:
Эта способность является важной концепцией и называется — Наследование.
Тинейджер рос не таким как все и вы решили изменить значение его метода, отвечающего за просмотр шоу Джерси Шоур. Вы могли бы изменить этот метод следующим образом:
С этих пор, каждый раз как только тинейджер смотрит шоу Джерси, уровень его интеллекта увеличивается! Класс Тинейджеров может не только наследовать все методы и свойства от базового класса, он может так-же и переопределять их. Эта гибкость в переопределении методов, которые наследуются от базового класса — является важной концепцией и называется Полиморфизмом.
Все вместе — Инкапсуляция, Наследование и Полиморфизм составляют основу Объектно-ориентированных языков программирования. Если вы понимаете эти 3 принципа, то вам не составит труда постичь такие языки как Ruby, Java, Objective C, C#, Python и много много других.
END
Я попытался довольно вольно перевести некоторые части этой замечательной статьи. Я уверен что есть куда стремится в плане совершенствования подачи мысли в массы, так что судите строго, все будет учтено и исправлено.
Благодарю за внимание, искренне надеюсь что эта чудесная статья поможет начинающим в понимании 3-х краеугольных камней ООП.