Программирование >>  Программирование с использованием ajax 

1 ... 73 74 75 [ 76 ] 77 78 79 ... 396


using System.Linq; using System.Text; using Ch09ClassLib;

namespace Ch09Ex02 {

class Program {

static void Mam (string [ ] args) {

MyExternalClass xnyObj = new MyExternalClass () ; Console .WriteLine (xnyObj . ToString ()) ; Console.ReadKey();

Obiecl Browser

Biowtce All Componenlf <Se ch>

Ы о Ch09Cl8JUib

Б MyCxternelClBJj Ы BejeTypcJ ij Object

u 9 Ch09Ex02

f£ -J Microjoft Build Converjionv3 5

Microsoft Build Engine ll Microioft Build.Framework Л. Л Microjoft Build Utilltiejv3.5 1 MicrojoftVisuaiBesic Ш . J MicrojoftVljuBiC SnClR \i} mjcorlib

I A}5emblyCh09CUffLib

C\BegVCSh8rp\ChepterO9\ChO9Cl8ssLib\Ch09Cl8sjLib\bin \Debug\Ch09ClejjLib.dll

Puc. 9.12. Просмотр содержимого добавленной ссылки в окне Object Browser

13. Запустите приложение. На рис. 9.13 показан результат, который должен получиться.


Рис. 9.13. Приложение Ch09Ex02 в действии

Описание полученных результатов

в этом примере были созданы два проекта: проект типа библиотеки классов и проект типа консольного приложения. Первый называется Ch09ClassLib и содержит два класса: MyExternalClass, который является общедоступным, и MylnternalClass, который является доступным только внутри проекта. Обратите внимание, что последний по умолчанию был неявным при создании, поскольку не имел никакого модификатора доступа. Однако уровень доступности рекомендуется указывать явно, поскольку это делает код более удобочитаемым, из-за чего и было добавлено ключевое слово internal. Что касается проекта типа консольного приложения, то он называется Ch09Ex02 и содержит простой код, применяющий проект библиотеки классов Ch09ClassLib.



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

Чтобы использовать классы из Ch0 9ClassLib, вы добавили в консольное приложение Ch0 9Ex02 ссылку на Ch0 9ClassLib.dll. То есть в данном примере вы просто указали на выходной файл библиотеки классов, хотя могли бы так же легко и скопировать этот файл в какую-то локальную папку Ch09Ex02, что позволило бы продолжать разработку библиотеки классов без оказания воздействия на само консольное приложение. Для замены старой версии сборки новой тогда было бы достаточно просто скопировать сгенерированный новый файл DLL-библиотеки поверх старого.

После добавления ссылки вы просмотрели доступные файлы с помощью окна Object Browser. Поскольку класс MylnternalClass является внутренним, его в этом окне видно не было - он не доступен для внешних проектов. Класс MyExternalClass, однако, доступен для внешних проектов, и именно он и применяется в консольном приложении.

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

static void Main(string[] args) {

MylnternalClass myObj = new MylnternalClass () ;

Console.WriteLine(myOb].ToString ()); Console.ReadKey 0;

При попытке скомпилировать этот код, однако, компилятор выдал бы сообщение об ошибке:

Ch09ClassLib.MylnternalClass is inaccessible due to its protection level ChOBClassLib.MylnternalClass является недоступным из-за его уровня защиты

Такой прием использования классов из внешних сборок является ключевым в программировании на С# и .NET Franiework. На самом деле при использовании любых классов из .NET Framework тоже применяется именно он, поскольку эти классы обрабатываются тем же самым образом.

Интерфейсы или абстрактные классы

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

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

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



ТО ИХ, наоборот, может быть в классах сколько угодно, но никакой серьезной разницы это не дает - похожие результаты могут достигаться и в том, и в другом случае. Просто подход с интерфейсами немного отличается.

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

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

Например, рассмотрим семейство объектов, представляющих поезда. В базовом классе - Train (Поезд) - должно содержаться основное определение поезда, вроде информации о ширине колеи и типе двигателя (который может быть паровым, дизельным и т.д.). Однако такой класс должен быть абстрактным, поскольку такого понятия, как универсальный поезд, не существует. Создание настоящего поезда требует добавления характеристик, отражающих специфику конкретно данного поезда, т.е., например, создания производных классов вроде PassengerTrain (Пассажирский поезд), FreightTrain (Товарный поезд) и 42 4DoubleBogey (Двухосный поезд 424), как показано на рис. 9.14.

Train

PassengerTrain

FreightTrain

424DoubleBogey

Рис. 9.14. Диаграмма классов, представляющих поезда

Аналогичным образом можно определить и семейство объектов, представляющих автомобили, с абстрактным базовым классом Саг (Автомобиль) и производными классами вроде Compact (Малолитражка), SUV (Внедорожник) и PickUp (Пикап). Тогда классы Саг и Train могут даже наследоваться от одного общего базового класса, например. Vehicle (Транспорт), как показано на рис. 9.15.



1 ... 73 74 75 [ 76 ] 77 78 79 ... 396

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика