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

  • Результат выполнения программы (из листинга 7.11)

  • Результат выполнения программы (из листинга 7.12)

  • Результат выполнения программы (из листинга 7.13)

  • Результат выполнения программы (из листинга 7.14)

  • Результат выполнения программы (из листинга 7.15)

  • Задания для самостоятельной работы

  • Васильев А.Н. Основы программирования на C#. Васильев А. Н. Программирование


    Скачать 5.54 Mb.
    НазваниеВасильев А. Н. Программирование
    АнкорВасильев А.Н. Основы программирования на C
    Дата20.09.2022
    Размер5.54 Mb.
    Формат файлаpdf
    Имя файлаVasilev_Programmirovanie-na-C-dlya-nachinayushchih-Osobennosti-y.pdf
    ТипДокументы
    #686596
    страница29 из 40
    1   ...   25   26   27   28   29   30   31   32   ...   40
    366
    //
    Ƚɥɚɜɧɵɣ ɤɥɚɫɫ:
    class GenRestDemo{
    //
    Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
    static void Main(){
    //
    ɋɨɡɞɚɧɢɟ ɨɛɴɟɤɬɨɜ ɨɛɵɱɧɵɯ ɤɥɚɫɫɨɜ:
    Alpha A=new Alpha(100);
    Bravo B=new Bravo(200);
    Charlie C=new Charlie(300);
    //
    ɋɨɡɞɚɧɢɟ ɨɛɴɟɤɬɨɜ ɧɚ ɨɫɧɨɜɟ ɨɛɨɛɳɟɧɧɨɝɨ ɤɥɚɫɫɚ:
    MyClass objA=new MyClass(A);
    MyClass objB=new MyClass(B);
    MyClass objC=new MyClass(C);
    MyClass objD=new MyClass(C);
    Результат выполнения программы следующий:
    
    Результат выполнения программы (из листинга 7.11)
    Ʉɥɚɫɫ Alpha: 100
    Ʉɥɚɫɫ Bravo: 200
    Ʉɥɚɫɫ Charlie: 300
    Ʉɥɚɫɫ Charlie: 300
    Во-первых, мы описали три обычных класса Alpha, Bravo и Charlie. Класс Alpha является базовым для класса Bravo, а класс Bravo является базовым для класса Charlie. В классе Alpha описано защищенное целочисленное поле code, конструктор с одним аргументом и виртуальный метод show(), который при вызове отображает название класса и значение поля code. В производных классах Bravo и Charlie метод show()
    переопределяется так, чтобы отображалось имя соответствующего класса (нам это нужно для того, чтобы можно было определить, из объекта какого класса вызывается метод).
    Класс MyClass является обобщенным. У него один обобщенный параметр, обозначенный как T. Ограничение where T: Alpha, накладываемое
    Обобщенные типы
    367
    на этот параметр, означает, что значением параметра T может быть имя класса, являющегося производным от класса Alpha (класс Alpha также попадает в данную категорию. В классе MyClass есть поле obj. Это ссылка на объект класса Alpha. Конструктору обобщенного класса передается один аргумент — ссылка на объект обобщенного типа T. Данная ссылка в качестве значения присваивается полю obj. Такая операция возможна, поскольку, как мы помним, значением обобщенного параметра может быть нелюбой класса только производный класс от класса
    Alpha
    . Далее, объектная переменная базового класса может ссылаться на объект производного класса. Поэтому поле obj, являющееся объектной переменной класса Alpha, может ссылаться на объект класса, который скрывается за параметром В конструкторе обобщенного класса MyClass из объекта, на который ссылается поле obj, вызывается метод show() (команда obj.show()). В итоге при создании объекта на основе обобщенного класса появляется сообщение, в котором указано имя обычного класса (Alpha, Bravo или
    Charlie
    ). Это класс объекта, на который записана ссылка в поле obj. Также в сообщении отображается значение поля code этого объекта.
    В главном методе создается объект A класса Alpha со значением 100 для поля code, объект B класса Bravo со значением 200 для поля code и объект C класса Charlie со значением 300 для поля code. Далее на основе обобщенного класса MyClass создается четыре объекта objA, objB
    , objC и objD. Каждый раз при создании такого объекта появляется сообщение в консольном окне. Причем при создании последнего объекта objD значением обобщенного параметра указан класс Alpha, хотя фактически в качестве аргумента конструктору класса MyClass передается объект C класса Charlie. Но, как видим, эта ситуация обрабатывается корректно.
    Еще один пример использования ограничения для обобщенного параметра типа представлен в листинге 7.12. На этот раз ограничение состоит в том, что значением обобщенного параметра может быть только классу которого есть конструктор без аргументов НАЗ А МЕТКУ Когда возникает необходимость накладывать ограничение, связанное с наличием конструктора без аргументов Например, в обобщенном классе создается объект обобщенного типа. Нужно вызвать конструктор класса, который обозначен как обобщенный параметр.
    Глава Если мы уверены, что у этого класса есть конструктор без аргументов, то можем вызвать такой конструктор, даже не зная, с каким классом в действительности придется иметь дело. А уверенными мы можем быть, если наложим ограничение, которое состоит в том, что у класса, являющегося значением обобщенного параметра, есть конструктор без аргументов.
    Рассмотрим представленный далее программный код.
    
    Листинг 7.12. Ограничение new() на параметр типа System;
    //
    ɉɟɪɜɵɣ ɤɥɚɫɫ:
    class Alpha{
    public int code;
    public override string ToString(){
    return
    ƎAlpha: Ǝ+code;
    }
    }
    //
    ȼɬɨɪɨɣ ɤɥɚɫɫ:
    class Bravo{
    public string text;
    public override string ToString(){
    return
    ƎBravo: Ǝ+text;
    }
    }
    //
    Ɉɛɨɛɳɟɧɧɵɣ ɤɥɚɫɫ ɫ ɨɝɪɚɧɢɱɟɧɢɟɦ ɧɚ ɨɛɨɛɳɟɧɧɵɣ ɩɚɪɚɦɟɬɪ:
    class MyClass where T: new(){
    //
    ɋɫɵɥɤɚ ɧɚ ɨɛɴɟɤɬ:
    public T obj;
    //
    Ʉɨɧɫɬɪɭɤɬɨɪ:
    public MyClass(){
    //
    ɋɨɡɞɚɧɢɟ ɨɛɴɟɤɬɚ ɨɛɨɛɳɟɧɧɨɝɨ ɬɢɩɚ:
    obj=new T();
    }
    Обобщенные типы //
    Ɇɟɬɨɞ:
    public void show(){
    Console.WriteLine(obj);
    }
    }
    //
    Ƚɥɚɜɧɵɣ ɤɥɚɫɫ:
    class MoreGenRestDemo{
    //
    Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
    static void Main(){
    //
    ɇɚ ɨɫɧɨɜɟ ɨɛɨɛɳɟɧɧɨɝɨ ɤɥɚɫɫɚ ɫɨɡɞɚɟɬɫɹ ɨɛɴɟɤɬ:
    MyClass objA=new MyClass();
    objA.obj.code=123;
    objA.show();
    //
    ɇɚ ɨɫɧɨɜɟ ɨɛɨɛɳɟɧɧɨɝɨ ɤɥɚɫɫɚ ɫɨɡɞɚɟɬɫɹ ɨɛɴɟɤɬ:
    MyClass objB=new MyClass();
    objB.obj.text=
    ƎtextƎ;
    objB.show();
    Результат выполнения программы показан ниже:
    
    Результат выполнения программы (из листинга 7.12)
    Alpha: 123
    Bravo: В программе описаны обычные классы Alpha (с целочисленным полем code
    ) и Bravo (с текстовым полем text). В каждом классе переопределен метод ToString(). Метод результатом возвращает текстовую строку с названием класса и значением поля. Нив одном из классов не описан конструктор, и это означает, что каждый класс имеет конструктор без аргументов.
    Обобщенный класс MyClass имеет один обобщенный параметр T, на который наложено ограничение where T: new(). Оно означает, что класс,
    Глава который будет использован как значение обобщенного параметра (при создании объекта на основе обобщенного класса, должен иметь конструктор без аргументов. Классы Alpha и Bravo удовлетворяют этому критерию.
    В обобщенном классе MyClass имеется поле obj обобщенного типа T. Значением полю присваивается ссылка на объект, который создается при вызове конструктора. Соответствующая команда имеет вид obj=new
    T(). То есть объект создается инструкцией new T(), в которой мы обобщенный параметр T используем как имя класса. Собственно, ради возможности использовать данную инструкцию на параметр T накладывается ограничение.
    У обобщенного класса MyClass есть метод show(). При его вызове в консольном окне печатается объект, на который ссылается поле obj в этом случае для объекта obj вызывается метод В методе Main() на основе обобщенного класса MyClass создаются два объекта при создании объекта objA значением обобщенного параметра является класса при создании объекта objB значением обобщенного параметра является класс Bravo. У каждого из объектов objA и objB есть поле obj. Для объекта objA поле obj ссылается на объект класса Alpha, а для объекта objB поле obj ссылается на объект класса Bravo. Командами и objB.obj.text=
    ƎtextƎ полям объектов, на которые есть ссылка в поле obj, присваиваются значения. После этого командами objA.show() и objB.show() проверяется результат.
    На один и тот же параметр может накладываться несколько ограничений сразу. Подобная ситуация представлена в листинге Листинг 7.13. Несколько ограничений на обобщенный параметр System;
    //
    Ȼɚɡɨɜɵɣ ɤɥɚɫɫ:
    class Alpha{
    //
    ɐɟɥɨɱɢɫɥɟɧɧɨɟ ɩɨɥɟ:
    public int code;
    //
    ɉɟɪɟɨɩɪɟɞɟɥɟɧɢɟ ɦɟɬɨɞɚ ToString():
    public override string ToString(){
    return
    ƎAlpha: Ǝ+code;
    }
    Обобщенные типы
    ɉɪɨɢɡɜɨɞɧɵɣ ɤɥɚɫɫ:
    class Bravo:Alpha{
    //
    Ɍɟɤɫɬɨɜɨɟ ɩɨɥɟ:
    public string text;
    //
    ɉɟɪɟɨɩɪɟɞɟɥɟɧɢɟ ɦɟɬɨɞɚ ToString():
    public override string ToString(){
    return
    ƎBravo: Ǝ+code+Ǝ ɢ Ǝ+text;
    }
    }
    //
    Ɉɛɨɛɳɟɧɧɵɣ ɤɥɚɫɫ:
    class MyClass
    where X: class,new() //
    Ɉɝɪɚɧɢɱɟɧɢɹ ɧɚ ɩɚɪɚɦɟɬɪ X
    where Y: X,new(){ //
    Ɉɝɪɚɧɢɱɟɧɢɹ ɧɚ ɩɚɪɚɦɟɬɪ Y
    //
    ɉɟɪɜɨɟ ɩɨɥɟ ɨɛɨɛɳɟɧɧɨɝɨ ɬɢɩɚ:
    public X first;
    //
    ȼɬɨɪɨɟ ɩɨɥɟ ɨɛɨɛɳɟɧɧɨɝɨ ɬɢɩɚ:
    public Y second;
    //
    Ʉɨɧɫɬɪɭɤɬɨɪ:
    public MyClass(){
    //
    ɋɨɡɞɚɸɬɫɹ ɨɛɴɟɤɬɵ ɨɛɨɛɳɟɧɧɵɯ ɬɢɩɨɜ:
    first=new X();
    second=new Y();
    }
    //
    ɉɟɪɟɨɩɪɟɞɟɥɟɧɢɟ ɦɟɬɨɞɚ ToString():
    public override string ToString(){
    return
    ƎMyClass->|Ǝ+first+Ǝ|Ǝ+second+Ǝ|Ǝ;
    }
    }
    //
    Ƚɥɚɜɧɵɣ ɤɥɚɫɫ:
    class MultiGenRestDemo{
    //
    Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
    Глава 7
    372
    static void Main(){
    //
    ɋɨɡɞɚɧɢɟ ɨɛɴɟɤɬɚ ɨɛɨɛɳɟɧɧɨɝɨ ɤɥɚɫɫɚ:
    MyClass obj=new MyClass();
    //
    ɉɪɢɫɜɚɢɜɚɧɢɟ ɡɧɚɱɟɧɢɣ ɩɨɥɹɦ:
    obj.first.code=100;
    obj.second.code=200;
    obj.second.text=
    ƎtextƎ;
    //
    Ɉɬɨɛɪɚɠɟɧɢɟ ɯɚɪɚɤɬɟɪɢɫɬɢɤ ɨɛɴɟɤɬɚ:
    Console.WriteLine(obj);
    Ниже показано, как выглядит результат выполнения программы:
    
    Результат выполнения программы (из листинга 7.13)
    MyClass->|Alpha: 100|Bravo: 200
    ɢ В программе описан класс Alpha, который является базовым для класса
    Bravo
    . У класса Alpha есть целочисленное поле code, а в классе Bravo к нему добавляется текстовое поле text. В каждом из классов переопределен метод ToString(): методом возвращается текстовая строка сна- званием класса и значением полей.
    В программе также описан обобщенный класс MyClass с двумя обобщенными параметрами (обозначены как X и Y). На параметр X наложено ограничение where X: class,new(), означающее, что значением этого параметра может быть классу которого есть конструктор без аргументов. На параметр Y накладывается ограничение where Y: X,new(). Ограничение означает, что значением параметра Y может быть класс с конструктором без аргументов. А еще этот класс должен быть производным от класса, являющегося значением параметра X. В обобщенном классе есть поле first типа X и поле second типа Y. В конструкторе класса MyClass создаются объекты классов X и Y, и ссылки на эти объекты записываются в поля first и second. А метод ToString() для класса MyClass определен так, что отображаются название класса и текстовые представления (а значит, значения полей) объектов, на которые ссылаются поля first и second.
    Обобщенные типы
    373
    В главном методе командой MyClass obj=new My
    Class()
    создается объект obj обобщенного класса. В качестве значения для обобщенного параметра X указан класса значением параметра Y указан класс Bravo (который является производным от класса Alpha). После присваивания значений полям объект obj выводится в консоль (в этом случае вызывается метод, описанный в классе Похожим образом накладываются ограничения на обобщенные параметры в интерфейсах. В листинге 7.14 представлена программа, в которой описывается обобщенный интерфейс (на обобщенные параметры которого накладываются ограничения, а затем путем реализации этого интерфейса создается обобщенный класс.
    
    Листинг 7.14. Обобщенный интерфейс с ограничением на обобщенный параметр System;
    //
    Ɉɛɨɛɳɟɧɧɵɣ ɢɧɬɟɪɮɟɣɫ ɫ ɨɝɪɚɧɢɱɟɧɢɟɦ
    //
    ɧɚ ɨɛɨɛɳɟɧɧɵɣ ɩɚɪɚɦɟɬɪ:
    interface MyInterface where T: struct{
    void show();
    }
    //
    Ɉɛɨɛɳɟɧɧɵɣ ɤɥɚɫɫ ɪɟɚɥɢɡɭɟɬ ɨɛɨɛɳɟɧɧɵɣ ɢɧɬɟɪɮɟɣɫ:
    class MyClass:MyInterface where T: struct{
    //
    ɉɨɥɟ ɨɛɨɛɳɟɧɧɨɝɨ ɬɢɩɚ:
    public T val;
    //
    Ʉɨɧɫɬɪɭɤɬɨɪ:
    public MyClass(T v){
    val=v;
    }
    //
    Ɉɩɢɫɚɧɢɟ ɦɟɬɨɞɚ ɢɡ ɢɧɬɟɪɮɟɣɫɚ:
    public void show(){
    Console.WriteLine(
    ƎɌɢɩ {0}: ɡɧɚɱɟɧɢɟ {1}Ǝ,typeof(T).Name,val);
    }
    }
    Глава 7
    374
    //
    Ƚɥɚɜɧɵɣ ɤɥɚɫɫ:
    class GenInterfaceRestDemo{
    static void Main(){
    //
    ɋɨɡɞɚɧɢɟ ɨɛɴɟɤɬɨɜ ɧɚ ɨɫɧɨɜɟ ɨɛɨɛɳɟɧɧɨɝɨ ɤɥɚɫɫɚ:
    MyClass A=new MyClass(100);
    MyClass B=new MyClass(
    ƍBƍ);
    //
    ȼɵɡɨɜ ɦɟɬɨɞɚ ɢɡ ɨɛɴɟɤɬɨɜ:
    A.show();
    B.show();
    При выполнении программы получаем следующий результат:
    
    Результат выполнения программы (из листинга 7.14)
    Ɍɢɩ Int32: ɡɧɚɱɟɧɢɟ 100
    Ɍɢɩ Char: ɡɧɚɱɟɧɢɟ Обобщенный интерфейс MyInterface описан с обобщенным параметром, на который накладывается ограничение where T: struct. Ограничение означает, что обобщенный параметр T может скрывать за собой нессылочный тип. В интерфейсе объявлен метод show() без аргументов, не возвращающий результат.
    Обобщенный класс MyClass реализует интерфейс MyInterface. Ограничение на обобщенный параметр в классе указано такое же, как ив интерфейсе. В классе описано поле val обобщенного типа. Значение поля отображается при вызове метода show(). Также отображается значение обобщенного параметра НАЗ А МЕТКУ Значение полю val присваивается в конструкторе. Напрямую здесь ограничение, накладываемое на обобщенный параметр, не используется, хотя это и имеет значение при присваивании значения полю val в него копируется значение аргумента (то есть копируется значение, а не выполняется ссылка на уже существующий объект
    Обобщенные типы
    375
    В главном методе создаются объекты A и B класса MyClass. Значение полю val объектов присваивается при создании объектов. Для проверки значений полей из объектов вызывается метод Еще один пример из листинга 7.15 иллюстрирует, как ограничения на обобщенные параметры реализуются в случае использования обобщенных делегатов и методов.
    
    Листинг 7.15. Обобщенные делегаты и методы с ограничениями на параметры System;
    //
    Ɉɛɨɛɳɟɧɧɵɣ ɞɟɥɟɝɚɬ ɫ ɨɝɪɚɧɢɱɟɧɢɟɦ
    //
    ɧɚ ɨɛɨɛɳɟɧɧɵɣ ɩɚɪɚɦɟɬɪ:
    delegate T MD(T[] arg) where T: struct;
    //
    Ƚɥɚɜɧɵɣ ɤɥɚɫɫ:
    class GenDelegateRestDemo{
    //
    ɋɬɚɬɢɱɟɫɤɢɣ ɨɛɨɛɳɟɧɧɵɣ ɦɟɬɨɞ ɫ ɨɝɪɚɧɢɱɟɧɢɟɦ ɧɚ
    //
    ɨɛɨɛɳɟɧɧɵɣ ɩɚɪɚɦɟɬɪ:
    static T First(T[] t) where T: struct{
    return t[0];
    }
    //
    ɋɬɚɬɢɱɟɫɤɢɣ ɨɛɨɛɳɟɧɧɵɣ ɦɟɬɨɞ (ɛɟɡ ɨɝɪɚɧɢɱɟɧɢɣ ɧɚ
    //
    ɨɛɨɛɳɟɧɧɵɣ ɩɚɪɚɦɟɬɪ):
    static T Last(T[] t){
    return t[t.Length-1];
    }
    //
    Ɉɛɵɱɧɵɣ (ɧɟ ɨɛɨɛɳɟɧɧɵɣ) ɫɬɚɬɢɱɟɫɤɢɣ ɦɟɬɨɞ:
    static int MaxVal(int[] a){
    int val=a[0];
    for(int k=1;k if(val }
    return val;
    }
    Глава 7
    376
    //
    Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
    static void Main(){
    //
    ɋɨɡɞɚɧɢɟ ɷɤɡɟɦɩɥɹɪɨɜ ɞɟɥɟɝɚɬɚ:
    MD A=First;
    MD B=Last;
    MD C=MaxVal;
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɨɜ ɞɟɥɟɝɚɬɚ:
    int x=A(new int[]{10,7,3,1});
    char y=B(new char[]{
    ƍAƍ,ƍCƍ,ƍFƍ});
    int z=C(new int[]{1,7,2,5,11,9,3,6});
    //
    ɉɪɨɜɟɪɤɚ ɪɟɡɭɥɶɬɚɬɚ:
    Console.WriteLine(
    ƎɁɧɚɱɟɧɢɹ: {0}, {1} ɢ {2}Ǝ,x,y,z);
    Ниже показано, как выглядит результат выполнения программы:
    
    Результат выполнения программы (из листинга 7.15)
    Ɂɧɚɱɟɧɢɹ: 10, F ɢ В данном случае мы описываем обобщенный делегат MD с одним обобщенным параметром (обозначен как T). На обобщенный параметр накладывается ограничение where T: struct, то есть параметром может быть нессылочный тип. Делегат соответствует методам, у которых аргумент является массивом, а результат — значением того же типа, что и элементы массива. Также в программе есть три статических метода два обобщенных и один обычный (не обобщенный. Обобщенный метод First() результатом возвращает значение первого элемента массива, переданного аргументом методу. На обобщенный параметр метода накладывается такое же ограничение, как и на параметр обобщенного делегата. Обобщенный метод Last() результатом возвращает значение последнего элемента массива, переданного аргументом методу (на обобщенный параметр метода ограничения не накладываются. Наконец, аргументом методу MaxVal() передается целочисленный массива результатом возвращается значение наибольшего элемента в массиве
    Обобщенные типы
    377
    В главном методе на основе статических методов создаются экземпляры для обобщенного делегата MD, причем при присваивании экземпляру ссылки на обобщенный метод последний мы указываем как с явной спецификацией значения обобщенного типа (команда
    MD
    A=First), таки без нее (команда MD B=Last). При создании экземпляра делегата на основе обычного (не обобщенного) метода значение для обобщенного параметра указывается только после названия делегата (команда MD C=MaxVal). Конечно, характеристики такого метода должны соответствовать характеристикам делегата. Также в главном методе есть примеры вызова созданных экземпляров делегата Резюме Побойся неба ПЖ живи я — счастлив А я еще больше счастлив!
    из к/ф «Кин-дза-дза»
    • При описании методов и классов (а также структур, интерфейсов и делегатов) тип может передаваться через параметр — в описании метода или класса тип обозначен параметром, а конкретное значение для типа данных определяется на этапе создания объекта или при вызове метода. Идентификатор (обобщенный параметр, обозначающий тип, указывается в угловых скобках после имени класса или названия метода. Если обобщенных параметров несколько, они разделяются запятыми При вызове обобщенного метода фактическое значение обобщенного параметра (или параметров) определяется на основе аргументов, переданных методу. Также можно указать значения для обобщенных параметров явно, указав их в угловых скобках после имени метода (в команде вызова метода. Значения обобщенных параметров указываются явно ив том случае, если значения обобщенных параметров не могут быть определены автоматически по команде вызова метода При создании объекта на основе обобщенного класса после имени класса в угловых скобках указываются значения для обобщенных параметров. Такой же принцип используется при работе с обобщенными структурами, интерфейсами и делегатами
    Глава 7
    378
    • Обобщенные методы можно перегружать. Обобщенные классы могут наследоваться. При этом на основе обобщенного класса могут создаваться как обобщенные классы, таки обычные На обобщенные параметры могут накладываться ограничения (например, необходимость иметь конструктор без аргументов, быть производным классом от какого-либо класса или реализовать определенный интерфейс. Ограничение задается выражением, которое состоит из ключевого слова where
    , после которого указывается название обобщенного параметра, двоеточие и инструкция, определяющая накладываемое на параметр ограничение.
    Задания для самостоятельной работы
    Такое предложение. Находим Скрипача, летим к местному правительству...
    из к/ф «Кин-дза-дза»
    1   ...   25   26   27   28   29   30   31   32   ...   40


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