SnakeがOOPを導入する方法単玔な単語の耇雑な抂念

こんにちは オンラむンプログラミングトレヌニングサヌビスであるGeekBrains.ruの線集スタッフに歓迎されおいたす。 Habréでブログを開始するこずにしたした プログラミング、IT、オンラむン教育の䞖界から倚くの興味深いこずを語り、議論する時間はただあるず確信しおいたす。 しかし、倚くのプレリュヌドなしで、孊生の䞀人からのCずOOPの基本に関する無料コヌスのレビュヌから、非垞に簡単に始めたしょう。 コヌスのスロヌガンには、「単玔な蚀葉の耇雑な抂念」ず曞かれおいたす。 これがどうなるか芋おみたしょう。







リスナヌに関するいく぀かの蚀葉手続き型プログラミング、Web開発、SQLに粟通したITプロゞェクトマネヌゞャヌ。 ビゞネスプロセスでの深い実装には、OOPの詳现な知識が必芁でした。 卒業生に䞀蚀。



「このようなプログラミングのゞョヌクがありたす。プログラミング蚀語は習埗が簡単です。倖囜語ずは異なり、単語がほずんどありたせん。 実際、コマンド、関数、ラむブラリ、デヌタ型、さらには構文の名前を孊ぶこずは、特にそれらの倚くが異なる蚀語で類䌌しおいるため、それほど難しくありたせん。 ただし、このステヌトメントがゞョヌクず呌ばれるのは理由がないわけではありたせん。特定のプログラミング蚀語で䜜業するには、原則、パラダむムの基瀎、および蚀語暙準を知る必芁がありたす。 あらゆるプログラミングパラダむムず同様に、オブゞェクト指向プログラミングには、すべおの蚀語に有効であり、いずれの堎合にも圹立぀䞀連の原則ずルヌルがありたす。



私自身は、オブゞェクト指向プログラミングの原則を習埗するための習熟コヌスを遞択したした。これは、Cで動䜜するプロゞェクトコン゜ヌルゲヌム「Snake」の䜜成に基づいおいたす。 これは、いく぀かの䞖代が講矩で時間を぀ぶし、テトリスやノキアの癜黒携垯電話で遊んでいた同じ蛇です。 しかし、あなたのおもちゃを曞くこずは、はるかに楜しく、そしお最も重芁なこずには、より䟿利だず蚀わなければなりたせん。 ゲヌムの䜜成䞭に、教垫はOOPのすべおの原則を明らかにするため、各原則は、課された退屈な理論ずしおではなく、頭の䞭ですでに発生した質問に察する解決策ずしお認識されたす。



プログラムの開始時に、私はすぐに開発者が䜿甚する2぀の最新ツヌルに突入したした。





遞択した蚀語はCですが、すでに実践から理解しおいるように、OOPの原則は同じであり、別の蚀語を孊習するずきに簡単に適甚できたす。



最初は、教垫は補品が開発されるずいう事実に焊点を合わせたす。 蛇に萜ちた遞択は偶然ではありたせん-誰もがゲヌムのロゞック、その機胜ず芁件を知っおいたす。 たた、開発では、初期段階で将来のプロゞェクトの党䜓像を把握するこずが重芁です。 このようなビゞョンは、それを意味のある段階に分解し、倚くの省略を回避するのに圹立ちたす。



最初の2぀のレッスンは、プログラミングにたったく慣れおいない人でも簡単に理解できるものです。 䌝統的に、仕事は幞せな「Hello、world」から始たりたす。



namespace Snake { class Program { static void Main( string[] args ) { Console.WriteLine("Hello world"); Console.ReadLine(); } } }
      
      









もう䞀床、関数ずは䜕か、どのように機胜するか、倉数はどのように䜜成されるかを繰り返したした。 コヌドを蚘述するために、手続き型のアプロヌチが䜿甚されたす-入力で指定されたパラメヌタヌを䜿甚しお、関数が順次適甚されたす。 mainのmain関数内にすべおのコヌドを䜜成するこずの2぀の欠点がすぐに明らかになりたす。コヌドの成長ず、この関数内での倉数の宣蚀です。



 namespace Snake { class Program { static void Main( string[] args ) { int x1 = 1; int y1 = 3; char sym1 = '*'; Draw( x1, y1, sym1 ); int x2 = 4; int y2 = 5; char sym2 = '#'; Draw( x2, y2, sym2 ); Console.ReadLine(); } static void Draw(int x, int y, char sym) { Console.SetCursorPosition( x, y ); Console.Write( sym ); } } }
      
      





実際、最初の2぀のクラスの埌は、かなり耇雑なこずを理解するこずから喜びを感じおいたす。 自分でチェックしたので、聎衆のコメントを賌読したした。







3回目の講矩では、クラスの抂念、デヌタ型に぀いお知りたした。 クラスはOOPの基本抂念の1぀であるため、その孊習には现心の泚意が払われたす。 倉数は、クラスのむンスタンス、぀たりオブゞェクトずしお䜜成され始めたすしたがっお、OOPの名前。



リスナヌが初心者の堎合、圌はコヌドの蚀語ず匏を理解するこずを孊びたすPoint p1 = new Point; 「オブゞェクトp1はPointクラスのむンスタンスずしお䜜成され、入力で座暙を取埗したす」ず認識され始めたす。



 namespace Snake { class Point { public int x; public int y; public char sym; public void Draw() { Console.SetCursorPosition( x, y ); Console.Write( sym ); } } }
      
      





同じレッスンで、生埒はコンピュヌタヌのように考えるこずを孊びたす。 これは、ブレヌクポむントを䜿甚し、デバッガヌを介しおコヌドを枡すこずで発生したす。ステップごずに、クラスオブゞェクトの䜜成、倉数の初期化、関数の操䜜Drawメ゜ッドの呌び出しを確認できたす。







4番目のレッスンでは、Pointクラスのコンストラクタヌを䜜成したす。これは、䜕も返さない特別な構文を持぀明瀺的に䜜成されたコンストラクタヌです。



 public Point(int _x, int _y, char _sym) { x = _x; y = _y; sym = _sym; }
      
      





コンストラクタヌを䜜成した埌、メむンプログラムのコヌドの量がどのように削枛されるかに気付きたした。 コンストラクタヌは、ポむントの座暙ずその指定のシンボルを入力ずしお受け入れたすが、ナヌザヌには実装の詳现は衚瀺されたせん-それらはコンストラクタヌ内に隠されおいたす。 そこで私は、OOPの3぀の原則の最初であるカプセル化に出䌚いたした。 カプセル化はシステムのプロパティであり、デヌタずメ゜ッドを組み合わせおクラスで䜿甚し、すべおの実装の詳现をナヌザヌから隠すこずができたす。



5番目の講矩では、メモリ構成の問題、プログラムがスタックずヒヌプでどのように機胜するかに぀いお詳しく説明したす。 説明は芖芚的な図によっお補足されたす。 その埌、䜜業は暙準Cリストラむブラリリストの新しいクラスから始たりたす。このクラスでは、芁玠を远加および削陀するための関数が䜜成され、foreachルヌプが䜜成されたす。



 List<int> numList = new List<int>(); numList.Add( 0 ); numList.Add( 1 ); numList.Add( 2 ); int x = numList[ 0 ]; int y = numList[ 1 ]; int z = numList[ 2 ]; foreach(int i in numList) { Console.WriteLine( i ); } numList.RemoveAt( 0 ); List<Point> pList = new List<Point>(); pList.Add( p1 ); pList.Add( p2 ); Console.ReadLine(); } }
      
      





デバッガヌでルヌプを操䜜するず、リスナヌはプログラムの構造ずシヌケンスをより明確に理解したす。

ゲヌムを実装するために、ヘビ甚の氎平および垂盎の障害物ラむンを䜜成したしたが、これらはポむントのリストにすぎたせん。 私は教垫に遅れを取らず、圌のコヌドを敎理し、独自のプログラムを䜜成し、プログラムでトレヌニングしたした。



 namespace Snake { class HorizontalLine { List<Point> pList; public HorizontalLine(int xLeft, int xRight, int y, char sym) { pList = new List<Point>(); for(int x = xLeft; x <= xRight; x++) { Point p = new Point( x, y, sym ); pList.Add( p ); } } public void Drow() { foreach(Point p in pList) { p.Draw(); } } } }
      
      





先生は、ポむントずラむンの䞡方、そしお埌に動くヘビ自䜓が本質的に数字であるこずに泚意しおいるので、コヌドを最適化し、コヌドを再利甚しお再利甚できる゜リュヌションが必芁です。 だから私はOOPの2番目の原則である継承に぀いお知りたした。 継承はシステムのプロパティであり、機胜を郚分的たたは完党に眮き換えた既存のクラスに基づいお新しいクラスを蚘述するこずができたす。 したがっお、各ラむン、スネヌク、およびポむントは、クラスFigureclass Horizo​​ntalLineFigureからの特別なケヌス継承になりたす。



 namespace Snake { class Figure { protected List<Point> pList; public void Drow() { foreach ( Point p in pList ) { p.Draw(); } } } }
      
      





継承されたクラスには必ず芪クラスの特性が含たれたすが、独自のクラスが含たれるこずもありたす。 継承の䟋は、教科曞ずクラスAから継承されたクラスのわかりやすい䟋によっおさらに分析されたす。ワヌカヌは、芪クラスから成長ず幎霢を持ち、自身の特性である絊䞎です。 ずころで、OOPでの継承の自己孊習の目的のためには、孊生カヌドたたは埓業員カヌドの蚭蚈に取り組むのが最善です。これをすぐに理解し、たず自分で知識を修正しおから、プロゞェクトで䜜業したす。



そしお、ヘビはフィヌルドで移動するこずを孊び、キヌボヌドからの矢印で制埡する必芁がありたす。 タスクは難しいように芋えたすが、私たちはただコン゜ヌルに぀いお話しおいるので、ヘビの動きの実装は可胜な限り簡単であるべきだず思い出したした。 私はすでに、ヘビが4方向、぀たり成長たたは枛少する方向に移動する必芁があるこずを知っおいたした。 そしお、ここで抜象化の時が来たす-オブゞェクトの遞択された重芁な特性に基づいおコヌドが蚘述され、マむナヌな特性が陀倖される状況。 重芁な兆候を遞択したす。ヘビは、マップ䞊のポむントからの図圢であり、開始䜍眮、座暙を持ち、4぀の方向のいずれかに移動したす。 Snakeクラスは倧きく倉わり、成長しおいたす。



 { class Snake : Figure { public Snake( Point tail, int length, Direction direction ) Direction direction; public Snake( Point tail, int length, Direction _direction ) { direction = _direction; pList = new List<Point>(); for(int i = 0; i < length; i++) for ( int i = 0; i < length; i++ ) { Point p = new Point( tail ); p.Move( i, direction ); pList.Add( p ); } } internal void Move() { Point tail = pList.First(); pList.Remove( tail ); Point head = GetNextPoint(); pList.Add( head ); tail.Clear(); head.Draw(); } public Point GetNextPoint() { Point head = pList.Last(); Point nextPoint = new Point( head ); nextPoint.Move( 1, direction ); return nextPoint; } } }
      
      





䞀般に、抜象化に぀いお話し続けるず、抜象クラスの抂念がOOPで広く䜿甚されたす。 珟時点で開発者が認識しお必芁ずしおいる機胜のみを実装するテンプレヌトクラスが䜜成されたす。 抜象から掟生したクラスは、将来すべおの機胜を補完できるようになりたす。

しかし、プロゞェクトに戻りたす。 別の列挙デヌタ型が䜿甚されるDirectionクラスが衚瀺されたす。これは、名前付き定数のセットで構成される列挙です。 私たちの堎合、これらは方向定数です右、巊、䞊、䞋。 PointクラスにはMoveメ゜ッドがありたす。



 public void Move(int offset, Direction direction) { if(direction == Direction.RIGHT) { x = x + offset; } else if(direction == Direction.LEFT) { x = x - offset; } else if(direction == Direction.UP) { y = y + offset; } else if(direction == Direction.DOWN) { y = y - offset; } }
      
      





したがっお、ヘビの動きは、スペヌスで尟を磚くず䜍眮のシフトずしお実珟されたす。 ヘビはキヌで制埡され、制埡は次のように実装されたす。



 public void HandleKey(ConsoleKey key) { if ( key == ConsoleKey.LeftArrow ) direction = Direction.LEFT; else if ( key == ConsoleKey.RightArrow ) direction = Direction.RIGHT; else if ( key == ConsoleKey.DownArrow ) direction = Direction.DOWN; else if ( key == ConsoleKey.UpArrow ) direction = Direction.UP; }
      
      





繰り返しになりたすが、カプセル化に遭遇したした-スネヌク管理はスネヌククラスに入りたす。

次の段階で、ヘビが食べ始め、FoodCreator機胜を䜿甚しお無限のサむクルで獲物が䜜成され、ヘビの頭の座暙ず食物を衚すポむントがチェックされたす。



 while (true) { if(snake.Eat( food ) ) { food = foodCreator.CreateFood(); food.Draw(); } else { snake.Move(); } Thread.Sleep( 100 ); if (Console.KeyAvailable) { ConsoleKeyInfo key = Console.ReadKey(); snake.HandleKey( key.Key ); } }
      
      





ヘビが無限ルヌプで食事をし、Wallクラスで䜜業するための障害を䜜成しお、3番目のOOPパラダむム-ポリモヌフィズム、さたざたなタむプのデヌタを凊理する機胜の胜力に぀いお孊びたした。 OOPでは、ポリモヌフィズムずは、オブゞェクトが基本クラスの䜜成時に存圚しなかった掟生クラスのメ゜ッドを䜿甚するこずです。 実行時に、掟生クラスのオブゞェクトは、メ゜ッドパラメヌタヌ、コレクション、配列などの堎所にある基本クラスのオブゞェクトず芋なすこずができたす。 これが発生するず、宣蚀された型は実行時に型自䜓ず䞀臎しなくなりたす。 ポリモヌフィズムはすぐには理解されないので、すぐに予玄をしなければなりたせん。もう䞀床講矩を聎き、長い間手元にあり、翌で埅っおいたシルトの玠晎らしい教科曞に目を向ける必芁がありたした。



最埌のレッスンで、ヘビは完党に独立し、障害物や自分のヘビの尟ずの衝突を凊理するこずを孊びたした。 講矩のコヌドは生成されなくなりたしたが、リポゞトリから取埗され、逆アセンブルされたす。 私は他の人のコヌドをコピヌする誘惑に埓わず、しばらくの間、自分で䜜成したコヌスを聞いおから、䜕床も䜕床も講矩に目を向けたした。 仕事ず理解には知識ず知識が必芁なので、同じこずをするこずをお勧めしたす。 GitHubに行っお、メむンコヌドが52行しかないシンプルなゲヌムを実装する方法を理解できるようにするための十分なティヌザヌを䞎えたこずを願っおいたす。぀たり、OOPのすべおの原則が正垞に適甚されたこずを意味したす。



芁玄するず、教垫は再びメむンのOOPパラダむムに戻り、パブリックおよびプラむベヌトアクセス修食子に泚意を匕き、仮想キヌワヌドに぀いお話したす。これにより、メ゜ッドを継承クラスで再定矩できたす。 プラむベヌトはオブゞェクト内のプラむベヌトデヌタずコヌドであり、パブリックはオヌプンです。 プラむベヌトデヌタずコヌドは、同じオブゞェクトの別の郚分からのみ利甚できたす。぀たり、倖郚からアクセスするこずはできたせん。 オヌプンデヌタずコヌドは、プログラムのどの郚分からもアクセス可胜であり、倚くの堎合、オブゞェクトの閉じた郚分ぞのむンタヌフェヌスずしお機胜したす。

コヌス党䜓に぀いお話すず、助けになりたした-私の仕事の質ず開発者ずのコミュニケヌションのレベルの䞡方が倉化したした。 少なくずもプログラミングに少し興味がある人には、ぜひ詊しおみおください。少なくずも脳を発達させ、䜓系的に考えるこずを教えたす。 私は間違いなく他のコヌスに耳を傟け、専門家ずチャットしたす。 さお、勇敢な新参者に幞運を祈りたす」



ビデオ圢匏がコンテンツ、広告、管理でどのように人気になっおいるこずに気づきたしたか ビデオが芖芚ず聎芚の䞡方を即座に匕き蟌むこずはよく知られおいたす。 さらに、ビデオコヌスを停止、巻き戻し、さらに数回聎き、コメントで質問するこずができたす。 さらに、 GeekBrainsは、プログラミングが日垞的な仕事であるため、業界の最新トレンドを垞に把握しおいる開業医を指導しおいたす。 もちろん、モニタヌの前でお茶を飲みながらコヌスを芋るのはほずんどメリットがないので、結論ずしお、芖聎者にアドバむスをしたいず思いたす。





独孊のための時間が無駄になるこずはないず確信しおいたす。 それは間違いなく報われるでしょう。



All Articles