Обучающие курсы:

Обучение профессии "Разработчик C#" + стажировка в Mail.ru
Обучение профессии "Разработчик Python" + трудоустройство
Обучение профессии "Веб-разработчик" + стажировка в Mail.ru


Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Классы.

И снова классы... Что же отличает классы C# от классов C++?

Уровни доступа

В языке C# доступ регулируется несколькими способами:

Доступ для членов класса:

public Общий (неограниченный) доступ
protected Доступ ограничен в пределах данного класса и классов, производных от данного
internel Доступ ограничен сборкой, в которой находится данный класс
protected internal Доступ ограничен в пределах данного класса и классов, производных от данного, или доступ ограничен сборкой, в которой находится данный класс
private Доступ ограничен в пределах данного класса
Доступом по умолчанию является private.

Доступ для классов верхнего уровня (классов, не вложенных в другие классы) ограничивается модификаторами internal и public (по умолчанию: internal).

Объявление полей и методов класса

В отличие от C++, модификатор доступа, должен появляться перед каждым отдельным полем или методом (иначе данный элемент будет иметь уровень доступа private).

class SomeClass
{
    public int i, j;
    protected int k;
    public void F()
    {

    }
}

Поля класса могут инициализироваться при объявлении

class SomeClass
{
    public int i = 1, j = 2;
    protected int k = 3;
    public void F()
    {

    }
}

Поля класса могут иметь модификатор readonly, который означает, что значение данной переменной класса может либо быть задано сразу, либо в конструкторе (см. ниже), и в дальнейшем ее значение изменяться не может.

class SomeClass
{
    public readonly int i = 7;
    protected int k = 3;
    public void F(int k)
    {
        // this - текущий экземпляр класса
        this.k = k;
    }
}

Объявление статических полей и методов класса

Для связи членов класса не с конкретными экземплярами класса, а с классом в целом, используются объявления статических переменных и статических функций.

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

class SomeClass
{
    // объявление константы подразумевает слово static !!!
    // после объявления константа немодифицируема 
    const int Test = 1000;
    public static int i = 100;
    public static int GetI()
    {
        return i;
    }
}

class Test
{
    static void Main()
    {
        SomeClass s = new SomeClass();
        Console.WriteLine(SomeClass.GetI());
        SomeClass.i = 1000;
        Console.WriteLine(SomeClass.GetI());
    }
}
******
Так как в C# отсутствуют глобальные переменные и константы, то все объявления должны находиться внутри классов. В результате часто образуются классы, состоящие исключительно из статических членов. Необходимость в создании экземпляров у таких классов полностью отсутствует, ведь статические переменные вызываются через имя класса. Чтобы запретить создание экземпляров данного класса создают закрытый конструктор (см., например, класс System.Console).
******

Конструкторы

Идеология конструктов в C# мало чем отличается от конструкторов в языке C++. Конструктор - это функция, которая вызывается при создании объекта класса. Исключение составляет лишь статический конструктор - функция, которая вызывается перед созданием первого экземпляра класса (статическому конструктору ничего не известно о создаваемом объекте). Статический конструктор параметров не получает, а статических деструкторов не существует.

class SomeClass
{
    // Если значение паременной зависит от конструктора,
    // то производим инициализацию в нем,
    // иначе присваиваем начальное значение сразу

    static double d;

    int i = 100;
    string j;
    
    static SomeClass()
    {
        d = 100.001; 
    }
    public SomeClass()
    {
        j = "Hello";
    }
    public SomeClass(string value)
    {
        j = value;
    }
    public void Out()
    {
        Console.WriteLine(j);
        Console.WriteLine(i);
        Console.WriteLine(d);
    }
}

class Test
{
    static void Main()
    {
        SomeClass s1 = new SomeClass();
        SomeClass s2 = new SomeClass("Test");

        s1.Out();
        s2.Out();
    }
}

Деструкторы

В C# понятие деструктора отличается от изученного нами в C++. В C# деструктор (или завершитель) вызывается сборщиком мусора (см. подробности в следующих разделах) при освобождении объекта. Таким образом, мы не можем напрямую управлять вызовом деструктора, поэтому его ценность (в сравнении с деструктором C++) намного ниже. В C# нет возможности вызвать деструктор напрямую, он вызывается автоматически при сборке мусора.

class SomeClass
{
    // Если значение паременной зависит от конструктора,
    // то производим инициализацию в нем,
    // иначе присваиваем начальное значение сразу

    static double d;

    int i = 100;
    string j;
    
    static SomeClass()
    {
        d = 100.001; 
    }
    public SomeClass()
    {
        j = "Hello";
    }
    public SomeClass(string value)
    {
        j = value;
    }
    // Деструктор
    ~SomeClass()
    {
        Console.WriteLine("Деструктор");
    }
    public void Out()
    {
        Console.WriteLine(j);
        Console.WriteLine(i);
        Console.WriteLine(d);
    }
}

class Test
{
    static void Main()
    {
        SomeClass s1 = new SomeClass();
        SomeClass s2 = new SomeClass("Test");

        s1.Out();
        s2.Out();
    }
}

Ссылочный тип

Объекты любых классов являются ссылочными типами. Это означает, что при объявлении они инициализируются null-значениями, и для них необходимо выделять память с помощью оператора new (естественно, объекты размещаются в куче).

class Test
{
    static void Main()
    {
        string [] m = new string[]{"4","5","3","9","1"};
        
        string [] n = new string[3];
        // память, выделенную под массив n, через какое-то время удалит
        // сборщик мусора, а теперь n и m ссылаются на один и тот же 
        // участок памяти, что не всегда есть хорошо
        n = m;
        n[0] = "1000";

        // выводимые данные одинаковы
        Console.WriteLine(m[0]);
        Console.WriteLine(n[0]);
    }
}


 
 
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru