Главная страница
Навигация по странице:

  • Наследование конструкторов

  • 2) позволяет получить доступ к члену базового класса, который скрыт "за" членом производного класса.

  • Билет №20. Деструкторы и конструкторы классов. Конструкторы

  • Конструкторы экземпляра

  • Билет №22. Операции классов

  • Билет №24. Переменные базового класса и производного класса. Виртуальные методы.

  • Билет № 25. Абстрактные методы и классы

  • Билет №27. Стандартные интерфейсы .Net.

  • шпоргалка исис. Билет 1. Платформа Microsoft. Net Framework 0


    Скачать 0.77 Mb.
    НазваниеБилет 1. Платформа Microsoft. Net Framework 0
    Анкоршпоргалка исис.pdf
    Дата29.07.2018
    Размер0.77 Mb.
    Формат файлаpdf
    Имя файлашпоргалка исис.pdf
    ТипДокументы
    #22205
    страница5 из 7
    1   2   3   4   5   6   7

    Наследование
    Класс в С# может иметь произвольное количество потомков и только одного предка.
    При описании класса имя его предка записывается в заголовке класса после двоеточия. Если имя предка не указано, предком считается базовый класс всей иерархии System.Object. Синтаксис наследования:
    [атрибуты] [спецификаторы] class имя_класса [: предки]
    { тело_класса}
    Обратите внимание на то, что слово «предки» присутствует в описании класса во множественном числе, хотя класс может иметь только одного предка. Это связано с тем, что класс наряду с единственным предком-классом может наследовать интерфейсы (специальный вид классов, не имеющих реализации). Интерфейсы будут рассмотрены чуть позже.
    Класс, который наследуется, называется базовым. Класс, который наследует базовый класс, называется производным. Производный класс, наследует все переменные, методы, свойства, операторы и индексаторы, определенные в базовом классе, кроме того в производный класс могут быть добавлены уникальные элементы или переопределены существующие.
    Наследование конструкторов
    В иерархии классов как базовые, так и производные классы могут иметь собственные конструкторы. При этом конструктор базового класса создает часть объекта, соответствующую базовому классу, а конструктор производного класса — часть объекта, соответствующую производному классу. Так как базовый класс не имеет доступа к элементам производного класса, то их конструкторы должны быть раздельными.
    Если же конструкторы определены и в базовом, и в производном классе, то процесс создания объектов несколько усложняется, т.к. должны выполниться конструкторы обоих классов. В этом случае используется ключевое слово base, которое имеет два назначения:
    1) позволяет вызвать конструктор базового класса:
    Производный класс может вызывать конструктор, определенный в его базовом классе, используя расширенную форму объявления конструктора и ключевое слово base. Формат расширенного объявления: конструктор_производного_класса (список_параметров) : base (список_аргументов)
    { тело конструктора } где с помощью элемента списка аргументов передаются параметры конструктору базового класса.
    2) позволяет получить доступ к члену базового класса, который скрыт "за" членом производного класса.
    В этом случаеключевое слово base действует подобно ссылке this, за исключением того, что ссылка base всегда указывает на базовый класс для производного класса, в котором она используется. В этом случае формат ее записи выглядит следующим образом: base.член_класса
    Здесь в качестве элемента член_класса можно указывать либо метод, либо поле экземпляра. Эта форма ссылки base наиболее применима в тех случаях, когда имя члена в производном классе скрывает член с таким же именем в базовом классе.
    Билет №26. Интерфейсы.
    Интерфейсы
    В объектно-ориентированном программировании иногда требуется определить, что класс должен делать, а не как он будет это делать. Такой подход может быть реализован с помощью абстрактного класса, при этом в абстрактном классе часть методов может быть реализована, часть нет. Кроме этого в С# предусмотрена возможность полностью отделить структуру класса от его реализации. Это делается с помощью интерфейса.
    Интерфейс – это «крайний случай» абстрактного класса, в котором не предусмотрена ни одна реализация члена класса. Таким образом, интерфейс описывает функциональность классов, но не определяет способа ее реализации. Каждый класс, наследуя интерфейс, может реализовать его элементы по- своему. Так достигается полиморфизм – объекты разных классов по-разному реагируют на вызовы одного и того же метода.
    Синтаксис интерфейса:
    [атрибуты] [спецификаторы] interface имя_интерфейса : [предки]
    {
    //объявление функциональных членов интерфейса без реализации

    }
    Для интерфейса могут быть указаны спецификаторы new, public, internal и private.
    Спецификатор new применяется для вложенных интерфейсов и имеет такой же смысл, как и соответствующий спецификатор метода класса. По умолчанию интерфейс доступен только из сборки, в которой он описан (internal).
    Все функциональные члены интерфейса по умолчанию являются открытыми (public) и абстрактными (abstract), поэтому при описании метода указывается только типа возвращаемого им значения и сигнатуры.
    В качестве функциональных членов в интерфейсе можно объявлять сигнатуры методов, свойств, индексаторов и событий (для Windows-приложений). Интерфейсы не могут содержать члены данных, конструкторы, деструкторы или операторные методы (методы, переопределяющие операции). Ни один член интерфейса не может быть объявлен статическим.
    Напомним, что класс может наследовать один базовый класс и несколько интерфейсов. Класс, наследующий интерфейс, должен реализовать его в полном объеме. Т.к. функциональные члены, объявленные внутри интерфейса, являются открытыми, то их реализация также должна быть открытой.
    Кроме того, сигнатура функционального члена в реализации должна в точности совпадать с сигнатурой, заданной
    в определении интерфейса.
    Билет №20. Деструкторы и конструкторы классов.
    Конструкторы
    Конструктор предназначен для инициализации объекта. Конструкторы делятся на конструкторы класса (для статических классов) и конструкторы экземпляра класса (всех остальных классов).
    Конструкторы экземпляра
    Конструктор экземпляра вызывается авто матически при создании объекта класса с помощью операции new. Имя конструктора совпадает с именем класса. Рассмотрим основные свойства конструкторов:
    1.
    Конструктор не возвращает значение, даже типа void.
    2.
    Класс может иметь несколько конструкторов с разными параметрами для раз ных видов инициализации.
    3.
    Если программист не указал ни одного конструктора или какие-то поля не были инициализированы, полям значимых типов присваивается нуль, полям ссылочных типов — значение null.
    Если же при создании объектов требуется присваивать полю разные значения, это следует делать с помощью явного задания конструктора.
    Конструкторы класса
    Статические классы содержат только статические члены, в том числе и контруктор, которые храняться в памяти в единственном экземпляре. Поэтому создавать экземпляры класса нет смысла.
    Чтобы подчеркнуть этот факт, в первой версии С# для статических классов создавали два конструктора, один - пустой закрытый (private) конструктор, второй - статический конструктор, не имеющий параметров. Первый конструктор предотвращал попытки создания экземпляров класса. Второй конструктор автоматически вызывается системой до первого обращения к любому элементу статического класса, выполняя необходимые действия по инициализации. Вышесказанное отражено в следующем примере: class Demo
    { static int a; static int b; private Demo(){} //закрытый конструктор static Demo() //статический конструктор
    { a=10; b=2;
    } public static void Print ()
    {
    Console.WriteLine("{0}+{1}={2}",a,b,a+b);
    Console.WriteLine("{0}*{1}={2}",a,b,a*b);
    Console.WriteLine("{0}-{1}={2}",a,b,a-b);
    }
    } class Program
    { static void Main()
    {
    //Demo S=new Demo(); //ошибка содать экземпляр класса нельзя
    Demo.Print();
    }
    }
    В версию 2.0 введена возможность описывать статический класс, то есть класс с модификатором static. Экземпляры такого класса создавать запрещено, и кроме того, от него запрещено наследовать. Все элементы такого класса должны явным образом объявляться с модификатором static (константы и вложенные типы классифицируются как статические элементы автоматически). Конструктор экземпляра для статического класса задавать запрещается. static class Demo
    { static int a=20; static int b=10; public static void Print ()
    {
    Console.WriteLine("{0}+{1}={2}",a,b,a+b);
    Console.WriteLine("{0}*{1}={2}",a,b,a*b);
    Console.WriteLine("{0}-{1}={2}",a,b,a-b);
    }
    } class Program
    { static void Main()
    {
    Demo.Print();
    }
    }
    Деструкторы
    В С# существует специальный вид метода, называемый деструктором, который вызывается сборщиком мусора непосредственно перед удалением объекта из памяти.
    В деструкторе описываются действия, гарантирующие корректность последующего удаления объекта. Например, проверяется все ли ресурсы, используемые объектом, освобождены (файлы закрыты, удаленное соединение разорвано и т. п.).
    Синтаксис деструктора:
    [атрибуты] [extern]

    имя_класса()
    {тело_деструктора}
    Деструктор не имеет параметров, не возвращает значения и не требует указания спецификаторов доступа. Его имя совпадает с име- нем класса и предваряется тильдой (), символизирующей обратные по отношению к конструктору действия. Тело деструктора представляет собой блок или просто точку с запятой. Если деструктор определен как внешний, то используется спецификатор extern.
    В общем случае применение деструкторов замедляет процесс сборки мусора. Поэтому создавать деструкторы следует только тогда, когда необходимо освободить какие-то ресурсы перед удалением объекта.
    Билет №22. Операции классов
    Операции класса
    С# позволяет переопределить большинство операций так, чтобы при использовании их объектами конкретного класса выполнялись действия, отличные от стандартных. Это дает возможность применять объекты собственных типов данных в составе выражений, например: newObject x, y, z;
    … z = x+y;
    // используется операция сложения, переопределенная для класса newObject
    Определение собственных операций класса называют перегрузкой операций. Перегрузка операций обычно применяется для классов, для которых семантика операций делает программу более понятной. Если назначение операции интуитивно непонятно, перегружать такую операцию не рекомендуется.
    Операции класса описываются с помощью методов специального вида, синтаксис которых выглядит следующим образом:
    [ атрибуты] спецификаторы объявитель_операции
    {тело}
    При описании операций необходимо соблюдать следующие правила:
    1)
    операция должна быть описана как открытый статический метод класса (public static);
    2)
    параметры в операцию должны передаваться по значению (то есть недопустимо использовать параметры ref и out);
    3)
    сигнатуры всех операций класса должны различаться;
    4)
    типы, используемые в операции, должны иметь не меньшие права доступа, чем сама операция (то есть должны быть доступны при использовании операции).
    Унарные операции
    В классе можно переопределять следующие унарные операции: + - ! ++ --, а также константы true и false. При этом, если была перегружена константа true, то должна быть перегружена и константа false, и наоборот.
    Синтаксис объявителя унарной операции: тип operator унарная_операция (параметр)
    Примеры заголовков унарных операций: public static int operator + (DemoArray m) public static DemoArray operator --(DemoArray m) public static bool operator true (DemoArray m)
    Операции не должны изменять значение передаваемого им операнда. Операция, возвращающая величину типа класса, для которого она определяется, должна создать новый объект этого класса, выполнить с ним необходимые действия и передать его в качестве результата.
    Бинарные операции
    При разработке класса можно перегрузить следующие бинарные операции: + - * / % & | ^
    << >> == != < > <= >=. Обратите внимание, операций присваивания в этом списке нет.
    Синтаксис объявителя бинарной операции: тип operator бинарная_операция (параметр1, параметр 2)
    Примеры заголовков бинарных операций: public static DemoArray operator + (DemoArray a, DemoArray b) public static bool operator == (DemoArray a, DemoArray b)
    При переопределении бинарных операций нужно учитывать следующие правила:
    1)
    Хотя бы один параметр, передаваемый в операцию, должен иметь тип класса, для которого она определяется.
    2)
    Операция может возвращать величину любого типа.
    3)
    Операции отношений определяются только парами и обычно возвращают логическое значение. Чаще всего переопределяются операции сравнения на равенство и неравенство для того, чтобы обеспечить сравнение значения некоторых полей объектов, а не ссылок на объект. Для того чтобы переопределить операции отношений, требуется знание стандартных интерфейсов, которые будет рассматриваться чуть позже.
    Билет №24. Переменные базового класса и производного класса. Виртуальные методы.
    Переменные базового класса и производного класса
    С# является языком со строгой типизацией, в нем требуется строгое соблюдение совместимости типов с учетом стандартных преобразований типов. Из чего следует, что переменная одного типа обычно не может ссылаться на объект другого ссылочного типа. За одним небольшим исключением – ссылочная переменная базового класса может ссылаться на объект любого производного класса. class DemoPoint
    { public int x; public int y; public void Show()
    {
    Console.WriteLine("точка на плоскости: ({0}, {1})",x, y);
    } public DemoPoint (int x, int y)
    { this.x=x; this.y=y;
    }
    } class DemoShape : DemoPoint
    { public int z; new public void Show()
    {
    Console.WriteLine("точка в пространстве: ({0}, {1}, {2})", x, y, z);
    } public DemoShape(int x, int y, int z):base(x, y)
    { this.z=z;
    }
    } class Program
    { static void Main()
    {
    DemoPoint point1 = new DemoPoint(0,1);
    Console.WriteLine("({0}, {1})",point1.x,point1.y);
    DemoShape pointShape = new DemoShape(2,3,4);
    Console.WriteLine("({0}, {1}, {2})",pointShape.x, pointShape.y, pointShape.z);
    DemoPoint point2=pointShape; //допустимая операция
    //ошибка - не соответствие типов указателей
    //pointShape=point1;
    Console.WriteLine("({0}, {1})", point2.x, point2.y);
    //ошибка, т.к. в классе DemoPoint нет поля z
    //Console.WriteLine("({0}, {1}, {2})", point2.x, point2.y, point2.z);
    }
    }
    Ошибка возникнет и при попытке через объект point2 обратиться к методу Show.
    Например, point2.Show(). В этом случае компилятор не сможет определить, какой метод Show вызвать – для базового или для производного класса. Для решения данной проблемы можно воспользоваться таким понятием как полиморфизм, который основывается на механизме виртуальных методов.
    Виртуальные методы
    Виртуальный метод – это метод, который объявлен в базовом классе с использованием ключевого слова virtual, и затем переопределен в производном классе с помощью ключевого слова override. При этом если реализована многоуровневая иерархия классов, то каждый производный класс может иметь свою собственную версию виртуального метода. Этот факт особенно полезен в случае, когда доступ к объекту производного класса осуществляется через ссылочную переменную базового класса. В этой ситуации С# сам выбирает какую версию виртуального метода нужно вызвать. Этот выбор производится по типу объекта, на которую ссылается данная ссылка.
    Таким образом, благодаря полиморфизму через ссылочную переменную возможно обращаться к объектам разного типа, а также с помощью одного и того же имени выполнять различные действия.
    Билет № 25. Абстрактные методы и классы
    Иногда полезно создать базовый класс, определяющий только своего рода "пустой бланк", который унаследуют все производные классы, причем каждый из них заполнит этот "бланк" собственной информацией. Такой класс определяет структуру методов, которые производные классы должны реализовать, но сам при этом не обеспечивает реализации этих методов. Подобная ситуация может возникнуть, когда базовый класс попросту не в состоянии реализовать метод. В данной ситуации разрабатываются абстрактные методы
    илицелые абстрактные классы.
    Абстрактный метод создается с помощью модификатора abstract. Он не имеет тела и, следовательно, не реализуется базовым классом, а производные классы должны его обязательно переопределить. Абстрактный метод автоматически является виртуальным, однако использовать спецификатор virtual не нужно. Более того, если вы попытаетесь использовать два спецификатора одновременно, abstract и virtual, то компилятор выдаст сообщение об ошибке.
    Если класс содержит один или несколько абстрактных классов, то его также нужно объявить как абстрактный, используя спецификатор abstract перед class. Поскольку абстрактный класс полностью не реализован, то невозможно создать экземпляр класса с помощью операции new. Например, если класс Demo определен как абстрактный, то попытка создать экземпляр класса Demo повлечет ошибку:
    Demo a = new Demo();
    Однако, можно создать массив ссылок, используя этот же абстрактный класс:
    Demo [] Ob=new Demo[5];
    Если производный класс наследует абстрактный, то он должен полностью переопределить все абстрактные методы базового класса или также быть объявлен как абстрактный. Таким образом, спецификатор abstract наследуется до тех пор, пока в производном классе не будут реализованы все абстрактные методы.
    Билет №27. Стандартные интерфейсы .Net.
    Стандартные интерфейсы .Net
    В библиотеке классов .Net определено множество стандартных интерфейсов, задающих желаемую функциональность объектов. Например, интерфейс IComparable задает метод сравнения объектов по принципу больше и меньше, что позволяет переопределить соответствующие операции в рамках класса, наследующего интерфейс IComparable. Реализация интерфейсов IEnumerable и IEnumerator дает возможность просматривать содержимое объекта с помощью оператора foreach.
    Можно создавать собственные классы, реализующие стандартные интерфейсы, что позволит использовать объекты этих классов стандартными способами.
    Более подробно рассмотрим стандартный интерфейс IComparable.
    Интерфейс IComparable определен в пространстве имен System и содержит единственный метод CompareTo, возвращающий результат сравнения двух объектов – текущего и переданного ему в качестве параметра: interface IComparable
    { int CompareTo(object obj);
    }
    Реализация данного метода должна возвращать:
    1)
    0 – если текущий объект и параметр равны;
    2)
    отрицательное число, если текущий объект меньше параметра;
    3)
    положительное число, если текущий объект больше параметра.
    Используя собственную реализацию метода CompareTo можно перегрузить операции отношения. Напомним, что операции отношения должны перегружаться парами: < и >, <= и >=, == и !=.
    1   2   3   4   5   6   7


    написать администратору сайта