Классы и объекты — различия между версиями

Материал из Deeptown Manual
Перейти к: навигация, поиск
(http://lietracde.jugem.jp/?eid=2 Camilla 3d review Camilla where playing free Camilla game download Camilla net download Camilla movie legally whistling song in Camilla Camilla downloads Camilla showi)
 
(не показаны 82 промежуточные версии 5 участников)
Строка 1: Строка 1:
http://lietracde.jugem.jp/?eid=2 Camilla 3d review Camilla where playing free Camilla game download Camilla net download Camilla movie legally whistling song in Camilla Camilla downloads Camilla showing times Camilla poet watch full version of fast Camilla movie film theaters watch Camilla Camilla order of reviews Camilla buy Camilla online pictures of dory from Camilla make my Camilla list of Camilla characters best price Camilla watch high quality movies Camilla online Camilla true story Camilla cutting scene meaning of Camilla Camilla bluray release date download Camilla movie bootleg summary of Camilla movie to watch online dvd Camilla Camilla video game Camilla 3d locations Camilla movie preview Camilla blu ray extended edition Camilla film dvd quality the order of Camilla movies picture of Camilla Camilla trailer hd Camilla lyrics download Camilla film hq Camilla wiki music of Camilla welcome to Camilla is Camilla on dvd yet quotes by Camilla Camilla soundtrack mediafire Camilla premier read Camilla Camilla toys Camilla song in trailer Camilla 3d review Camilla where playing free Camilla game download Camilla net download Camilla movie legally whistling song in Camilla Camilla downloads Camilla showing times Camilla poet watch full version of fast Camilla movie film theaters watch Camilla Camilla order of reviews Camilla buy Camilla online pictures of dory from Camilla make my Camilla list of Camilla characters best price Camilla watch high quality movies Camilla online Camilla true story Camilla cutting scene meaning of Camilla Camilla bluray release date download Camilla movie bootleg summary of Camilla movie to watch online dvd Camilla Camilla video game Camilla 3d locations Camilla movie preview Camilla blu ray extended edition Camilla film dvd quality the order of Camilla movies picture of Camilla Camilla trailer hd Camilla lyrics download Camilla film hq Camilla wiki music of Camilla welcome to Camilla is Camilla on dvd yet quotes by Camilla Camilla soundtrack mediafire Camilla premier read Camilla Camilla toys Camilla song in trailer
+
__TOC__
http://lietracde.jugem.jp/?eid=3 On Golden Pond film review On Golden Pond rating On Golden Pond suits for sale On Golden Pond film soundtrack quotes from On Golden Pond movie On Golden Pond icon make your own On Golden Pond shop On Golden Pond On Golden Pond hd download where to download movies On Golden Pond On Golden Pond latest movie windows xp On Golden Pond On Golden Pond vol watch online rules in On Golden Pond On Golden Pond video On Golden Pond dvd download bloat On Golden Pond place fast On Golden Pond On Golden Pond generator buy cheap On Golden Pond watch whole film of On Golden Pond On Golden Pond free about On Golden Pond film real On Golden Pond film download On Golden Pond mp4 megaupload where to buy On Golden Pond film On Golden Pond all movies On Golden Pond fan new movie On Golden Pond On Golden Pond online youtube On Golden Pond release date usa On Golden Pond gift set On Golden Pond chatting games download On Golden Pond soundtrack On Golden Pond pic On Golden Pond movie length movie theaters playing On Golden Pond watch complete On Golden Pond film On Golden Pond movie in theaters download On Golden Pond film On Golden Pond it music On Golden Pond stream download On Golden Pond movie avi On Golden Pond theatre On Golden Pond dvd bluray windows On Golden Pond black On Golden Pond film review On Golden Pond rating On Golden Pond suits for sale On Golden Pond film soundtrack quotes from On Golden Pond movie On Golden Pond icon make your own On Golden Pond shop On Golden Pond On Golden Pond hd download where to download movies On Golden Pond On Golden Pond latest movie windows xp On Golden Pond On Golden Pond vol watch online rules in On Golden Pond On Golden Pond video On Golden Pond dvd download bloat On Golden Pond place fast On Golden Pond On Golden Pond generator buy cheap On Golden Pond watch whole film of On Golden Pond On Golden Pond free about On Golden Pond film real On Golden Pond film download On Golden Pond mp4 megaupload where to buy On Golden Pond film On Golden Pond all movies On Golden Pond fan new movie On Golden Pond On Golden Pond online youtube On Golden Pond release date usa On Golden Pond gift set On Golden Pond chatting games download On Golden Pond soundtrack On Golden Pond pic On Golden Pond movie length movie theaters playing On Golden Pond watch complete On Golden Pond film On Golden Pond movie in theaters download On Golden Pond film On Golden Pond it music On Golden Pond stream download On Golden Pond movie avi On Golden Pond theatre On Golden Pond dvd bluray windows On Golden Pond black
+
 
http://dailybooth.com/ilrecatt699/21852520 download Imogene McCarthery movie for iphone download Imogene McCarthery for free Imogene McCarthery extended dvd how to watch the full movie of Imogene McCarthery Imogene McCarthery online games Imogene McCarthery playing Imogene McCarthery on video movie Imogene McCarthery release date download movie Imogene McCarthery pda newest Imogene McCarthery movie Imogene McCarthery cover Imogene McCarthery movie soundtrack review of Imogene McCarthery movie times for Imogene McCarthery real Imogene McCarthery live free or Imogene McCarthery dvd movies Imogene McCarthery purchase Imogene McCarthery filming location new movie Imogene McCarthery Imogene McCarthery online com Imogene McCarthery videogame lost Imogene McCarthery downloads Imogene McCarthery official trailer Imogene McCarthery opening Imogene McCarthery wiki Imogene McCarthery cast list free Imogene McCarthery ebooks Imogene McCarthery online classes Imogene McCarthery dvd cheapest Imogene McCarthery remake where is Imogene McCarthery playing Imogene McCarthery coupons new Imogene McCarthery film real Imogene McCarthery film download Imogene McCarthery ipod download Imogene McCarthery movie for iphone download Imogene McCarthery for free Imogene McCarthery extended dvd how to watch the full movie of Imogene McCarthery Imogene McCarthery online games Imogene McCarthery playing Imogene McCarthery on video movie Imogene McCarthery release date download movie Imogene McCarthery pda newest Imogene McCarthery movie Imogene McCarthery cover Imogene McCarthery movie soundtrack review of Imogene McCarthery movie times for Imogene McCarthery real Imogene McCarthery live free or Imogene McCarthery dvd movies Imogene McCarthery purchase Imogene McCarthery filming location new movie Imogene McCarthery Imogene McCarthery online com Imogene McCarthery videogame lost Imogene McCarthery downloads Imogene McCarthery official trailer Imogene McCarthery opening Imogene McCarthery wiki Imogene McCarthery cast list free Imogene McCarthery ebooks Imogene McCarthery online classes Imogene McCarthery dvd cheapest Imogene McCarthery remake where is Imogene McCarthery playing Imogene McCarthery coupons new Imogene McCarthery film real Imogene McCarthery film download Imogene McCarthery ipod
+
== История развития ООП ==
Oyle Bir Gecer Zaman ki creators download Oyle Bir Gecer Zaman ki movie camrip Oyle Bir Gecer Zaman ki theaters Oyle Bir Gecer Zaman ki movie download website how many Oyle Bir Gecer Zaman ki movies are there download Oyle Bir Gecer Zaman ki full length movie Oyle Bir Gecer Zaman ki game Oyle Bir Gecer Zaman ki real video Oyle Bir Gecer Zaman ki blu ray release Oyle Bir Gecer Zaman ki movie on the internet virtual Oyle Bir Gecer Zaman ki games Oyle Bir Gecer Zaman ki tv spot Oyle Bir Gecer Zaman ki dialogues let it snow Oyle Bir Gecer Zaman ki movie Oyle Bir Gecer Zaman ki plot Oyle Bir Gecer Zaman ki soundtrack free download watch Oyle Bir Gecer Zaman ki free Oyle Bir Gecer Zaman ki desktop Oyle Bir Gecer Zaman ki games for xbox 360 Oyle Bir Gecer Zaman ki on bluray Oyle Bir Gecer Zaman ki screening Oyle Bir Gecer Zaman ki on video Oyle Bir Gecer Zaman ki gallery Oyle Bir Gecer Zaman ki voice film Oyle Bir Gecer Zaman ki Oyle Bir Gecer Zaman ki cast list summary of Oyle Bir Gecer Zaman ki movie download Oyle Bir Gecer Zaman ki film legally Oyle Bir Gecer Zaman ki ending video timeline of Oyle Bir Gecer Zaman ki http://lietracde.jugem.jp/?eid=4 Oyle Bir Gecer Zaman ki creators download Oyle Bir Gecer Zaman ki movie camrip Oyle Bir Gecer Zaman ki theaters Oyle Bir Gecer Zaman ki movie download website how many Oyle Bir Gecer Zaman ki movies are there download Oyle Bir Gecer Zaman ki full length movie Oyle Bir Gecer Zaman ki game Oyle Bir Gecer Zaman ki real video Oyle Bir Gecer Zaman ki blu ray release Oyle Bir Gecer Zaman ki movie on the internet virtual Oyle Bir Gecer Zaman ki games Oyle Bir Gecer Zaman ki tv spot Oyle Bir Gecer Zaman ki dialogues let it snow Oyle Bir Gecer Zaman ki movie Oyle Bir Gecer Zaman ki plot Oyle Bir Gecer Zaman ki soundtrack free download watch Oyle Bir Gecer Zaman ki free Oyle Bir Gecer Zaman ki desktop Oyle Bir Gecer Zaman ki games for xbox 360 Oyle Bir Gecer Zaman ki on bluray Oyle Bir Gecer Zaman ki screening Oyle Bir Gecer Zaman ki on video Oyle Bir Gecer Zaman ki gallery Oyle Bir Gecer Zaman ki voice film Oyle Bir Gecer Zaman ki Oyle Bir Gecer Zaman ki cast list summary of Oyle Bir Gecer Zaman ki movie download Oyle Bir Gecer Zaman ki film legally Oyle Bir Gecer Zaman ki ending video timeline of Oyle Bir Gecer Zaman ki
+
 
Come Together guide is Come Together in theaters Come Together movie wiki where watch Come Together film watch new Come Together film Come Together trailer leaked Come Together movie megavideo Come Together movie information summer in the city Come Together watch Come Together free Come Together vol soundtrack download top Come Together Come Together wiki film Come Together free download order of Come Together Come Together mov Come Together movz which Come Together character are you full movie online Come Together Come Together movie theatre 3d chat Come Together watch Come Together movie in high quality download Come Together film in ipod quality where can i download Come Together movie online Come Together theaters Come Together clipart Come Together two towers Come Together catalog Come Together movie mediafire download Come Together movies list in order Come Together game online Come Together film party when is the new Come Together coming out Come Together livejournal Come Together theatre tickets tamil movies online Come Together Come Together websites play Come Together game online dvd cover Come Together Come Together movie download website Come Together collection blu ray where is Come Together playing Come Together poster rules Come Together online codes Come Together bluray 1080p download mediafire download Come Together soundtrack Come Together dvd cheapest http://dailybooth.com/ilrecatt699/21852528 Come Together guide is Come Together in theaters Come Together movie wiki where watch Come Together film watch new Come Together film Come Together trailer leaked Come Together movie megavideo Come Together movie information summer in the city Come Together watch Come Together free Come Together vol soundtrack download top Come Together Come Together wiki film Come Together free download order of Come Together Come Together mov Come Together movz which Come Together character are you full movie online Come Together Come Together movie theatre 3d chat Come Together watch Come Together movie in high quality download Come Together film in ipod quality where can i download Come Together movie online Come Together theaters Come Together clipart Come Together two towers Come Together catalog Come Together movie mediafire download Come Together movies list in order Come Together game online Come Together film party when is the new Come Together coming out Come Together livejournal Come Together theatre tickets tamil movies online Come Together Come Together websites play Come Together game online dvd cover Come Together Come Together movie download website Come Together collection blu ray where is Come Together playing Come Together poster rules Come Together online codes Come Together bluray 1080p download mediafire download Come Together soundtrack Come Together dvd cheapest
+
Для того чтобы понять, что же такое классы и объекты, сперва необходимо проследить историю развития программирования. А конкретнее, историю возникновения концепции ООП. Автор верит, что знание истории возникновения тех или иных мыслей и идей может помочь читателю осознать необходимость нововведений, и главное — их преимуществ перед существовавшими в то время решениями.
Carry on Columbus collectors edition cast Carry on Columbus watch Carry on Columbus movie stream Carry on Columbus online game download xbox live Carry on Columbus dvd cover Carry on Columbus Carry on Columbus full movie download Carry on Columbus hdrip Carry on Columbus download high quality movies Carry on Columbus collectables buy Carry on Columbus it movie high quality watch Carry on Columbus online dvd quality Carry on Columbus xbox Carry on Columbus vol music Carry on Columbus for sale Carry on Columbus cheat codes watch Carry on Columbus megavideo summer in the city Carry on Columbus watch Carry on Columbus film right now download movie Carry on Columbus in ipod download full movie Carry on Columbus torrents Carry on Columbus Carry on Columbus movie in hd Carry on Columbus star Carry on Columbus blue ray extended edition Carry on Columbus 3d bluray i want to watch Carry on Columbus movie Carry on Columbus creator online pics of Carry on Columbus 3d Carry on Columbus creator Carry on Columbus on blue ray dvd release date Carry on Columbus Carry on Columbus original download Carry on Columbus it full movie free http://lietracde.jugem.jp/?eid=5 Carry on Columbus collectors edition cast Carry on Columbus watch Carry on Columbus movie stream Carry on Columbus online game download xbox live Carry on Columbus dvd cover Carry on Columbus Carry on Columbus full movie download Carry on Columbus hdrip Carry on Columbus download high quality movies Carry on Columbus collectables buy Carry on Columbus it movie high quality watch Carry on Columbus online dvd quality Carry on Columbus xbox Carry on Columbus vol music Carry on Columbus for sale Carry on Columbus cheat codes watch Carry on Columbus megavideo summer in the city Carry on Columbus watch Carry on Columbus film right now download movie Carry on Columbus in ipod download full movie Carry on Columbus torrents Carry on Columbus Carry on Columbus movie in hd Carry on Columbus star Carry on Columbus blue ray extended edition Carry on Columbus 3d bluray i want to watch Carry on Columbus movie Carry on Columbus creator online pics of Carry on Columbus 3d Carry on Columbus creator Carry on Columbus on blue ray dvd release date Carry on Columbus Carry on Columbus original download Carry on Columbus it full movie free
+
 
http://dailybooth.com/ilrecatt699/21852539 watch Kimberly movie dvd quality Kimberly items latest Kimberly film watch whole film of Kimberly Kimberly film out Kimberly vol subtitles Kimberly opening date Kimberly series in order Kimberly characters list Kimberly online film what theaters are playing Kimberly whistling song from Kimberly Kimberly gift shop watch Kimberly film download Kimberly game review Kimberly episode the film Kimberly watch Kimberly movie divx watch full version Kimberly movie Kimberly movie order free Kimberly movies Kimberly film soundtrack Kimberly soundtrack listen buy Kimberly top Kimberly blu ray extended edition how to download Kimberly film Kimberly printables director of Kimberly soundtrack of Kimberly Kimberly online download free Kimberly download mp3 all Kimberly movies in order Kimberly movie on internet star of Kimberly Kimberly hood film for sale Kimberly movie megavideo Kimberly dvd extended Kimberly on sale play Kimberly games free online Kimberly megaupload mp4 virtual Kimberly chat watch Kimberly movie dvd quality Kimberly items latest Kimberly film watch whole film of Kimberly Kimberly film out Kimberly vol subtitles Kimberly opening date Kimberly series in order Kimberly characters list Kimberly online film what theaters are playing Kimberly whistling song from Kimberly Kimberly gift shop watch Kimberly film download Kimberly game review Kimberly episode the film Kimberly watch Kimberly movie divx watch full version Kimberly movie Kimberly movie order free Kimberly movies Kimberly film soundtrack Kimberly soundtrack listen buy Kimberly top Kimberly blu ray extended edition how to download Kimberly film Kimberly printables director of Kimberly soundtrack of Kimberly Kimberly online download free Kimberly download mp3 all Kimberly movies in order Kimberly movie on internet star of Kimberly Kimberly hood film for sale Kimberly movie megavideo Kimberly dvd extended Kimberly on sale play Kimberly games free online Kimberly megaupload mp4 virtual Kimberly chat
+
=== Возникновение языков программирования ===
Wojna zensko meska online login Wojna zensko meska subtitle read Wojna zensko meska online for free Wojna zensko meska divx Wojna zensko meska film synopsis watch movies online Wojna zensko meska play Wojna zensko meska game full download Wojna zensko meska movies actress from Wojna zensko meska Wojna zensko meska composer watch Wojna zensko meska online megavideo watch full Wojna zensko meska it film in hd Wojna zensko meska opening credits ringtone Wojna zensko meska Wojna zensko meska stuff Wojna zensko meska bluray dvd shop for movies Wojna zensko meska Wojna zensko meska song lyrics watch Wojna zensko meska online dvd quality Wojna zensko meska fancy dress first Wojna zensko meska movie apple movie trailer Wojna zensko meska online Wojna zensko meska game play download Wojna zensko meska movie for ipod Wojna zensko meska fanfiction archive Wojna zensko meska blu ray review download movie Wojna zensko meska in divx Wojna zensko meska suits for sale download Wojna zensko meska movie for mac Wojna zensko meska fanclub Wojna zensko meska writer Wojna zensko meska film picture movie trailer Wojna zensko meska online Wojna zensko meska oscars Wojna zensko meska out on dvd Wojna zensko meska online com http://brontisbthimb.jugem.jp/?eid=2 Wojna zensko meska online login Wojna zensko meska subtitle read Wojna zensko meska online for free Wojna zensko meska divx Wojna zensko meska film synopsis watch movies online Wojna zensko meska play Wojna zensko meska game full download Wojna zensko meska movies actress from Wojna zensko meska Wojna zensko meska composer watch Wojna zensko meska online megavideo watch full Wojna zensko meska it film in hd Wojna zensko meska opening credits ringtone Wojna zensko meska Wojna zensko meska stuff Wojna zensko meska bluray dvd shop for movies Wojna zensko meska Wojna zensko meska song lyrics watch Wojna zensko meska online dvd quality Wojna zensko meska fancy dress first Wojna zensko meska movie apple movie trailer Wojna zensko meska online Wojna zensko meska game play download Wojna zensko meska movie for ipod Wojna zensko meska fanfiction archive Wojna zensko meska blu ray review download movie Wojna zensko meska in divx Wojna zensko meska suits for sale download Wojna zensko meska movie for mac Wojna zensko meska fanclub Wojna zensko meska writer Wojna zensko meska film picture movie trailer Wojna zensko meska online Wojna zensko meska oscars Wojna zensko meska out on dvd Wojna zensko meska online com
+
 
characters from For Sale by Owner For Sale by Owner last scene For Sale by Owner trialer For Sale by Owner episode guide For Sale by Owner sound download For Sale by Owner soundtrack For Sale by Owner re release play For Sale by Owner game online watch For Sale by Owner full film in hd make my For Sale by Owner For Sale by Owner playlist For Sale by Owner movie score download For Sale by Owner film dvd For Sale by Owner movie quotes For Sale by Owner must listen For Sale by Owner movie rating how to draw For Sale by Owner watch made from For Sale by Owner For Sale by Owner video game trailer characters in For Sale by Owner For Sale by Owner film song For Sale by Owner dvd prices For Sale by Owner sites For Sale by Owner official site For Sale by Owner film still watch For Sale by Owner movie full For Sale by Owner questions For Sale by Owner screenshots where to download the fast For Sale by Owner movie For Sale by Owner widescreen download For Sale by Owner movie live free For Sale by Owner For Sale by Owner movie timings virtual world For Sale by Owner For Sale by Owner movie download for free For Sale by Owner actor For Sale by Owner online play For Sale by Owner film downloads what is For Sale by Owner about how to watch For Sale by Owner tide online http://lietracde.jugem.jp/?eid=6 characters from For Sale by Owner For Sale by Owner last scene For Sale by Owner trialer For Sale by Owner episode guide For Sale by Owner sound download For Sale by Owner soundtrack For Sale by Owner re release play For Sale by Owner game online watch For Sale by Owner full film in hd make my For Sale by Owner For Sale by Owner playlist For Sale by Owner movie score download For Sale by Owner film dvd For Sale by Owner movie quotes For Sale by Owner must listen For Sale by Owner movie rating how to draw For Sale by Owner watch made from For Sale by Owner For Sale by Owner video game trailer characters in For Sale by Owner For Sale by Owner film song For Sale by Owner dvd prices For Sale by Owner sites For Sale by Owner official site For Sale by Owner film still watch For Sale by Owner movie full For Sale by Owner questions For Sale by Owner screenshots where to download the fast For Sale by Owner movie For Sale by Owner widescreen download For Sale by Owner movie live free For Sale by Owner For Sale by Owner movie timings virtual world For Sale by Owner For Sale by Owner movie download for free For Sale by Owner actor For Sale by Owner online play For Sale by Owner film downloads what is For Sale by Owner about how to watch For Sale by Owner tide online
+
На заре зарождения вычислительных машин их приходилось программировать поистине "вручную". Все, что было в руках  программиста это пульт управления ЭВМ. На шестнадцатеричной клавиатуре (а еще раньше на пульте с тумблерами) программист задавал некоторый адрес ячейки памяти, затем он мог либо выполнить операцию чтения — тогда на табло появлялись цифры, соответствующие значению ячейки памяти, либо операцию записи — при этом, по указанному адресу записывалось значение, набранное на клавиатуре данных. Затем, программист переходил к следующей ячейке, и так повторялось до тех пор, пока в память ЭВМ не была внесена вся программа. На программистах (точнее, на операторах ЭВМ) лежала огромная ответственность! Одна ошибка, один неверно установленный переключатель или одна пропущенная команда неминуемо вели к ошибкам в работе программы, а, следовательно, и к ошибкам в расчетах. Могли потребоваться недели, и даже месяцы на поиск этой ошибки и на ее исправление! Естественно, ни о каких языках программирования тогда не могло идти и речи.
http://ineedin.over-blog.com/article-watch-the-real-al-di-la-della-legge-1968-it-film-95873705.html download Al di la della legge free mediafire Al di la della legge names of Al di la della legge fun Al di la della legge games Al di la della legge cd cover Al di la della legge movie review music from Al di la della legge vol how to download Al di la della legge song from Al di la della legge Al di la della legge collection blu ray pictures of dory from Al di la della legge Al di la della legge map illegal Al di la della legge movie download Al di la della legge free streaming Al di la della legge soundtrack cd Al di la della legge online mmorpg Al di la della legge pc game free download Al di la della legge film online Al di la della legge bluray 1080p download mediafire cheapest Al di la della legge dvd Al di la della legge watch full movie Al di la della legge 3d collection download Al di la della legge films i want to watch the full film of Al di la della legge Al di la della legge sound track Al di la della legge audiobook free Al di la della legge blue ray extended edition cast of Al di la della legge match Al di la della legge hd download xbox live Al di la della legge Al di la della legge music score Al di la della legge psx Al di la della legge film money free Al di la della legge divx Al di la della legge film watch full film Al di la della legge movie showing Al di la della legge creator free where can i buy fast Al di la della legge movie download Al di la della legge free mediafire Al di la della legge names of Al di la della legge fun Al di la della legge games Al di la della legge cd cover Al di la della legge movie review music from Al di la della legge vol how to download Al di la della legge song from Al di la della legge Al di la della legge collection blu ray pictures of dory from Al di la della legge Al di la della legge map illegal Al di la della legge movie download Al di la della legge free streaming Al di la della legge soundtrack cd Al di la della legge online mmorpg Al di la della legge pc game free download Al di la della legge film online Al di la della legge bluray 1080p download mediafire cheapest Al di la della legge dvd Al di la della legge watch full movie Al di la della legge 3d collection download Al di la della legge films i want to watch the full film of Al di la della legge Al di la della legge sound track Al di la della legge audiobook free Al di la della legge blue ray extended edition cast of Al di la della legge match Al di la della legge hd download xbox live Al di la della legge Al di la della legge music score Al di la della legge psx Al di la della legge film money free Al di la della legge divx Al di la della legge film watch full film Al di la della legge movie showing Al di la della legge creator free where can i buy fast Al di la della legge movie
+
 
http://lietracde.jugem.jp/?eid=7 buy High Security Vacation tide movie High Security Vacation online megavideo where to watch High Security Vacation it full movie High Security Vacation film song High Security Vacation hd rapidshare High Security Vacation length High Security Vacation volumes High Security Vacation online membership High Security Vacation trailer mp4 download High Security Vacation music director download High Security Vacation movie hdrip High Security Vacation movie meaning watch High Security Vacation film watch High Security Vacation for free High Security Vacation movie streaming High Security Vacation film video virtual High Security Vacation creator High Security Vacation full lenght movie in divx format High Security Vacation free online games High Security Vacation language buy High Security Vacation movie high quality High Security Vacation showing movie review for High Security Vacation High Security Vacation director cut High Security Vacation generator High Security Vacation rating High Security Vacation world High Security Vacation download hd movies High Security Vacation tracklist High Security Vacation subtitle watch High Security Vacation movie full where can i download High Security Vacation film online download film High Security Vacation dvdrip High Security Vacation hd download High Security Vacation full film to watch watch full version of High Security Vacation film High Security Vacation secrets watch High Security Vacation movie now High Security Vacation movie blog live free High Security Vacation High Security Vacation languages High Security Vacation best quotes buy High Security Vacation tide movie High Security Vacation online megavideo where to watch High Security Vacation it full movie High Security Vacation film song High Security Vacation hd rapidshare High Security Vacation length High Security Vacation volumes High Security Vacation online membership High Security Vacation trailer mp4 download High Security Vacation music director download High Security Vacation movie hdrip High Security Vacation movie meaning watch High Security Vacation film watch High Security Vacation for free High Security Vacation movie streaming High Security Vacation film video virtual High Security Vacation creator High Security Vacation full lenght movie in divx format High Security Vacation free online games High Security Vacation language buy High Security Vacation movie high quality High Security Vacation showing movie review for High Security Vacation High Security Vacation director cut High Security Vacation generator High Security Vacation rating High Security Vacation world High Security Vacation download hd movies High Security Vacation tracklist High Security Vacation subtitle watch High Security Vacation movie full where can i download High Security Vacation film online download film High Security Vacation dvdrip High Security Vacation hd download High Security Vacation full film to watch watch full version of High Security Vacation film High Security Vacation secrets watch High Security Vacation movie now High Security Vacation movie blog live free High Security Vacation High Security Vacation languages High Security Vacation best quotes
+
=== Появление ассемблера ===
http://dailybooth.com/commaduc928/21852558 Falling in Love with the Girl Next Door analysis Falling in Love with the Girl Next Door episode list Falling in Love with the Girl Next Door 3d Falling in Love with the Girl Next Door official site download Falling in Love with the Girl Next Door film in hd formats watch Falling in Love with the Girl Next Door film is Falling in Love with the Girl Next Door 3d Falling in Love with the Girl Next Door 3d collection Falling in Love with the Girl Next Door desktop background Falling in Love with the Girl Next Door online forum Falling in Love with the Girl Next Door film to digital movie trailers Falling in Love with the Girl Next Door watch a movie online how to watch the full film of Falling in Love with the Girl Next Door Falling in Love with the Girl Next Door full lenght film in dvd format Falling in Love with the Girl Next Door fanfiction archive shop for movies Falling in Love with the Girl Next Door Falling in Love with the Girl Next Door movie music download hd Falling in Love with the Girl Next Door Falling in Love with the Girl Next Door movie locations film Falling in Love with the Girl Next Door watch fast Falling in Love with the Girl Next Door ful film watch the complete Falling in Love with the Girl Next Door movie watch free online fast Falling in Love with the Girl Next Door Falling in Love with the Girl Next Door it film opening Falling in Love with the Girl Next Door movie torrents Falling in Love with the Girl Next Door movie on youtube where to buy Falling in Love with the Girl Next Door download Falling in Love with the Girl Next Door movie bdrip 720p Falling in Love with the Girl Next Door button instant Falling in Love with the Girl Next Door Falling in Love with the Girl Next Door soundtrack listen Falling in Love with the Girl Next Door film camera Falling in Love with the Girl Next Door release dvd movie Falling in Love with the Girl Next Door real Falling in Love with the Girl Next Door Falling in Love with the Girl Next Door extended edition Falling in Love with the Girl Next Door film location Falling in Love with the Girl Next Door vol full movie Falling in Love with the Girl Next Door series wiki Falling in Love with the Girl Next Door online review about Falling in Love with the Girl Next Door film codes for Falling in Love with the Girl Next Door online download the whole film of Falling in Love with the Girl Next Door Falling in Love with the Girl Next Door movie hd where can i download Falling in Love with the Girl Next Door online watch Falling in Love with the Girl Next Door full movie online is Falling in Love with the Girl Next Door on dvd online Falling in Love with the Girl Next Door Falling in Love with the Girl Next Door analysis Falling in Love with the Girl Next Door episode list Falling in Love with the Girl Next Door 3d Falling in Love with the Girl Next Door official site download Falling in Love with the Girl Next Door film in hd formats watch Falling in Love with the Girl Next Door film is Falling in Love with the Girl Next Door 3d Falling in Love with the Girl Next Door 3d collection Falling in Love with the Girl Next Door desktop background Falling in Love with the Girl Next Door online forum Falling in Love with the Girl Next Door film to digital movie trailers Falling in Love with the Girl Next Door watch a movie online how to watch the full film of Falling in Love with the Girl Next Door Falling in Love with the Girl Next Door full lenght film in dvd format Falling in Love with the Girl Next Door fanfiction archive shop for movies Falling in Love with the Girl Next Door Falling in Love with the Girl Next Door movie music download hd Falling in Love with the Girl Next Door Falling in Love with the Girl Next Door movie locations film Falling in Love with the Girl Next Door watch fast Falling in Love with the Girl Next Door ful film watch the complete Falling in Love with the Girl Next Door movie watch free online fast Falling in Love with the Girl Next Door Falling in Love with the Girl Next Door it film opening Falling in Love with the Girl Next Door movie torrents Falling in Love with the Girl Next Door movie on youtube where to buy Falling in Love with the Girl Next Door download Falling in Love with the Girl Next Door movie bdrip 720p Falling in Love with the Girl Next Door button instant Falling in Love with the Girl Next Door Falling in Love with the Girl Next Door soundtrack listen Falling in Love with the Girl Next Door film camera Falling in Love with the Girl Next Door release dvd movie Falling in Love with the Girl Next Door real Falling in Love with the Girl Next Door Falling in Love with the Girl Next Door extended edition Falling in Love with the Girl Next Door film location Falling in Love with the Girl Next Door vol full movie Falling in Love with the Girl Next Door series wiki Falling in Love with the Girl Next Door online review about Falling in Love with the Girl Next Door film codes for Falling in Love with the Girl Next Door online download the whole film of Falling in Love with the Girl Next Door Falling in Love with the Girl Next Door movie hd where can i download Falling in Love with the Girl Next Door online watch Falling in Love with the Girl Next Door full movie online is Falling in Love with the Girl Next Door on dvd online Falling in Love with the Girl Next Door
+
 
The Last Run games net The Last Run discussion questions The Last Run whistling song The Last Run games free download videos The Last Run play The Last Run games free online picture of dory from The Last Run The Last Run icons run The Last Run The Last Run out on dvd The Last Run picture editor The Last Run creator online The Last Run movie buy watch The Last Run movie free The Last Run movie price The Last Run character list tickets to The Last Run The Last Run screenplay pdf The Last Run film to watch now The Last Run read online watch full version of The Last Run online The Last Run marker The Last Run movie on line why is The Last Run rated where can i download The Last Run online download The Last Run movie full length The Last Run game demo websites to watch The Last Run movie The Last Run purchasing movie order of The Last Run movies download The Last Run film in hd quality The Last Run watch online The Last Run movie download full movie The Last Run dvds where did they film The Last Run The Last Run soundtrack track list The Last Run fan definition download movie The Last Run dvd The Last Run characters running The Last Run real life The Last Run The Last Run full lenght movie in hd format new york The Last Run http://ineedin.over-blog.com/article-movies-the-last-run-1971-purchase-95873741.html The Last Run games net The Last Run discussion questions The Last Run whistling song The Last Run games free download videos The Last Run play The Last Run games free online picture of dory from The Last Run The Last Run icons run The Last Run The Last Run out on dvd The Last Run picture editor The Last Run creator online The Last Run movie buy watch The Last Run movie free The Last Run movie price The Last Run character list tickets to The Last Run The Last Run screenplay pdf The Last Run film to watch now The Last Run read online watch full version of The Last Run online The Last Run marker The Last Run movie on line why is The Last Run rated where can i download The Last Run online download The Last Run movie full length The Last Run game demo websites to watch The Last Run movie The Last Run purchasing movie order of The Last Run movies download The Last Run film in hd quality The Last Run watch online The Last Run movie download full movie The Last Run dvds where did they film The Last Run The Last Run soundtrack track list The Last Run fan definition download movie The Last Run dvd The Last Run characters running The Last Run real life The Last Run The Last Run full lenght movie in hd format new york The Last Run
+
Впоследствии, программисты смекнули, что команды можно записывать в виде мнемонических обозначений или мнемоник — то, что раньше применялось только для удобства записи на бумаге — было стандартизировано и приспособлено как ''язык'' общения человека и ЭВМ. Так появился первый язык программирования — ''язык ассемблера''. Конечно, языком его можно назвать с некоторой натяжкой, ведь он не обеспечивал и десятой доли тех возможностей (вроде автоматического разбора арифметических выражений), которые мы привыкли ассоциировать с языками программирования. Тем не менее, ассемблер выполнял свою главную и основную функцию — избавлял программиста от необходимости работать с памятью (и адресами) напрямую. Вместо этого, программист записывал свои команды в стандартной форме, понятной ЭВМ. Далее выполнялась программа ''транслятор'', которая преобразовывала исходный текст программы в поток машинных команд, которые уже можно исполнять.
Run of the Arrow free online watch movies Run of the Arrow play Run of the Arrow online without downloading Run of the Arrow mp4 download Run of the Arrow episodes Run of the Arrow mmorpg online free online Run of the Arrow game Run of the Arrow stories movie spoiler Run of the Arrow download movie Run of the Arrow hd download Run of the Arrow films watch online Run of the Arrow Run of the Arrow clipart Run of the Arrow it movie clothing Run of the Arrow soundtrack track list is Run of the Arrow in theaters Run of the Arrow wallpaper order Run of the Arrow movie Run of the Arrow film premier Run of the Arrow film imdb Run of the Arrow movie download zshare movie Run of the Arrow pictures of Run of the Arrow characters movie to watch online Run of the Arrow certificate Run of the Arrow vol music Run of the Arrow group movie Run of the Arrow plot movies Run of the Arrow purchase Run of the Arrow movie info play Run of the Arrow game watch Run of the Arrow film full version Run of the Arrow special extended edition Run of the Arrow audiobook http://lietracde.jugem.jp/?eid=8 Run of the Arrow free online watch movies Run of the Arrow play Run of the Arrow online without downloading Run of the Arrow mp4 download Run of the Arrow episodes Run of the Arrow mmorpg online free online Run of the Arrow game Run of the Arrow stories movie spoiler Run of the Arrow download movie Run of the Arrow hd download Run of the Arrow films watch online Run of the Arrow Run of the Arrow clipart Run of the Arrow it movie clothing Run of the Arrow soundtrack track list is Run of the Arrow in theaters Run of the Arrow wallpaper order Run of the Arrow movie Run of the Arrow film premier Run of the Arrow film imdb Run of the Arrow movie download zshare movie Run of the Arrow pictures of Run of the Arrow characters movie to watch online Run of the Arrow certificate Run of the Arrow vol music Run of the Arrow group movie Run of the Arrow plot movies Run of the Arrow purchase Run of the Arrow movie info play Run of the Arrow game watch Run of the Arrow film full version Run of the Arrow special extended edition Run of the Arrow audiobook
+
 
http://brontisbthimb.jugem.jp/?eid=3 the movie Married to It newest Married to It movie Married to It full movie divx Married to It movie sales the order of Married to It movies Married to It video clips watch complete Married to It movie cast Married to It music Married to It Married to It movie online Married to It shopping movie new Married to It series story of Married to It list of Married to It characters watch Married to It vol online new Married to It trailer Married to It free streaming order Married to It film how to download a movie Married to It subtitles for Married to It Married to It vol soundtrack fast Married to It film high quality pictures of dory from Married to It watch Married to It online for free Married to It movie showing full Married to It film downloads watch new Married to It film download Married to It films Married to It length of movie Married to It itunes Married to It download hd movies Married to It new years Married to It tv series download Married to It full lenght Married to It film download zshare new movies 2011 Married to It digital Married to It preview trailer Married to It flv Married to It cheat codes download Married to It songs Married to It review film Married to It film watch it where can i watch Married to It movie the movie Married to It newest Married to It movie Married to It full movie divx Married to It movie sales the order of Married to It movies Married to It video clips watch complete Married to It movie cast Married to It music Married to It Married to It movie online Married to It shopping movie new Married to It series story of Married to It list of Married to It characters watch Married to It vol online new Married to It trailer Married to It free streaming order Married to It film how to download a movie Married to It subtitles for Married to It Married to It vol soundtrack fast Married to It film high quality pictures of dory from Married to It watch Married to It online for free Married to It movie showing full Married to It film downloads watch new Married to It film download Married to It films Married to It length of movie Married to It itunes Married to It download hd movies Married to It new years Married to It tv series download Married to It full lenght Married to It film download zshare new movies 2011 Married to It digital Married to It preview trailer Married to It flv Married to It cheat codes download Married to It songs Married to It review film Married to It film watch it where can i watch Married to It movie
+
=== Концепция языка высокого уровня ===
 +
 
 +
...С увеличением сложности программ, программировать на ассемблере становилось все сложнее и сложнее.  Ввиду естественных ограничений человеческой памяти и внимания, написание программ и их отладка стали настолько сложными, что люди всерьез подошли к рассмотрению идеи языка высокого уровня — некоторой системы обозначений и абстрактных команд, которая позволила бы записывать программы в абстрактной форме, не заботясь о том, как располагать в памяти код и данные, как их структурировать и т. д. Всю эту работу брал на себя компилятор. Кроме того, он обеспечивал программиста удобным способом записи математических выражений — в естественной форме. При этом, компилятор сам "разворачивал" эти выражения в наборы инструкций ассемблера, попутно подставляя значения констант и адреса переменных. Это дало возможность программистам записывать формулы вычислений в натуральном виде, что уменьшало трудозатраты, ускоряло написание программ и уменьшало вероятность ошибок. Тем не менее, многие авторитеты того времени очень негативно отзывались о языках высокого уровня. В то время языки были довольно несовершенными и генерировали "ужасный" с точки зрения программистов код. Код был не оптимален, занимал огромное по тем временам количество памяти и работал медленнее, чем та же программа, написанная на ассемблере. Смешно сказать, но в то время многие не верили в то, что будущее за ЯП высокого уровня; их считали не более чем игрушкой для "чайников", возжелавших вообразить себя настоящими программистами.
 +
 
 +
Но время шло, количество приверженцев нового подхода постоянно увеличивалось. Сами же компиляторы становились все более мощными и генерировали все более компактный и оптимальный код. Дошло до того, что компилятор с оптимизатором в некоторых случаях генерировал код, более качественный, чем это делал программист. С этого момента ЯП высокого уровня заняли свое место в истории и в инструментарии любого разработчика.
 +
 
 +
=== Структурное программирование ===
 +
 
 +
С развитием языков программирования появились новые концепции и новые парадигмы программирования. От линейного моноблочного программирования, при котором программа писалась единым "куском" от начала до конца, перешли к программам модульным и структурным. При них программа представляла уже совокупность процедур (функций), которые вызывали друг друга в ходе работы программы. Процедуры представляли собой подпрограммы, решающие отдельные частные задачи. При этом код получался более читаемым, и облегчалась его отладка.
 +
 
 +
Опять же, в ходе усложнения решаемых задач и, вследствие этого, увеличения количества переменных с которыми приходилось работать программисту, возникла идея группировки некоторых переменных в группы или структуры. Структуры формировались по назначению и содержали в себе переменные, имеющие отношение к одной и той же сущности. Это значительно повысило читаемость программ и уменьшило количество ошибок в них.
 +
 
 +
=== Объектно-ориентированное программирование ===
 +
 
 +
Ну и наконец, одна светлая голова додумалась до мысли: "а что если в структурах группировать не только переменные, но и сами процедуры которые должны работать с ними?". В результате получилось то, что мы сейчас называем классом — то есть, некоторая обособленная функциональная сущность, которая сама хранит свои данные, а главное сама умеет их обрабатывать. Теперь программисту не нужно помнить, какая из процедур отвечает за некоторое действие над такими-то переменными — он просто берет объект и работает с ним. Все что происходит с объектом внутри — это его личное дело.
 +
 
 +
Последним шагом к современному пониманию программ явились концепции [http://ru.wikipedia.org/wiki/Полиморфизм_(программирование) полиморфизма], [http://ru.wikipedia.org/wiki/Инкапсуляция_(программирование) инкапсуляции] и [http://ru.wikipedia.org/wiki/Наследование_(программирование) наследования]. Не будем пока углубляться в суть этих понятий, отметим только, что их введение сформировало современное понимание объектно-ориентированного программирования.
 +
 
 +
При написании программы на объектно-ориентированном языке, программист строит математическую модель взаимодействия различных сущностей. Каждая из сущностей это свой мир, у которого есть свои законы и особенности. При этом сущности могут быть как конкретные, вроде "сетевой интерфейс" или "файл", так и совершенно абстрактные, например "отношение" или "ошибка". Программист описывает каждую из сущностей в отдельности, обособлено от остальных. Вся необходимая для работы информация хранится внутри, а для взаимодействия с внешним миром предусмотрен ''интерфейс'' — некоторая совокупность ''свойств'' данной сущности (отражающих ее внутреннее состояние) и способов взаимодействия с ней — ''методов''.
 +
 
 +
В ходе работы программы сущности могут взаимодействовать, читая и записывая свойства и вызывая методы друг друга, использовать друг друга как подсистемы, порождать новые сущности и т. д. Получается, что при написании программы, программист переносит свое внутреннее представление того как он видит эту программу, то из чего она состоит и как отдельные ее части взаимодействуют. Теперь не приходится адаптировать свое понимание проблемы к конкретным инструментальным средствам и возможностям языка программирования (конечно, это все же происходит, но уже гораздо менее заметно).
 +
 
 +
В терминах современных языков программирования такие сущности называются ''классами'', в смысле ''классами сущностей''. А отдельные представители этих классов называются ''экземплярами'', ''инстанциями'' (на английский манер) или ''объектами''. Более подробно, различие между классами и объектами будет рассмотрено ниже.
 +
 
 +
 
 +
Итак, любой современный объектно-ориентированный язык оперирует понятиями классов и объектов. Точно такой же подход нашел свое применение в нашей виртуальной машине. Основой всей платформы Gide является объектно-ориентированный принцип. Причем, в этом смысле она является более объектно-ориентированной, нежели традиционные ЯП вроде C++. В C++ существуют понятия элементарных типов. Это сделано в целях производительности и было продиктовано архитектурой самого языка. В классических языках программирования, элементарные типы, так или иначе, отражают сущности из "реального мира". Например, целочисленные типы int и short соответствуют 32х и 16ти разрядным регистрам процессора, указатели и строки соответствуют представлению данных в памяти и т. д. В Gide это не так. Все с чем оперирует виртуальная машина — это объекты. Соответственно, не существует понятия элементарных типов (просто нет критерия, который бы позволил отделить одно от другого).
 +
 
 +
Язык K++ в полной мере наследует идеологию Gide. Скажем, для него нет отличия между типом <tt>int</tt> (целое число) и некоторым пользовательским классом <tt>MyWeirdClass</tt>: везде, где можно использовать <tt>int</tt>, можно использовать <tt>MyWeirdClass</tt> и наоборот. Более того, это позволяет работать с системными классами так же, как с пользовательскими! Например, ничто не мешает унаследовать свой класс от класса <tt>int</tt>, равно как ничто не мешает определить математические операторы для класса <tt>MyWeirdClass</tt> и использовать объекты этого класса в арифметических выражениях. При этом изменится логика работы всего языка. К примеру, после добавления некоторого метода к классу int можно будет вызывать методы у всех его экземпляров, даже тех, что представлены числовыми константами внутри самого языка!
 +
 
 +
== Понятие класса ==
 +
 
 +
Что такое ''класс'' проще всего объяснить на примерах. Представьте, что вас спрашивают "что такое яблоко?". Скорее всего, вы ответите что-то вроде: "яблоки, это вкусные плоды, растущие на деревьях — яблонях; они бывают разных цветов и размеров". Заметьте, что когда мы описываем ''яблоки как понятие'', мы не имеем в виду некоторый конкретный объект, а скорее описываем наше обобщенное представление о них. Если же вас попросят описать совершенно конкретное яблоко, лежащее на блюдечке перед вами, вы будете говорить о нем по другому: "это яблоко, оно красное, сочное, судя по всему спелое. С черенком, на котором остался листик, и маленькой червоточинкой".
 +
 
 +
Разница заключается в том, что когда вы говорили ''о яблоках'', вы описывали свое представление яблок, как ''класса'' объектов. Когда вы описывали ''яблоко'', то вы имели в виду конкретный ''экземпляр'', или ''объект''. Говоря о классе, вы можете описать только те свойства, что принадлежат всем яблокам; когда же вы описываете объект, то в первую очередь имеете в виду его индивидуальные особенности (свойства). Тем не менее, описание объекта начинается с упоминания его класса ("это яблоко,..."), а затем уже свойств объекта (ведь "сочным и спелым" может быть и апельсин). Это важная особенность объектно-ориентированного подхода.
 +
 
 +
Другой пример: если вас попросить "представьте дерево", то вы либо представите некоторое совершенно абстрактное, усредненное дерево, либо попросите уточнить, какое именно дерево имеется в виду. Ваше сознание из имеющейся информации смогло уяснить только самые общие сведения о классе. Но этой информации не достаточно, для более детального описания. Это тоже важно, поскольку в этом простом примере кроется сущность механизма наследования — постепенного уточнения классами-потомками общих черт своих предков. Таким образом, и яблоня, и груша — деревья. Но яблони отличаются от груш. Получается, что классы ''яблони'' и ''груши'' имеют общего предка — класс ''дерево''.
 +
 
 +
Таким образом, понятия классов и объектов это не математическая абстракция, а скорее часть нашего восприятия мира, того как мы мыслим.
 +
 
 +
 
 +
Из примеров выше мы смогли уяснить следующее:
 +
 
 +
* Классы, это некоторые абстрактные сущности, задающие общие черты своих объектов
 +
* Все объекты одного класса похожи друг на друга, но имеют некоторые индивидуальные особенности
 +
* Классы могут наследоваться, расширяя набор свойств класса родителя своими собственными
 +
 
 +
Перейдем теперь ближе к основной теме нашего повествования, а именно языку К++:
 +
 
 +
С точки зрения языка, ''класс'' представляет собой набор следующих элементов:
 +
* ''полей'', т.е. переменных, хранящих индивидуальные особенности объектов,
 +
* ''методов'', т.е. функций, определяющих поведение данного объекта;
 +
* ''свойств'', определяющих взаимодействие других объектов с объектами данного класса.
 +
 
 +
''Поля'' — это переменные, которые относятся к некоторому конкретному экземпляру нашего класса. Каждый экземпляр имеет свою копию набора переменных, таким образом, они могут хранить свое состояние (например, показатель "спелости", в примере с яблоками). Эти переменные доступны только самому классу, доступ извне для них запрещен. Для того чтобы частично разрешить этот доступ, применяются ''свойства''. Сами свойства будут описаны позже, здесь стоит отметить только то, что свойство может быть доступно "только на чтение", "только на запись" или "и на чтение и на запись". Свойство может быть связано либо с некоторым полем, либо с методом. Например, если свойство доступно "только на чтение" то его можно использовать для получения значения, но не для его записи (то есть, такое свойство не может фигурировать в качестве [[lvalue]]).
 +
 
 +
''Методы'' — это тот самый, связанный с данными код (вспомните [[Классы и объекты#История развития ООП|историю ООП]]) который, естественно, может работать с переменными объекта (то есть с полями) и служит для описания поведения данного класса объектов.
 +
 
 +
Класс может иметь одного или нескольких родителей (опять же, подробнее об этом см. ниже)
 +
 
 +
Методы и свойства класса могут находиться в различных областях видимости. Это обеспечивается с помощью [[Спецификаторы доступа|спецификаторов доступа]]:
 +
 
 +
* <tt>'''private'''</tt> — Частная собственность! Видимость только внутри методов данного класса
 +
* <tt>'''protected'''</tt> — "Семейная реликвия", доступ внутри методов данного класса и всех его дочерних классов
 +
* <tt>'''public'''</tt> — видимость и доступ для всех
 +
 
 +
'''Примечание:''' По умолчанию методы имеют видимость <tt>'''private'''</tt>, в то время как свойства — <tt>'''public'''</tt>.
 +
 
 +
Приведем, наконец, пример объявления класса:
 +
 
 +
<source lang="kpp" line="1">
 +
class MyWeirdClass {
 +
    var m_x = 0;  // поле m_x, изначально проинициализированное нулем
 +
    const m_y = 1; // поле-константа m_y
 +
 
 +
    // методы класса
 +
    public const function int get_mul() { return m_x * m_y; }
 +
    public function void set_mul(int x) { m_x = x / m_y; }
 +
 
 +
    // свойство класса
 +
    public property mul read get_mul write set_mul;
 +
}
 +
</source>
 +
 
 +
 
 +
;1: Как у любого нормального разумного существа, у класса есть "голова" и "тело". Ключевое слово <tt>'''class'''</tt> начинает объявление класса. Далее за ним следует [[идентификатор]] имени класса, после чего идет тело класса.
 +
 
 +
;3-4: Здесь мы видим объявление двух полей класса — переменной ''m_x'' и константы ''m_y'', которые, подобно обычным переменным инициализируются тут же, на месте объявления (камень в огород C++). Зачем нужны поля-константы, описано в главе [[Константы]]. 
 +
 
 +
;7-8: Для доступа к состоянию объекта, определены два метода: ''аксессор'' <tt>get_mul()</tt> и ''мутатор'' <tt>set_mul()</tt>. Подобные конструкции применяются настолько часто, что им были даны специальные имена. Как видно из названия, первый метод дает доступ к значению, второй изменяет или мутирует его.
 +
 
 +
;11: Завершается объявление класса объявлением свойства ''mul'', которое связывается с аксессором и мутатором. Думаю, читатель уже догадался, что это свойство типа "чтение и запись". Таким образом, при обращении к свойству на чтение, будет вызван аксессор, а результат его выполнения будет возвращен в качестве значения свойства. И, наоборот, при попытке записать в свойство некоторое значение, будет вызван мутатор, в качестве аргумента которому будет передано это самое значение, а уж сам мутатор позаботится о том, чтобы оно было "доставлено по адресу".
 +
 
 +
: '''Примечание:''' Зачем нужны такие сложности, и зачем дублировать вроде бы одинаковый функционал, будет описано ниже.
 +
 
 +
== Понятие объекта ==
 +
 
 +
Собственно, понятие объекта уже много раз было затронуто выше по повествованию. Поэтому здесь приведем лишь небольшое определение: Под ''объектом'' подразумевается экземпляр того или иного класса, т.е. некоторая сущность, поведение которой задается соответствующим классом.
 +
 
 +
Для создания объекта того или иного класса служит оператор <tt>'''new'''</tt>:
 +
<source lang="kpp">
 +
    var myWeirdObject = new MyWeirdClass;
 +
</source>
 +
 
 +
Здесь мы видим типичную конструкцию объявления переменной, однако в инициализаторе переменной находится всего один оператор, за которым следует [[идентификатор]] имени класса, экземпляр которого мы хотим создать.
 +
 
 +
== Наследование ==
 +
 
 +
Под ''наследованием'' классов понимается механизм такого создания (объявления) класса, при котором он расширяет функционал одного или нескольких уже существующих классов (родителей). Вспомните пример с деревьями. Когда мы говорим, что класс ''яблоня'' наследуется от класса ''дерево'' — это значит что ''яблоня'' унаследует все свойства своего класса-родителя, некоторые из которых он может изменить, ну и дополнить своими собственными свойствами. Опыт нам подсказывает, что у любого дерева есть листья (для простоты не будем вспоминать про хвойные), однако не любое дерево плодоносит яблоками. Если же рассмотреть сами яблоки, то можно сказать, что класс ''яблоко'' унаследован от класса ''фрукт'', который определяет что фрукты (и соответственно яблоки) должны расти на деревьях.
 +
 
 +
Таким образом, наследование гарантирует, что к дочерним классам применимы все операции, доступные в родительском классе: любой алгоритм, работающий с объектами родительского класса, может работать с объектами его дочерних классов.
 +
 
 +
Для задания наследования, в объявлении класса следует указать ключевое слово <tt>'''extends'''</tt>,  за которым необходимо перечислить список идентификаторов классов-родителей, разделяя их запятыми:
 +
 
 +
<source lang="kpp" line="1">
 +
// коробка
 +
class Box {
 +
    // из чего сделана коробка?
 +
    public const function string material() { return "Картон"; }
 +
 
 +
    // что в коробке?
 +
    public const function string contents() { return "Пусто"; }
 +
}
 +
 
 +
// коробка с картошкой
 +
class BoxWithPotatoes extends Box {
 +
    public const function string contents() { return "Картошка"; }
 +
}
 +
 
 +
function OutputBox(const Box b) {
 +
    print("Материал: " + b.material() + ", содержит: " + b.contents() + "\n");
 +
}
 +
 
 +
export function main() {
 +
    var b1 = new Box;
 +
    var b2 = new BoxWithPotatoes;
 +
    OutputBox(b1); // Материал: Картон, содержит: Пусто
 +
    OutputBox(b2); // Материал: Картон, содержит: Картошка
 +
}
 +
</source>
 +
 
 +
 
 +
;2-8: В этом примере мы создаем класс <tt>Box</tt>, который представляет собой некоторую коробку. Мы определяем ее свойства, такие как ''материал'' и ''содержимое''.
 +
 
 +
;11-13: Далее мы определяем класс <tt>BoxWithPotatoes</tt> (''коробка с картошкой''), который наследуется от класса <tt>Box</tt>, и тем самым заимствует свойства материала и содержимого, но первое он переопределяет (в случае методов это называется ''перекрытием'') собственным методом.
 +
 
 +
;15-17: Мы определяем некоторую [[Функции|функцию]] для работы с нашими классами, которая будет отображать их состояние. Заметьте, что в качестве [[Функции#Аргументы|аргумента функции]] передается экземпляр класса <tt>Box</tt>, то есть класса-родителя. При этом мы предполагаем, что любой класс, унаследованный от базового класса, будет обладать необходимым нам интерфейсом, а именно методами получения информации о свойствах (аксессорами мы их не называем, потому что они не связаны с конкретным полем; это было бы неверно).
 +
 
 +
;19-24: Объявляется функция <tt>main()</tt>, внутри которой и происходит самое интересное. Сначала мы создаем два экземпляра ''b1'' и ''b2'' классов <tt>Box</tt> и <tt>BoxWithPotatoes</tt> соответственно. А затем, вызываем вышеописанную функцию <tt>OutputBox()</tt>, которая отображает содержимое. Вывод в терминал (написан в комментарии к вызову) показывает, как это все работает.
 +
 
 +
'''Примечание:''' при использовании множественного наследования существует одно серьезное ограничение: его нельзя применять для наследования от классов стандартной библиотеки. Это ограничение связано с архитектурой платформы Gide. Однако его можно обойти с помощью создания [[Класс-обертка|классов-оберток]] для системного класса, с последующим наследованием от него нового класса.
 +
 
 +
== Методы ==
 +
 
 +
''Метод'' — это некоторый код, связанный с объектом и управляющий его поведением. Управление может заключаться в изменении переменных состояния объекта (полей), либо выполнением некоторых операций над ними.
 +
 
 +
При объявлении метода могут быть указаны следующие ключевые слова, в указанном порядке:
 +
* <tt>'''private'''</tt>, <tt>'''protected'''</tt> или <tt>'''public'''</tt> — определяют область видимости метода
 +
* <tt>'''static'''</tt> — указывает, что метод является ''статическим'' (см. ниже)
 +
* <tt>'''const'''</tt> — метод не изменяет объект
 +
* <tt>'''function'''</tt>, <tt>'''operator'''</tt> или <tt>'''constructor'''</tt> указывает, что объявляется: ''метод'', ''[[Операторы|оператор]]'' или ''конструктор'' (см. ниже)
 +
* <tt>'''const'''</tt> — метод возвращает результат, который нельзя изменять
 +
 
 +
После этого указывается тип, возвращаемый методом. Если он опущен — возвращается [[Переменные#Нетипированные (динамические) переменные|динамическая переменная]]; если вместо типа указано ключевое слово <tt>'''void'''</tt> — метод не возвращает результата. Следом за типом идет имя метода, затем — перечисление [[Функции#Аргументы|аргументов]] в скобках. Подробнее об объявлении функций и передаче параметров, можно прочитать в главе [[Функции]].
 +
 
 +
В теле метода доступны все поля, методы и свойства данного класса и его предков. Например, в нижеприведенном коде, метод <tt>F2()</tt> вызывает метод <tt>F1()</tt> для того же объекта:
 +
<source lang="kpp" line="1">
 +
class MyClass {
 +
    public const function string F1() { return "smth"; }
 +
    public const function string F2() { return F1(); }
 +
}
 +
</source>
 +
 
 +
 
 +
=== Статические методы ===
 +
 
 +
''Статический метод класса'' — это метод, относящийся к данному классу, но не объекту этого класса. Т.е. это некоторая вспомогательная для данного класса функция.
 +
 
 +
При объявлении статического метода нужно указать ключевое слово <tt>'''static'''</tt>.
 +
 
 +
В теле статического метода нет возможности напрямую обращаться к другим методам данного класса, т.к. статическому методу недоступен объект класса. Фактически, единственным отличием статического метода от обычной функции является то, что такой метод может обращаться к защищенным полям и методам класса некоторого другого объекта. Подобный подход широко применяется при написании ''конструкторов'' (см. ниже).
 +
 
 +
Пример:
 +
<source lang="kpp">
 +
class MyClass {
 +
    public static function string Info() { return "Я MyClass!"; }
 +
}
 +
 
 +
function f() {
 +
    // Вызов статического метода:
 +
    var myClassInfo = MyClass.Info();
 +
}
 +
</source>
 +
 
 +
=== Конструкторы ===
 +
 
 +
<font color="red">'''Внимание: информация в этом разделе устарела. Необходимо обновление'''</font>
 +
 
 +
 
 +
В ходе написания программы часто приходится создавать новые объекты. При этом объекту требуется установить некоторое начальное состояние. Разумеется, это выполняется либо путем написания инициализаторов соответствующих полей, либо значения полям присваиваются явным образом. Но что делать, если объект может иметь несколько начальных состояний? То есть, в зависимости от некоторых условий, одним и тем же полям объекта могут быть присвоены различные наборы значений. Тут уже одними инициализаторами не обойтись. Присваивать значения можно прямо в коде программы, однако это не очень красивое решение, поскольку один и тот же объект может создаваться в нескольких местах программы и придется копировать один и тот же участок кода, инициализирующий поля объекта. Недостаток этого подхода в том, что при большом количестве полей, программист может забыть проинициализировать некаторе поле, либо при изменении условий инициализации он может изменить их только в одном месте программы, забыв, что объект может создаваться и в других местах. Более разумным является подход, при котором программист пишет функцию, инициализирующую поля объекта. При этом весь код собирается в одном месте и вероятность ошибок значительно понижается.
 +
 
 +
Конструкторы развивают эту идею, дополняя код инициализации полей кодом создания самого экземпляра объекта. То есть, в конструкторе собирается весь код, относящийся к созданию инстанции класса. Итак, ''конструктор класса'' — это специальный метод, инициализирующий объект класса. С точки зрения языка, конструктор — это статический метод класса, возвращающий экземпляр данного класса.
 +
 
 +
Таким образом, следующие объявления в рамках класса эквивалентны:
 +
<source lang="kpp">
 +
public constructor Create();
 +
public static MyClass Create();
 +
</source>
 +
 
 +
Тело конструктора чаще всего выглядит следующим образом: сначала создается экземпляр класса при помощи оператора <tt>'''new'''</tt>, затем производятся некоторые действия, инициализующие этот объект, и, наконец, этот объект возвращается в качестве результата.
 +
 
 +
В качестве примера приведем пример реализации некоторого абстрактного класса <tt>MyStream</tt>, использующего системную реализацию класса <tt>stream</tt>, и определяющую собственный конструктор:
 +
 
 +
<source lang="kpp" line="1">
 +
class MyStream {
 +
    var string m_URL;
 +
    var stream m_Stream;
 +
public:
 +
    static const MODE_READ = 1;
 +
    static const MODE_WRITE = 2;
 +
    constructor open(const string url, int mode) {
 +
        var self = new MyStream;
 +
        self.m_Stream.open(url, mode);
 +
        self.m_URL = url;
 +
        return self;
 +
    }
 +
    // прочие методы (опущены для краткости)
 +
}
 +
</source>
 +
 
 +
 
 +
;2-3: Объявляются поля ''m_URL'' и ''m_Stream'' нашего класса, которые будут инициализироваться в конструкторе.
 +
 
 +
;5-6: В публичной области класса объявляются статические константы ''MODE_READ'' и ''MODE_WRITE'', которые задают желаемый режим доступа к открываемому потоку. Это единственный случай, когда поле класса доступно на прямой доступ извне.
 +
 
 +
;7: Объявляется конструктор <tt>open()</tt>, принимающий в качестве параметров [[URL]] ресурса который требуется открыть и число, задающее с помощью вышеописанных констант режим доступа к потоку. В теле конструктора мы создаем инстанцию ''self'' нашего класса. Затем производится попытка открытия потока ''m_Stream'': если операция пройдет успешно, то происходит инициализация оставшегося поля ''m_URL'' и выход из конструктора с возвратом созданной инстанции; если же операция открытия потока провалится, то будет сгенерировано ''[[Обработка исключений|исключение]]'' и выполнение конструктора прекратится (управление будет передано "наверх", вызывающему коду).
 +
 
 +
 
 +
Использовать наш класс можно примерно так:
 +
<source lang="kpp">var data = MyStream.open("http://www.deeptown.org/index.html", MyStream.MODE_READ);</source>
 +
 
 +
Обратите внимание на второй параметр функции, где мы передаем константу ''MODE_READ'', объявленную внутри самого класса. Подобный подход, когда константы, используемые при работе с классом, инкапсулируются в тело класса, помогает сконцентрировать код в одном месте и избежать многих ошибок. В результате повышается читаемость кода и не возникает конфликта имен констант.
 +
 
 +
=== Абстрактные методы ===
 +
 
 +
Случается, что при проектировании интерфейсов классов, возникает желание объявить некоторый набор методов в базовом классе, однако не реализовывать их. Обычно это связано с тем, что базовый класс не располагает достаточным количеством информации или возможностей для реализации этой функции. В таких случаях прменяется спецификатор <tt>'''abstract'''</tt>, говорящий комплиятору примерно следующее: "Это всего лишь объявление прототипа метода; не надо пытаться искать его реализацию ниже и выдавать ошибку". Абстрактные методы реализуются в потомках класса, предоставляя уже конкретный функционал. Тем не менее, существует возможность обращения к таким методам напрямую из базового класса.
 +
 
 +
Можно возразить следующее: зачем объявлять прототипы методов, если это не критично для языка? Ведь К++ Не является строго типированным, соответственно необходимость последующей реализации метода можно просто оставить на совести программиста...
 +
 
 +
На самом деле это не совсем так. Декларация абстрактного метода помогает вылавливать некоторые ошибки и делает интерфейс класса более четким.
 +
 
 +
Во-первых, при использовании такого метода в абстрактных алгоритмах базового класса, компилятор имеет возможность проверять правильность вызова метода и выполнять автоматическое преобразование типов, если это необходимо.
 +
 
 +
Во-вторых, программист, изучающий интерфейс класса в качестве кандидата для своего класса-потомка, сразу будет видеть какие методы использует данный базовый класс. Если же абстрактные методы не объявить, то программисту-пользователю придется либо изучать исходники более подробно, либо "курить мануалы". Зачастую, ошибки подобного рода обнаруживаются только во время выполнения программы.
 +
 
 +
Наконец, объявление абстрактного метода в базовом классе, позволяет автоматически генерировать особый тип исключения: <tt>[[EAbstractError]]</tt>. Оно возникает в случае, если была произведена попытка вызова метода объявленного абстрактным в базовом классе но не реализованом в используемом потомке. В таком случае сразу ясно, где кроется ошибка. Если бы объявления не было, то возникло бы обычное исключение о том что метод не найден.
 +
 
 +
Примечание: Использование абстрактных методов особенно удобно при реализации [[Примеси|примесей]]. Приведем пример стандартной примеси <tt>[[Enumerable|примесь Enumerable]]</tt>:
 +
 
 +
<source lang="kpp">
 +
class Enumerable {
 +
public:
 +
    abstract const function each(block b);
 +
    abstract const function int compare(const x);
 +
 
 +
    const function bool all(block b = identity_block) {
 +
        var result = true;
 +
        this.each() { |...|
 +
            if (!b.invoke(args())) {
 +
                result = false;
 +
                break;
 +
            }
 +
        };
 +
        return result;
 +
    }
 +
   
 +
    // (Другие методы примеси)
 +
}
 +
</source>
 +
 
 +
Примесь Enumerable предоставляет классам коллекций несколько методов для итерации по элементам, выбору, поиску и возможности сортировки. Класс испольщующий примесь должен объявить у себя метод <tt>each()</tt>, который вызывает переданный блок последовательно передавая ему элементы коллекции. Если требуется использовать методы Enumerable::max, min или алгоритм сортировки, то необходимо также реализовать соответствующий метод <tt>compare()</tt>. Примеси эффективны там, где много различных классов могут реализовывать похожее поведение, однако наследовать их все от некотрого общего базового класса нерационально. В некотором роде, примесь это своеобразный "недокласс", экземпляры которого не является полностью самостоятельными сущностями, но поведение методов примеси в рамках другого класса может быть разумным. Так, напирмер вышеописанная примесь <tt>Enumerable</tt> предоставляет большое количество методов для работы с коллекциями (обработки элементов), однако она понятия не имеет, о каких именно элементах идет речь. Примесь не располагает механизмом сохранения и выборки элементов, предполагая что эта функциональность будет получена в результате "симбиоза" с классом, включающим данную примесь.
 +
 
 +
В данном случае мы видим, что примесь явным образом объявляет абстрактные методы <tt>each()</tt> и <tt>compare()</tt>. Эти два метода -- единственная внешняя зависимость примеси от класса, ее использующего.  
 +
 
 +
Таким образом, мы можем использовать примесь в любом классе, который может и не являться коллекцией. В качестве примера можно привести такой код:
 +
<source lang="kpp">
 +
class MyClass extends Enumerable {
 +
    public const function each(block b) {
 +
        b("hello");
 +
        b("to");
 +
        b("mixin!!!");
 +
    }
 +
}
 +
 
 +
export function main() {
 +
    var c = new MyClass;
 +
    var i = 1;
 +
    c.collect() { |x| i++ to string + ' ' + x; }.each() { |x| puts(x); }
 +
}
 +
</source>
 +
 
 +
Нетрудно догадаться, что результатом выполнения такой программы будут следующие строки:
 +
1 hello
 +
2 to
 +
3 mixin!!!
 +
 
 +
Обратите внимание, что мы обращаемся с инстанцией нашего класса как с коллекцией -- вызываем методы collect() и итерируем по элементам так, как будто это массив. Основное преимущество примесей в том, что они позволяют писать очень гибкий код одновременно делая его максимально универсальным и годным для повторного использования.
 +
 
 +
'''Примечание:''' Метод collect() объявлен в стандартной библиотеке К++ (файл kpp.kpp).
 +
 
 +
== Поля ==
 +
 
 +
Поле класса — это некоторый объект, используемый объектом данного класса.
 +
 
 +
Объявление поля начинается с одного из трех ключевых слов:
 +
* <tt>'''var'''</tt>  — объявление "обычного" поля;
 +
* <tt>'''const'''</tt> — данное поле является константой и не может быть изменено;
 +
* <tt>'''mutable'''</tt> — значение данного поля не влияет на состояние объекта, и его можно менять даже в методах, объявленных константными.
 +
 
 +
За ключевым словом следует тип поля и [[идентификатор]] его имени. Тип поля может быть опущен. После имени может стоять символ "=" и выражение, инициализирующее значение данного поля. В целом, синтаксис тот же, что и при объявлении обычной переменой или константы:
 +
 
 +
<source lang="kpp">
 +
var int m_x;
 +
const m_y = 0;
 +
var m_stream = new stream;
 +
</source>
 +
 
 +
Тип поля определяется по следующим правилам:
 +
* если тип указан явно, ничего определять не надо;
 +
* если тип не указан, но при объявлении использован инициализатор — типом становится тип результата инициализатора;
 +
* в противном случае, для поля устанавливается [[Переменные#Нетипированные (динамические) переменные|динамический тип]].
 +
 
 +
'''Примечание:''' В K++ доступ к полям имеет только объект класса — т.е. фактически, все поля находятся в закрытой (private) области видимости. Для предоставления внешним классам доступа к полям следует использовать ''свойства'' (см. ниже).
 +
 
 +
== Свойства ==
 +
 
 +
''Свойства'' — это специальные конструкции языка К++, которые позволяют совмещать обращение к данным с вызовом определенного метода. Смысл свойств заключается в том, чтобы программист мог контролировать процесс изменения состояния объекта и своевременно реагировать на это изменение. Свойства бывают доступны на чтение, на запись, или на чтение и на запись одновременно. Это связано с тем, что некоторые свойства объекта (в естественном понимании этого слова), могут предполагать только получение информации о них, другие же могут подразумевать изменение состояния, без возможности чтения.
 +
 
 +
В существующих языках программирования, таких как C++ тот же функционал реализуется с помощью вызова специальных методов: ''аксессоров'' и ''мутаторов'', которые используются для получения сведений о некотором свойстве или для записи соответственно. Однако это делает код менее читаемым, особенно в случае мутаторов. Свойства же, позволяют работать с собой подобно обычным полям или объектам, используя операторы.
 +
 
 +
Приведем два примера, которые позволят понять смысл свойств и их отличие от обычных полей класса.
 +
 
 +
Предположим, что у нас есть класс, отвечающий за чтение состояния некоторого устройства. Допустим, состояние представляется целым числом и должно определяться по мере обращения. Если бы мы писали на языке C++, то мы оформили бы это в виде метода:
 +
 
 +
<source lang="cpp">
 +
class MyDevice {
 +
    int GetState();
 +
};
 +
</source>
 +
 
 +
Везде, где нам потребовалось бы читать состояние устройства мы должны были писать что-то типа:
 +
 
 +
<source lang="cpp">
 +
int current_state = Device.GetState();
 +
</source>
 +
 
 +
В случае с К++, чтение свойств осуществляется подобно обычным полям. Перепишем вышеописанный пример на язык К++:
 +
 
 +
<source lang="kpp">
 +
class MyDevice {
 +
    function int GetState();
 +
    property int state read GetState;
 +
}
 +
</source>
 +
 
 +
Соответственно, обращение к свойству состояния будет выглядеть так:
 +
 
 +
<source lang="kpp">
 +
var current_state = Device.state;
 +
</source>
 +
 
 +
При обращении к свойству <tt>state</tt>  будет автоматически вызван метод <tt>GetState()</tt>, результат которого будет возвращен как значение свойства. Вышеописанный пример кому-то может показаться странным, ведь получается, что мы усложнили код класса ради сомнительного выигрыша в коде обращения. На самом деле, в реальных условиях, с настоящими классами, с большим количеством свойств и в сложных выражениях, выигрыш становится куда более заметен. Сравните два примера одного и того же участка кода, один из которых написан на C++, другой на K++. Несмотря на то, что приведенный код тоже взят "с потолка", разница в читаемости уже более заметна. В целом, чем сложнее выражение и чем больше в нем применяется операций присваивания и доступа к полям классов — тем большее преимущество дает использование свойств:
 +
 
 +
<source lang="cpp">
 +
Object1.SetStatus(Object2.GetStatus() > 0 ? Object2.GetStatus() : DefaultObject.GetStatus());
 +
printf("object %s (%d) located at %s : status changed to %u",
 +
    Object1.GetName(), Object1.GetIndex(), Object1.GetLocation(), Object1.GetStatus());
 +
</source>
 +
 
 +
<source lang="kpp">
 +
Object1.status = Object2.status > 0 ? Object2.status : DefaultObject.status;
 +
puts("object % (%) located at % : status changed to %",
 +
    Object1.name, Object1.index, Object1.location, Object1.status);
 +
</source>
 +
 
 +
В качестве второго примера мы приведем код, более близкий к реальной жизни. Как известно, многие элементы управления современных графических интерфейсов могут находиться в состоянии "активен" или "не активен". Неактивные элементы не реагируют на действия пользователя (например, кнопки не будут нажиматься) и как правило окрашиваются в оттенки серого (для того чтобы нельзя было их спутать с активными элементами). Естественно, это поведение определяется некоторым полем в объекте элемента управления. В зависимости от его значения, библиотека графического интерфейса будет по-разному обрабатывать и отрисовывать этот элемент управления.
 +
 
 +
В языке К++ это поведение можно легко описать, используя двусторонние свойства, то есть такие, которые можно использовать как на чтение, так и на запись. Логично предположить, что чтение такого свойства не должно сказываться на самом элементе управления, в то время как запись в свойство должна дать команду элементу управления изменить свое состояние и соответственно внешний вид. Вот пример описания некоторого абстрактного класса элемента управления:
 +
 
 +
<source lang="kpp" line="1">
 +
class Widget {
 +
    var m_Enabled = true; //поле, хранящее текущее состояние активности
 +
    function void SetEnabled(const value) {
 +
        var old_value = m_Enabled;
 +
        m_Enabled = value;
 +
        if (old_value != m_Enabled)
 +
            Invalidate(); //Состояние изменилось, обновляем элемент управления
 +
    }
 +
    property enabled read m_Enabled write SetEnabled;
 +
    //далее идет остальная часть класса, например методы отрисовки
 +
}
 +
</source>
 +
 
 +
Теперь, если мы унаследуем некоторый класс от данного класса и переопределим соответствующие методы отрисовки, то у класса потомка так же можно будет использовать свойство <tt>enabled</tt>:
 +
 
 +
<source lang="kpp">
 +
var myForm = new Form; //создаем окно
 +
var myButton = Button.CreateAtPos(myForm, 10, 10); //добавляем кнопку
 +
myButton.caption = "Click me!"; //устанавливаем подпись
 +
myButton.OnClick += { |x| x.enabled = false; }; //подключаем обработчик события
 +
myForm.Show(); //показываем окно
 +
</source>
 +
 
 +
Приведенный выше код создаст окно и разместит на нем кнопку (подразумевается, что класс <tt>Button</tt> унаследован от нашего класса <tt>Widget</tt>). Затем устанавливаются свойства кнопки, такие как подпись и [[Блоки|блок]] обработчика события <tt>OnClick</tt>. При нажатии на кнопку она станет неактивной.
 +
 
 +
 
 +
----
 +
 
 +
 
 +
В заключение, кратко опишем синтаксис объявления свойства и поясним его. Итак, объявление любого свойства начинается с указания ключевого слова <tt>'''property'''</tt>, после которого идет [[идентификатор]] типа свойства. Тип может быть опущен, тогда для свойства будет определен [[Переменные#Нетипированные (динамические) переменные|динамический тип]]. Затем указывается идентификатор имени свойства.
 +
 
 +
Оставшаяся часть зависит от того, какое свойство объявляется:
 +
 
 +
* Если объявляется свойство на чтение, то указывается ключевое слово <tt>'''read'''</tt>, после которого идет либо идентификатор имени поля, которое нужно читать, либо имя метода, который должен использоваться как ''аксессор''. В роли аксессора может выступать метод, не принимающий параметров и возвращающий некоторое значение, которое будет возвращаться как значение свойства.
 +
* Если объявляется свойство на запись, то указывается, соответственно ключевое слово <tt>'''write'''</tt> после которого идет либо имя поля, которое нужно записывать, либо имя метода, который должен использоваться как ''мутатор''. В качестве мутатора может выступать метод, принимающий один параметр. Возвращаемое значение игнорируется, так что оно может быть любым.
 +
* Если объявляется свойство, доступное как на чтение, так и на запись, то указываются обе части, причем первой идет часть чтения.
 +
 
 +
 
 +
'''Примечание:''' Если тип свойства указан явно, то в зависимости от типа поля либо типа возвращаемого значения аксессора, может быть выполнена операция [[Приведение типов|приведения типов]]. Разумеется, если тип поля или результат аксессора неприводим к указанному типу свойства, то будет выдано сообщение об ошибке. Аналогичная ситуация обстоит и с параметром мутатора.
 +
 
 +
Кратко, синтаксис объявления свойства можно описать в стиле справки к командам оболочки:
 +
<source lang="kpp">
 +
property [тип] <имя> [read <аксессор|поле>] [write <мутатор|поле>];
 +
</source>
 +
 
 +
'''Примечание 2:''' Существует альтернативный синтаксис описания аксессоров и мутаторов, при котором код соответствующий им записывается прямо в определении самого свойства. Это выглядит так:
 +
 
 +
<source lang="kpp">
 +
class MyClass {
 +
    var f = 1;
 +
    property int read { f + 1; } write { |v| f = v; };
 +
}
 +
</source>
 +
 
 +
И аксессор и мутатор, представлены здесь в виде inline конструкций, схожих по описанию (и смыслу) с inline блоками. Аксессор возвращает значение поля ''f'', увеличенное на единицу, в то время как мутатор принимает некоторое значение ''v'' и записывает его в соответствующее поле без каких либо изменений.
 +
 
 +
Подобные конструкции могут быть удобны при необходимости реализации свойств-преобразователей, например возвращающих значение некоторого угла в градусах, в то время как в объекте он хранится в радианах. При этом код преобразования довольно краток, что позволяет записать его "как есть", прямо в свойство. Напротив, для сложных преобразований, код которых не умещается на одной строке, рекомендуется использовать основной синтаксис, при котором в теле свойства указывается имя метода, выполняющего операцию.
 +
 
 +
== Расширения ==
 +
 
 +
Иногда бывает необходимо расширить функциональность некоторого существующего класса без порождения дочернего класса. Это может быть необходимо в тех случаях, когда исходный класс уже используется в коде программы и порождение нового класса нарушило бы спецификацию на интерфейс, либо потребовало значительных изменений в исходных текстах программы. В таких случаях целесообразно применять т. н. ''расширения классов''. Синтаксически, конструкция расширения практически не отличается от конструкции объявления класса, однако методы и свойства, перечисленные в нем, дополняются к исходному классу, то есть наследования не происходит.
 +
 
 +
Как правило, расширения применяются к классам [[Стандартной библиотека Gide|стандартной библиотеки]], либо к [[unmanaged код|неуправляемым классам]].
 +
 
 +
В качестве примера приведем код, расширяющий функциональность класса <tt>[[Стандартные типы данных#Целые числа|int]]</tt> с помощью свойства <tt>factorial</tt>. Расширения объявляются путем указания ключевого слова <tt>'''extend'''</tt>, после которого указывается [[идентификатор]] имени класса, который следует расширить. Затем идет тело расширения, такое же, как при описании классов:
 +
 
 +
<source lang="kpp" line="1">
 +
package intmod_fact;
 +
 
 +
extend int {
 +
    const function int GetFactorial() {
 +
        var result = 1;
 +
        for (var x = this; x > 1; x--)
 +
            result *= x;
 +
        return result;
 +
    }
 +
    property int factorial read GetFactorial;
 +
}
 +
 
 +
export function main() {
 +
    puts("Factorial of 10 is " + 10.factorial);
 +
}
 +
</source>
 +
 
 +
 
 +
;3-11: Мы объявляем расширение класса <tt>[[Стандартные типы данных#Целые числа|int]]</tt>, реализованного в [[Стандартная библиотека gide|стандартной библиотеке]]. Добавляется частный метод <tt>GetFactorial()</tt>, и свойство <tt>factorial</tt>, связанное с методом. Как видно из названия, метод рассчитывает факториал числа, которое содержится в объекте. В данном контексте, специальная переменная ''this'' имеет тип <tt>int</tt> и ссылается на сам объект. Таким образом, для числа 10 переменная ''this'' будет равна 10.
 +
 
 +
;14: Здесь мы видим применение расширения в действии. Константа 10 на момент компиляции преобразуется в [[Константы#Константные объекты|константный объект]] класса <tt>int</tt>, который подобно любому другому объекту этого же класса будет иметь свойство <tt>factorial</tt>, которое мы и используем. При попытке чтения из этого свойства будет вызван метод <tt>GetFactorial()</tt>, результат выполнения которого возвращается как значение свойства, то есть как факториал числа. <!--Его мы вызываем с помощью специального синтаксиса, для передачи блока в качестве [[Функции#Аргументы|параметра функции]]. При этом сам блок указывается прямо в коде вызова функции. Тело блока состоит из одного вызова функции, выводящей текущее число в стандартный поток вывода. -->
 +
 
 +
: Обратите внимание, что функция <tt>puts()</tt>, принимает в качестве параметра [[Стандартные типы данных#Строки|строку]], в то время как тип свойства определен как <tt>[[Стандартные типы данных#Целые числа|int]]</tt>. В этом нет ничего странного, потому что класс <tt>int</tt> имеет [[Типы операторов#Операторы приведения типов|оператор приведения типа]] к классу <tt>[[Стандартные типы данных#Строки|string]]</tt>, который вызывается компилятором автоматически. Таким образом, при вычислении значения выражения в скобках, сперва значение факториала ''приводится'' к типу строки, которая складываясь со строкой слева от оператора <tt>+</tt>, передается в качестве параметра функции.
 +
 
 +
 
 +
'''Примечание:''' При работе с расширениями существует одно важное обстоятельство. Методы, объявленные в расширении, будут перекрывать соответствующие им методы класса. Важно понимать, что такое перекрытие не является объявлением виртуального метода — происходит именно замещение старого метода новым.
 +
 
 +
<!-- '''Примечание:''' При работе с расширениями существует одно важное ограничение. Расширять классы можно только методами и свойствами, но не полями. Это связано с внутренней организацией языка К++ и виртуальной машины. Дополнительно стоит отметить, что методы объявленные в расширении будут перекрывать соответствующие им методы класса (имеется в виду ситуация когда имена и наборы параметров полностью совпадают). Важно понимать, что такое перекрытие не является объявлением виртуального метода — происходит именно замещение старого метода новым. -->
 +
 
 +
== Смотри также ==

Текущая версия на 14:40, 13 июля 2013

Содержание


[править] История развития ООП

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

[править] Возникновение языков программирования

На заре зарождения вычислительных машин их приходилось программировать поистине "вручную". Все, что было в руках программиста это пульт управления ЭВМ. На шестнадцатеричной клавиатуре (а еще раньше на пульте с тумблерами) программист задавал некоторый адрес ячейки памяти, затем он мог либо выполнить операцию чтения — тогда на табло появлялись цифры, соответствующие значению ячейки памяти, либо операцию записи — при этом, по указанному адресу записывалось значение, набранное на клавиатуре данных. Затем, программист переходил к следующей ячейке, и так повторялось до тех пор, пока в память ЭВМ не была внесена вся программа. На программистах (точнее, на операторах ЭВМ) лежала огромная ответственность! Одна ошибка, один неверно установленный переключатель или одна пропущенная команда неминуемо вели к ошибкам в работе программы, а, следовательно, и к ошибкам в расчетах. Могли потребоваться недели, и даже месяцы на поиск этой ошибки и на ее исправление! Естественно, ни о каких языках программирования тогда не могло идти и речи.

[править] Появление ассемблера

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

[править] Концепция языка высокого уровня

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

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

[править] Структурное программирование

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

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

[править] Объектно-ориентированное программирование

Ну и наконец, одна светлая голова додумалась до мысли: "а что если в структурах группировать не только переменные, но и сами процедуры которые должны работать с ними?". В результате получилось то, что мы сейчас называем классом — то есть, некоторая обособленная функциональная сущность, которая сама хранит свои данные, а главное сама умеет их обрабатывать. Теперь программисту не нужно помнить, какая из процедур отвечает за некоторое действие над такими-то переменными — он просто берет объект и работает с ним. Все что происходит с объектом внутри — это его личное дело.

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

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

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

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


Итак, любой современный объектно-ориентированный язык оперирует понятиями классов и объектов. Точно такой же подход нашел свое применение в нашей виртуальной машине. Основой всей платформы Gide является объектно-ориентированный принцип. Причем, в этом смысле она является более объектно-ориентированной, нежели традиционные ЯП вроде C++. В C++ существуют понятия элементарных типов. Это сделано в целях производительности и было продиктовано архитектурой самого языка. В классических языках программирования, элементарные типы, так или иначе, отражают сущности из "реального мира". Например, целочисленные типы int и short соответствуют 32х и 16ти разрядным регистрам процессора, указатели и строки соответствуют представлению данных в памяти и т. д. В Gide это не так. Все с чем оперирует виртуальная машина — это объекты. Соответственно, не существует понятия элементарных типов (просто нет критерия, который бы позволил отделить одно от другого).

Язык K++ в полной мере наследует идеологию Gide. Скажем, для него нет отличия между типом int (целое число) и некоторым пользовательским классом MyWeirdClass: везде, где можно использовать int, можно использовать MyWeirdClass и наоборот. Более того, это позволяет работать с системными классами так же, как с пользовательскими! Например, ничто не мешает унаследовать свой класс от класса int, равно как ничто не мешает определить математические операторы для класса MyWeirdClass и использовать объекты этого класса в арифметических выражениях. При этом изменится логика работы всего языка. К примеру, после добавления некоторого метода к классу int можно будет вызывать методы у всех его экземпляров, даже тех, что представлены числовыми константами внутри самого языка!

[править] Понятие класса

Что такое класс проще всего объяснить на примерах. Представьте, что вас спрашивают "что такое яблоко?". Скорее всего, вы ответите что-то вроде: "яблоки, это вкусные плоды, растущие на деревьях — яблонях; они бывают разных цветов и размеров". Заметьте, что когда мы описываем яблоки как понятие, мы не имеем в виду некоторый конкретный объект, а скорее описываем наше обобщенное представление о них. Если же вас попросят описать совершенно конкретное яблоко, лежащее на блюдечке перед вами, вы будете говорить о нем по другому: "это яблоко, оно красное, сочное, судя по всему спелое. С черенком, на котором остался листик, и маленькой червоточинкой".

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

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

Таким образом, понятия классов и объектов это не математическая абстракция, а скорее часть нашего восприятия мира, того как мы мыслим.


Из примеров выше мы смогли уяснить следующее:

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

Перейдем теперь ближе к основной теме нашего повествования, а именно языку К++:

С точки зрения языка, класс представляет собой набор следующих элементов:

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

Поля — это переменные, которые относятся к некоторому конкретному экземпляру нашего класса. Каждый экземпляр имеет свою копию набора переменных, таким образом, они могут хранить свое состояние (например, показатель "спелости", в примере с яблоками). Эти переменные доступны только самому классу, доступ извне для них запрещен. Для того чтобы частично разрешить этот доступ, применяются свойства. Сами свойства будут описаны позже, здесь стоит отметить только то, что свойство может быть доступно "только на чтение", "только на запись" или "и на чтение и на запись". Свойство может быть связано либо с некоторым полем, либо с методом. Например, если свойство доступно "только на чтение" то его можно использовать для получения значения, но не для его записи (то есть, такое свойство не может фигурировать в качестве lvalue).

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

Класс может иметь одного или нескольких родителей (опять же, подробнее об этом см. ниже)

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

  • private — Частная собственность! Видимость только внутри методов данного класса
  • protected — "Семейная реликвия", доступ внутри методов данного класса и всех его дочерних классов
  • public — видимость и доступ для всех

Примечание: По умолчанию методы имеют видимость private, в то время как свойства — public.

Приведем, наконец, пример объявления класса:

<source lang="kpp" line="1"> class MyWeirdClass {

   var m_x = 0;  // поле m_x, изначально проинициализированное нулем
   const m_y = 1; // поле-константа m_y
   // методы класса
   public const function int get_mul() { return m_x * m_y; }
   public function void set_mul(int x) { m_x = x / m_y; }
   // свойство класса
   public property mul read get_mul write set_mul;

} </source>


1
Как у любого нормального разумного существа, у класса есть "голова" и "тело". Ключевое слово class начинает объявление класса. Далее за ним следует идентификатор имени класса, после чего идет тело класса.
3-4
Здесь мы видим объявление двух полей класса — переменной m_x и константы m_y, которые, подобно обычным переменным инициализируются тут же, на месте объявления (камень в огород C++). Зачем нужны поля-константы, описано в главе Константы.
7-8
Для доступа к состоянию объекта, определены два метода: аксессор get_mul() и мутатор set_mul(). Подобные конструкции применяются настолько часто, что им были даны специальные имена. Как видно из названия, первый метод дает доступ к значению, второй изменяет или мутирует его.
11
Завершается объявление класса объявлением свойства mul, которое связывается с аксессором и мутатором. Думаю, читатель уже догадался, что это свойство типа "чтение и запись". Таким образом, при обращении к свойству на чтение, будет вызван аксессор, а результат его выполнения будет возвращен в качестве значения свойства. И, наоборот, при попытке записать в свойство некоторое значение, будет вызван мутатор, в качестве аргумента которому будет передано это самое значение, а уж сам мутатор позаботится о том, чтобы оно было "доставлено по адресу".
Примечание: Зачем нужны такие сложности, и зачем дублировать вроде бы одинаковый функционал, будет описано ниже.

[править] Понятие объекта

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

Для создания объекта того или иного класса служит оператор new: <source lang="kpp">

   var myWeirdObject = new MyWeirdClass;

</source>

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

[править] Наследование

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

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

Для задания наследования, в объявлении класса следует указать ключевое слово extends, за которым необходимо перечислить список идентификаторов классов-родителей, разделяя их запятыми:

<source lang="kpp" line="1"> // коробка class Box {

   // из чего сделана коробка?
   public const function string material() { return "Картон"; }
   // что в коробке?
   public const function string contents() { return "Пусто"; }

}

// коробка с картошкой class BoxWithPotatoes extends Box {

   public const function string contents() { return "Картошка"; }

}

function OutputBox(const Box b) {

   print("Материал: " + b.material() + ", содержит: " + b.contents() + "\n");

}

export function main() {

   var b1 = new Box;
   var b2 = new BoxWithPotatoes;
   OutputBox(b1); // Материал: Картон, содержит: Пусто
   OutputBox(b2); // Материал: Картон, содержит: Картошка

} </source>


2-8
В этом примере мы создаем класс Box, который представляет собой некоторую коробку. Мы определяем ее свойства, такие как материал и содержимое.
11-13
Далее мы определяем класс BoxWithPotatoes (коробка с картошкой), который наследуется от класса Box, и тем самым заимствует свойства материала и содержимого, но первое он переопределяет (в случае методов это называется перекрытием) собственным методом.
15-17
Мы определяем некоторую функцию для работы с нашими классами, которая будет отображать их состояние. Заметьте, что в качестве аргумента функции передается экземпляр класса Box, то есть класса-родителя. При этом мы предполагаем, что любой класс, унаследованный от базового класса, будет обладать необходимым нам интерфейсом, а именно методами получения информации о свойствах (аксессорами мы их не называем, потому что они не связаны с конкретным полем; это было бы неверно).
19-24
Объявляется функция main(), внутри которой и происходит самое интересное. Сначала мы создаем два экземпляра b1 и b2 классов Box и BoxWithPotatoes соответственно. А затем, вызываем вышеописанную функцию OutputBox(), которая отображает содержимое. Вывод в терминал (написан в комментарии к вызову) показывает, как это все работает.

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

[править] Методы

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

При объявлении метода могут быть указаны следующие ключевые слова, в указанном порядке:

  • private, protected или public — определяют область видимости метода
  • static — указывает, что метод является статическим (см. ниже)
  • const — метод не изменяет объект
  • function, operator или constructor указывает, что объявляется: метод, оператор или конструктор (см. ниже)
  • const — метод возвращает результат, который нельзя изменять

После этого указывается тип, возвращаемый методом. Если он опущен — возвращается динамическая переменная; если вместо типа указано ключевое слово void — метод не возвращает результата. Следом за типом идет имя метода, затем — перечисление аргументов в скобках. Подробнее об объявлении функций и передаче параметров, можно прочитать в главе Функции.

В теле метода доступны все поля, методы и свойства данного класса и его предков. Например, в нижеприведенном коде, метод F2() вызывает метод F1() для того же объекта: <source lang="kpp" line="1"> class MyClass {

   public const function string F1() { return "smth"; }
   public const function string F2() { return F1(); }

} </source>


[править] Статические методы

Статический метод класса — это метод, относящийся к данному классу, но не объекту этого класса. Т.е. это некоторая вспомогательная для данного класса функция.

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

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

Пример: <source lang="kpp"> class MyClass {

   public static function string Info() { return "Я MyClass!"; }

}

function f() {

   // Вызов статического метода:
   var myClassInfo = MyClass.Info();

} </source>

[править] Конструкторы

Внимание: информация в этом разделе устарела. Необходимо обновление


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

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

Таким образом, следующие объявления в рамках класса эквивалентны: <source lang="kpp"> public constructor Create(); public static MyClass Create(); </source>

Тело конструктора чаще всего выглядит следующим образом: сначала создается экземпляр класса при помощи оператора new, затем производятся некоторые действия, инициализующие этот объект, и, наконец, этот объект возвращается в качестве результата.

В качестве примера приведем пример реализации некоторого абстрактного класса MyStream, использующего системную реализацию класса stream, и определяющую собственный конструктор:

<source lang="kpp" line="1"> class MyStream {

   var string m_URL;
   var stream m_Stream;

public:

   static const MODE_READ = 1;
   static const MODE_WRITE = 2;
   constructor open(const string url, int mode) {
       var self = new MyStream;
       self.m_Stream.open(url, mode);
       self.m_URL = url;
       return self;
   }
   // прочие методы (опущены для краткости)

} </source>


2-3
Объявляются поля m_URL и m_Stream нашего класса, которые будут инициализироваться в конструкторе.
5-6
В публичной области класса объявляются статические константы MODE_READ и MODE_WRITE, которые задают желаемый режим доступа к открываемому потоку. Это единственный случай, когда поле класса доступно на прямой доступ извне.
7
Объявляется конструктор open(), принимающий в качестве параметров URL ресурса который требуется открыть и число, задающее с помощью вышеописанных констант режим доступа к потоку. В теле конструктора мы создаем инстанцию self нашего класса. Затем производится попытка открытия потока m_Stream: если операция пройдет успешно, то происходит инициализация оставшегося поля m_URL и выход из конструктора с возвратом созданной инстанции; если же операция открытия потока провалится, то будет сгенерировано исключение и выполнение конструктора прекратится (управление будет передано "наверх", вызывающему коду).


Использовать наш класс можно примерно так: <source lang="kpp">var data = MyStream.open("http://www.deeptown.org/index.html", MyStream.MODE_READ);</source>

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

[править] Абстрактные методы

Случается, что при проектировании интерфейсов классов, возникает желание объявить некоторый набор методов в базовом классе, однако не реализовывать их. Обычно это связано с тем, что базовый класс не располагает достаточным количеством информации или возможностей для реализации этой функции. В таких случаях прменяется спецификатор abstract, говорящий комплиятору примерно следующее: "Это всего лишь объявление прототипа метода; не надо пытаться искать его реализацию ниже и выдавать ошибку". Абстрактные методы реализуются в потомках класса, предоставляя уже конкретный функционал. Тем не менее, существует возможность обращения к таким методам напрямую из базового класса.

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

На самом деле это не совсем так. Декларация абстрактного метода помогает вылавливать некоторые ошибки и делает интерфейс класса более четким.

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

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

Наконец, объявление абстрактного метода в базовом классе, позволяет автоматически генерировать особый тип исключения: EAbstractError. Оно возникает в случае, если была произведена попытка вызова метода объявленного абстрактным в базовом классе но не реализованом в используемом потомке. В таком случае сразу ясно, где кроется ошибка. Если бы объявления не было, то возникло бы обычное исключение о том что метод не найден.

Примечание: Использование абстрактных методов особенно удобно при реализации примесей. Приведем пример стандартной примеси примесь Enumerable:

<source lang="kpp"> class Enumerable { public:

   abstract const function each(block b);
   abstract const function int compare(const x);
   const function bool all(block b = identity_block) {
       var result = true;
       this.each() { |...|
           if (!b.invoke(args())) {
               result = false;
               break;
           }
       };
       return result;
   }
   
   // (Другие методы примеси)

} </source>

Примесь Enumerable предоставляет классам коллекций несколько методов для итерации по элементам, выбору, поиску и возможности сортировки. Класс испольщующий примесь должен объявить у себя метод each(), который вызывает переданный блок последовательно передавая ему элементы коллекции. Если требуется использовать методы Enumerable::max, min или алгоритм сортировки, то необходимо также реализовать соответствующий метод compare(). Примеси эффективны там, где много различных классов могут реализовывать похожее поведение, однако наследовать их все от некотрого общего базового класса нерационально. В некотором роде, примесь это своеобразный "недокласс", экземпляры которого не является полностью самостоятельными сущностями, но поведение методов примеси в рамках другого класса может быть разумным. Так, напирмер вышеописанная примесь Enumerable предоставляет большое количество методов для работы с коллекциями (обработки элементов), однако она понятия не имеет, о каких именно элементах идет речь. Примесь не располагает механизмом сохранения и выборки элементов, предполагая что эта функциональность будет получена в результате "симбиоза" с классом, включающим данную примесь.

В данном случае мы видим, что примесь явным образом объявляет абстрактные методы each() и compare(). Эти два метода -- единственная внешняя зависимость примеси от класса, ее использующего.

Таким образом, мы можем использовать примесь в любом классе, который может и не являться коллекцией. В качестве примера можно привести такой код: <source lang="kpp"> class MyClass extends Enumerable {

   public const function each(block b) {
       b("hello");
       b("to");
       b("mixin!!!");
   }

}

export function main() {

    var c = new MyClass;
    var i = 1;
    c.collect() { |x| i++ to string + ' ' + x; }.each() { |x| puts(x); }

} </source>

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

1 hello
2 to
3 mixin!!!

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

Примечание: Метод collect() объявлен в стандартной библиотеке К++ (файл kpp.kpp).

[править] Поля

Поле класса — это некоторый объект, используемый объектом данного класса.

Объявление поля начинается с одного из трех ключевых слов:

  • var — объявление "обычного" поля;
  • const — данное поле является константой и не может быть изменено;
  • mutable — значение данного поля не влияет на состояние объекта, и его можно менять даже в методах, объявленных константными.

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

<source lang="kpp"> var int m_x; const m_y = 0; var m_stream = new stream; </source>

Тип поля определяется по следующим правилам:

  • если тип указан явно, ничего определять не надо;
  • если тип не указан, но при объявлении использован инициализатор — типом становится тип результата инициализатора;
  • в противном случае, для поля устанавливается динамический тип.

Примечание: В K++ доступ к полям имеет только объект класса — т.е. фактически, все поля находятся в закрытой (private) области видимости. Для предоставления внешним классам доступа к полям следует использовать свойства (см. ниже).

[править] Свойства

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

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

Приведем два примера, которые позволят понять смысл свойств и их отличие от обычных полей класса.

Предположим, что у нас есть класс, отвечающий за чтение состояния некоторого устройства. Допустим, состояние представляется целым числом и должно определяться по мере обращения. Если бы мы писали на языке C++, то мы оформили бы это в виде метода:

<source lang="cpp"> class MyDevice {

   int GetState();

}; </source>

Везде, где нам потребовалось бы читать состояние устройства мы должны были писать что-то типа:

<source lang="cpp"> int current_state = Device.GetState(); </source>

В случае с К++, чтение свойств осуществляется подобно обычным полям. Перепишем вышеописанный пример на язык К++:

<source lang="kpp"> class MyDevice {

   function int GetState();
   property int state read GetState;

} </source>

Соответственно, обращение к свойству состояния будет выглядеть так:

<source lang="kpp"> var current_state = Device.state; </source>

При обращении к свойству state будет автоматически вызван метод GetState(), результат которого будет возвращен как значение свойства. Вышеописанный пример кому-то может показаться странным, ведь получается, что мы усложнили код класса ради сомнительного выигрыша в коде обращения. На самом деле, в реальных условиях, с настоящими классами, с большим количеством свойств и в сложных выражениях, выигрыш становится куда более заметен. Сравните два примера одного и того же участка кода, один из которых написан на C++, другой на K++. Несмотря на то, что приведенный код тоже взят "с потолка", разница в читаемости уже более заметна. В целом, чем сложнее выражение и чем больше в нем применяется операций присваивания и доступа к полям классов — тем большее преимущество дает использование свойств:

<source lang="cpp"> Object1.SetStatus(Object2.GetStatus() > 0 ? Object2.GetStatus() : DefaultObject.GetStatus()); printf("object %s (%d) located at %s : status changed to %u",

   Object1.GetName(), Object1.GetIndex(), Object1.GetLocation(), Object1.GetStatus());

</source>

<source lang="kpp"> Object1.status = Object2.status > 0 ? Object2.status : DefaultObject.status; puts("object % (%) located at % : status changed to %",

   Object1.name, Object1.index, Object1.location, Object1.status);

</source>

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

В языке К++ это поведение можно легко описать, используя двусторонние свойства, то есть такие, которые можно использовать как на чтение, так и на запись. Логично предположить, что чтение такого свойства не должно сказываться на самом элементе управления, в то время как запись в свойство должна дать команду элементу управления изменить свое состояние и соответственно внешний вид. Вот пример описания некоторого абстрактного класса элемента управления:

<source lang="kpp" line="1"> class Widget {

   var m_Enabled = true; //поле, хранящее текущее состояние активности
   function void SetEnabled(const value) {
       var old_value = m_Enabled;
       m_Enabled = value;
       if (old_value != m_Enabled)
           Invalidate(); //Состояние изменилось, обновляем элемент управления
   }
   property enabled read m_Enabled write SetEnabled;
   //далее идет остальная часть класса, например методы отрисовки

} </source>

Теперь, если мы унаследуем некоторый класс от данного класса и переопределим соответствующие методы отрисовки, то у класса потомка так же можно будет использовать свойство enabled:

<source lang="kpp"> var myForm = new Form; //создаем окно var myButton = Button.CreateAtPos(myForm, 10, 10); //добавляем кнопку myButton.caption = "Click me!"; //устанавливаем подпись myButton.OnClick += { |x| x.enabled = false; }; //подключаем обработчик события myForm.Show(); //показываем окно </source>

Приведенный выше код создаст окно и разместит на нем кнопку (подразумевается, что класс Button унаследован от нашего класса Widget). Затем устанавливаются свойства кнопки, такие как подпись и блок обработчика события OnClick. При нажатии на кнопку она станет неактивной.




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

Оставшаяся часть зависит от того, какое свойство объявляется:

  • Если объявляется свойство на чтение, то указывается ключевое слово read, после которого идет либо идентификатор имени поля, которое нужно читать, либо имя метода, который должен использоваться как аксессор. В роли аксессора может выступать метод, не принимающий параметров и возвращающий некоторое значение, которое будет возвращаться как значение свойства.
  • Если объявляется свойство на запись, то указывается, соответственно ключевое слово write после которого идет либо имя поля, которое нужно записывать, либо имя метода, который должен использоваться как мутатор. В качестве мутатора может выступать метод, принимающий один параметр. Возвращаемое значение игнорируется, так что оно может быть любым.
  • Если объявляется свойство, доступное как на чтение, так и на запись, то указываются обе части, причем первой идет часть чтения.


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

Кратко, синтаксис объявления свойства можно описать в стиле справки к командам оболочки: <source lang="kpp"> property [тип] <имя> [read <аксессор|поле>] [write <мутатор|поле>]; </source>

Примечание 2: Существует альтернативный синтаксис описания аксессоров и мутаторов, при котором код соответствующий им записывается прямо в определении самого свойства. Это выглядит так:

<source lang="kpp"> class MyClass {

   var f = 1;
   property int read { f + 1; } write { |v| f = v; };

} </source>

И аксессор и мутатор, представлены здесь в виде inline конструкций, схожих по описанию (и смыслу) с inline блоками. Аксессор возвращает значение поля f, увеличенное на единицу, в то время как мутатор принимает некоторое значение v и записывает его в соответствующее поле без каких либо изменений.

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

[править] Расширения

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

Как правило, расширения применяются к классам стандартной библиотеки, либо к неуправляемым классам.

В качестве примера приведем код, расширяющий функциональность класса int с помощью свойства factorial. Расширения объявляются путем указания ключевого слова extend, после которого указывается идентификатор имени класса, который следует расширить. Затем идет тело расширения, такое же, как при описании классов:

<source lang="kpp" line="1"> package intmod_fact;

extend int {

   const function int GetFactorial() {
       var result = 1;
       for (var x = this; x > 1; x--)
           result *= x;
       return result;
   }
   property int factorial read GetFactorial;

}

export function main() {

   puts("Factorial of 10 is " + 10.factorial);

} </source>


3-11
Мы объявляем расширение класса int, реализованного в стандартной библиотеке. Добавляется частный метод GetFactorial(), и свойство factorial, связанное с методом. Как видно из названия, метод рассчитывает факториал числа, которое содержится в объекте. В данном контексте, специальная переменная this имеет тип int и ссылается на сам объект. Таким образом, для числа 10 переменная this будет равна 10.
14
Здесь мы видим применение расширения в действии. Константа 10 на момент компиляции преобразуется в константный объект класса int, который подобно любому другому объекту этого же класса будет иметь свойство factorial, которое мы и используем. При попытке чтения из этого свойства будет вызван метод GetFactorial(), результат выполнения которого возвращается как значение свойства, то есть как факториал числа.
Обратите внимание, что функция puts(), принимает в качестве параметра строку, в то время как тип свойства определен как int. В этом нет ничего странного, потому что класс int имеет оператор приведения типа к классу string, который вызывается компилятором автоматически. Таким образом, при вычислении значения выражения в скобках, сперва значение факториала приводится к типу строки, которая складываясь со строкой слева от оператора +, передается в качестве параметра функции.


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


[править] Смотри также

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
информация
документация
Инструменты