Основным понятием C# является объектно-ориен тированное программирование (ООП). Методика ООП не отделима от С#, и поэтому все программы на C# являются объектно-ориентированными хотя бы в самой малой сте пени. В связи с этим очень важно и полезно усвоить осно вополагающие принципы ООП, прежде чем приступать к написанию самой простой программы на С#.
ООП представляет собой эффективный подход к про граммированию. Методики программирования претер пели существенные изменения с момента изобретения компьютера, постепенно приспосабливаясь, главным образом, к повышению сложно сти программ. Когда, например, появились первые ЭВМ, программирование заклю чалось в ручном переключении на разные двоичные машинные команды с переднего пульта управления ЭВМ. Такой подход был вполне оправданным, поскольку програм мы состояли всего из нескольких сотен команд. Дальнейшее усложнение программ привело к разработке языка ассемблера, который давал программистам возможность работать с более сложными программами, используя символическое представление отдельных машинных команд. Постоянное усложнение программ вызвало потреб ность в разработке и внедрении в практику программирования таких языков высокого уровня, как, например, FORTRAN и COBOL, которые предоставляли программистам больше средств для того, чтобы как-то справиться с постоянно растущей сложностью программ. Но как только возможности этих первых языков программирования были полностью исчерпаны, появились разработки языков структурного программирова ния, в том числе и С.
На каждом этапе развития программирования появлялись методы и инстру ментальные средства для "обуздания" растущей сложности программ. И на каждом таком этапе новый подход вбирал в себя все самое лучшее из предыдущих, знаме нуя собой прогресс в программировании. Это же можно сказать и об ООП. До ООП многие проекты достигали (а иногда и превышали) предел, за которым структурный подход к программированию оказывался уже неработоспособным. Поэтому для пре одоления трудностей, связанных с усложнением программ, и возникла потребность в ООП.
ООП вобрало в себя все самые лучшие идеи структурного программирования, объединив их с рядом новых понятий. В итоге появился новый и лучший способ орга низации программ. В самом общем виде программа может быть организована одним из двух способов: вокруг кода (т.е. того, что фактически происходит) или же вокруг данных (т.е. того, что подвергается воздействию). Программы, созданные только мето дами структурного программирования, как правило, организованы вокруг кода. Такой подход можно рассматривать "как код, воздействующий на данные".
Совсем иначе работают объектно-ориентированные программы. Они организованы вокруг данных, исходя из главного принципа: "данные управляют доступом к коду". В объектно-ориентированном языке программирования определяются данные и код, которому разрешается воздействовать на эти данные. Следовательно, тип данных точ но определяет операции, которые могут быть выполнены над данными.
Для поддержки принципов ООП все объектно-ориентированные языки програм мирования, в том числе и С#, должны обладать тремя общими свойствами: инкапсу ляцией, полиморфизмом и наследованием. Рассмотрим каждое из этих свойств в от дельности. Инкапсуляция
Инкапсуляция — это механизм программирования, объединяющий вместе код и данные, которыми он манипулирует, исключая как вмешательство извне, так и не правильное использование данных. В объектно-ориентированном языке данные и код могут быть объединены в совершенно автономный черный ящик. Внутри такого ящика находятся все необходимые данные и код. Когда код и данные связываются вместе по добным образом, создается объект. Иными словами, объект — это элемент, поддержи вающий инкапсуляцию.
В объекте код, данные или же и то и другое могут быть закрытыми или же от крытыми. Закрытые данные или код известны и доступны только остальной части объекта. Это означает, что закрытые данные или код недоступны части программы, находящейся за пределами объекта. Если же данные или код оказываются открытыми, то они доступны другим частям программы, хотя и определены внутри объекта. Как правило, открытые части объекта служат для организации управляемого интерфейса с закрытыми частями.
Основной единицей инкапсуляции в C# является класс, который определяет форму объекта. Он описывает данные, а также код, который будет ими оперировать. В C# описание класса служит для построения объектов, которые являются экземплярами класса. Следовательно, класс, по существу, представляет собой ряд схематических опи саний способа построения объекта.
Код и данные, составляющие вместе класс, называют членами. Данные, определяе мые классом, называют полями, или переменными экземпляра. А код, оперирующий данными, содержится в функциях-членах, самым типичным представителем которых является метод. В C# метод служит в качестве аналога подпрограммы. (К числу других функций-членов относятся свойства, события и конструкторы.) Таким образом, методы класса содержат код, воздействующий на поля, определяемые этим классом. Полиморфизм
Полиморфизм, что по-гречески означает "множество форм", — это свойство, по зволяющее одному интерфейсу получать доступ к общему классу действий. Простым примером полиморфизма может служить руль автомашины, который выполняет одни и те же функции своеобразного интерфейса независимо от вида применяемого механизма управления автомашиной. Это означает, что руль действует одинаково не зависимо от вида рулевого управления: прямого действия, с усилением или реечной передачей. Следовательно, при вращении руля влево автомашина всегда поворачивает влево, какой бы вид управления в ней ни применялся. Главное преимущество единоо бразного интерфейса заключается в том, что, зная, как обращаться с рулем, вы сумеете водить автомашину любого типа.
Тот же самый принцип может быть применен и в программировании. Рассмотрим для примера стек, т.е. область памяти, функционирующую по принципу "последним пришел — первым обслужен". Допустим, что в программе требуются три разных типа стеков: один — для целых значений, другой — для значений с плавающей точкой, тре тий — для символьных значений. В данном примере алгоритм, реализующий все эти стеки, остается неизменным, несмотря на то, что в них сохраняются разнотипные дан ные. В языке, не являющемся объектно-ориентированным, для этой цели пришлось бы создать три разных набора стековых подпрограмм с разными именами. Но благодаря полиморфизму для реализации всех трех типов стеков в C# достаточно создать лишь один общий набор подпрограмм. Зная, как пользоваться одним стеком, вы сумеете воспользоваться и остальными.
В более общем смысле понятие полиморфизма нередко выражается следующим образом: "один интерфейс — множество методов". Это означает, что для группы взаи мосвязанных действий можно разработать общий интерфейс. Полиморфизм помогает упростить программу, позволяя использовать один и тот же интерфейс для описания общего класса действий. Выбрать конкретное действие (т.е. метод) в каждом отдельном случае — это задача компилятора. Программисту не нужно делать это самому. Ему достаточно запомнить и правильно использовать общий интерфейс. Наследование
Наследование представляет собой процесс, в ходе которого один объект приобре тает свойства другого объекта. Это очень важный процесс, поскольку он обеспечивает принцип иерархической классификации. Если вдуматься, то большая часть знаний поддается систематизации благодаря иерархической классификации по нисходящей. Например, сорт яблок "Джонатан" входит в общую классификацию сортов яблок, которые, в свою очередь, относятся к классу фруктов, а те — к еще более крупному классу пищевых продуктов. Это означает, что класс пищевых продуктов обладает ря дом свойств (съедобности, питательности и т.д.), которые по логике вещей распростра няются и на его подкласс фруктов. Помимо этих свойств, класс фруктов обладает свои ми собственными свойствами (сочностью, сладостью и т.д.), которыми он отличается от других пищевых продуктов. У класса яблок имеются свои характерные особенности (растут на деревьях, не в тропиках и т.д.). Таким образом, сорт яблок "Джонатан" на следует свойства всех предшествующих классов, обладая в то же время свойствами, присущими только этому сорту яблок, например красной окраской кожицы с желтым бочком и характерным ароматом и вкусом.
Если не пользоваться иерархиями, то для каждого объекта пришлось бы явно опре делять все его свойства. А если воспользоваться наследованием, то достаточно опреде лить лишь те свойства, которые делают объект особенным в его классе. Он может так же наследовать общие свойства своего родителя. Следовательно, благодаря механизму наследования один объект становится отдельным экземпляром более общего класса. Первая простая программа
А теперь самое время перейти к примеру конкретной программы на С#. Для на чала скомпилируем и выполним короткую программу. /* Это простая программа на С#. Назовем ее Example.cs. */ using System; class Example { // Любая программа на C# начинается с вызова метола Main(). static void Main() { Console.WriteLine("Простая программа на С#."); } }
Основной средой для разработки программ на C# служит Visual Studio корпорации Microsoft. Для компилирования примеров всех программ, приведенных для примера в этой книге, в том числе и тех, где используются новые средства C# 4.0, вам потребует ся Visual Studio 2010 или же более поздняя версия, поддерживающая С#.