Energy
education

сайт для тех, кто хочет изучать энергетику

17. Классы

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

Определение класса

Определение класса начинается с ключевого слова class за котоым следует имя класса, а затем и тело класса, заключенное в паре фигурных скобок. Ниже показана общая форма определения класса:

    
<access specifier> class  class_name 
{
    // члены переменные
    <access specifier> <data type> variable1;
    <access specifier> <data type> variable2;
    ...
    <access specifier> <data type> variableN;
    // члены методы
    <access specifier> <return type> method1(parameter_list) 
    {
        // тело метода
    }
    <access specifier> <return type> method2(parameter_list) 
    {
        // тело метода
    }
    ...
    <access specifier> <return type> methodN(parameter_list) 
    {
        // тело метода
    }
}
    

Обратите внимание, что,

  • Спецификаторы доступа задают правила доступа как для членов, как и для самого класса, если спецификатор доступа не определен, тогда он выбирается по умолчанию для класса как internal. Доступ по умолчанию для членов класса private.
  • Тип данных определяет тип значений переменных, а также значений возвращаемых методами, при условии, что они что они что-то возвращают.
  • Для доступа к членам класса используется оператор точка (.).
  • Оператор точка связывает имя объекта с именем члена.

Следующий пример показывает концепцию описанную выше:

    
using System;
namespace BoxApplication
{
    class Box
    {
       public double length;   // длина коробки
       public double breadth;  // ширина коробки
       public double height;   // высота коробки
    }
    class Boxtester
    {
        static void Main(string[] args)
        {
            Box Box1 = new Box();        // объявление Box1 типа Box
            Box Box2 = new Box();        // объявление Box2 типа Box
            double volume = 0.0;         // переменная для хранения объема коробки
            // описание Box1
            Box1.height = 5.0;
            Box1.length = 6.0;
            Box1.breadth = 7.0;
            // описание Box2
            Box2.height = 10.0;
            Box2.length = 12.0;
            Box2.breadth = 13.0;
           
            // объем Box1
            volume = Box1.height * Box1.length * Box1.breadth;
            Console.WriteLine("Объем Box1 : {0}",  volume);
            // объем Box2
            volume = Box2.height * Box2.length * Box2.breadth;
            Console.WriteLine("Объем Box2 : {0}", volume);
            Console.ReadKey();
        }
    }
}
    

Если приведенный выше код скомпилировать и выполнить, это приведет к следующему результату:

    
Объем Box1 : 210
Объем Box2 : 1560
    

Методы и инкапсуляция

Метод класса это функция которая определяется внутри класса как и любая переменная. Он влияет на любой объект класса в котором он описан, и имеет доступ ко всем членам класса этого объекта.

Переменные класса это атрибуты объекта (с точки зрения дизайна) и они имеют спецификатор доступа private для реализации инкапсуляции. Эти переменные могут быть доступны только для использования методами с спецификатором доступа public.

Показанная выше концепция для установки и получения значений различных членов класса реализуется следующим образом:

    
using System;
namespace BoxApplication
{
    class Box
    {
       private double length;   // длина коробки
       private double breadth;  // ширина коробки
       private double height;   // высота коробки
       public void setLength( double len )
       {
            length = len;
       }
       public void setBreadth( double bre )
       {
            breadth = bre;
       }
       public void setHeight( double hei )
       {
            height = hei;
       }
       public double getVolume()
       {
           return length * breadth * height;
       }
    }
    class Boxtester
    {
        static void Main(string[] args)
        {
            Box Box1 = new Box();        // объявление Box1 типа Box
            Box Box2 = new Box();
            double volume;
            // объявление Box2 типа Box
            // описание Box1
            Box1.setLength(6.0);
            Box1.setBreadth(7.0);
            Box1.setHeight(5.0);
            // описание Box2
            Box2.setLength(12.0);
            Box2.setBreadth(13.0);
            Box2.setHeight(10.0);
       
            // объем Box1
            volume = Box1.getVolume();
            Console.WriteLine("Volume of Box1 : {0}" ,volume);
            // объем Box2
            volume = Box2.getVolume();
            Console.WriteLine("Volume of Box2 : {0}", volume);
           
            Console.ReadKey();
        }
    }
}
    

Если приведенный выше код скомпилировать и выполнить, это приведет к следующему результату:

    
Volume of Box1 : 210
Volume of Box2 : 1560
    

Конструкторы в C#

Конструктор класса это специальный метод класса, который выполняется при создании нового объекта класса.

Конструктор имеет в точности такое же имя как и класс и не имеет возвращаемого типа. Следующий пример объясняет концепцию конструктора:

    
using System;
namespace LineApplication
{
   class Line
   {
      private double length;   // длина линии
      public Line()
      {
         Console.WriteLine("Объект создан");
      }
      public void setLength( double len )
      {
         length = len;
      }
      public double getLength()
      {
         return length;
      }
      static void Main(string[] args)
      {
         Line line = new Line();    
         // задается длина линии
         line.setLength(6.0);
         Console.WriteLine("Длина линии : {0}", line.getLength());
         Console.ReadKey();
      }
   }
}
    

Если приведенный выше код скомпилировать и выполнить, это приведет к следующему результату:

    
Объект создан
Длина линии : 6
    

Конструктор по умолчанию не имеет параметоров, но если необходимо конструктор может иметь параметры. Такой конструктор называется конструктор с параметрами. Эта техника поможет вам присвоить начальное значение объекту на момент его создания, как показано в следующей примере:

    
using System;
namespace LineApplication
{
   class Line
   {
      private double length;   // длина линии
      public Line(double len)  // конструктор с параметрами
      {
         Console.WriteLine("Объект создан, длина = {0}", len);
         length = len;
      }
      public void setLength( double len )
      {
         length = len;
      }
      public double getLength()
      {
         return length;
      }
      static void Main(string[] args)
      {
         Line line = new Line(10.0);
         Console.WriteLine("Длина линии : {0}", line.getLength()); 
         // set line length
         line.setLength(6.0);
         Console.WriteLine("Длина линии : {0}", line.getLength()); 
         Console.ReadKey();
      }
   }
}
    

Если приведенный выше код скомпилировать и выполнить, это приведет к следующему результату:

    
Объект создан, длина = 10
Длина линии : 10
Длина линии : 6
    

Деструктор в C#

Деструктор это специальный метод класса, который выполняется когда объект класса больше не нужен. Деструктор имеет точно текое же имя как и класс, перед которым стоит тильда (~) и он не возвращает значения и не имеет параметров.

Деструктор может быть очень полезен для освобождения ресурсов программы, таких как закрытие файлов, освобождение памяти и т.д. Деструкторы не наследоваться или перегружаться.

Следующий пример объясняет концепцию деструктора:

    
using System;
namespace LineApplication
{
   class Line
   {
      private double length;   // длина линии
      public Line()  // конструктор
      {
         Console.WriteLine("Объект создан");
      }
      ~Line() // деструктор
      {
         Console.WriteLine("Объект уничтожен");
      }
      public void setLength( double len )
      {
         length = len;
      }
      public double getLength()
      {
         return length;
      }
      static void Main(string[] args)
      {
         Line line = new Line();
         // set line length
         line.setLength(6.0);
         Console.WriteLine("Длина линии : {0}", line.getLength());           
      }
   }
}
    

Если приведенный выше код скомпилировать и выполнить, это приведет к следующему результату:

    
Объект создан
Длина линии : 6
Объект уничтожен
    

Статические члены класса C#

Мы можем объявить члены класса как статические использую ключевое слово static. Когда мы объявляем член класса как статический, это означает что не важно сколько объектов класса будет создано, будет существовать только одна копия статического члена.

Ключевое слово static предполагает, что только один экземпляр элемента существует для класса. Статические переменные используются для определения констант, потому что их значения могут быть использованы при вызове класса без создания его экземпляра. Статические переменные можно инициализировать вне методов или определения класса. Можно также инициализировать статические переменные внутри определения класса.

Следующий пример демонстрирует использование статических переменных:

    
using System;
namespace StaticVarApplication
{
    class StaticVar
    {
       public static int num;
        public void count()
        {
            num++;
        }
        public int getNum()
        {
            return num;
        }
    }
    class StaticTester
    {
        static void Main(string[] args)
        {
            StaticVar s1 = new StaticVar();
            StaticVar s2 = new StaticVar();
            s1.count();
            s1.count();
            s1.count();
            s2.count();
            s2.count();
            s2.count();         
            Console.WriteLine("Переменная num для s1: {0}", s1.getNum());
            Console.WriteLine("Переменная num для s2: {0}", s2.getNum());
            Console.ReadKey();
        }
    }
}
    

Если приведенный выше код скомпилировать и выполнить, это приведет к следующему результату:

    
Переменная num для s1: 6
Переменная num для s2: 6
    

Вы такде можете определить метод класса как статический. Такой метод может получить доступ только к статическим переменным. Статический метод существует вне зависимости от созданных объектов. Следующий пример демонстрирует использование статических методов:

    
using System;
namespace StaticVarApplication
{
    class StaticVar
    {
       public static int num;
        public void count()
        {
            num++;
        }
        public static int getNum()
        {
            return num;
        }
    }
    class StaticTester
    {
        static void Main(string[] args)
        {
            StaticVar s = new StaticVar();
            s.count();
            s.count();
            s.count();                   
            Console.WriteLine("Переменная num: {0}", StaticVar.getNum());
            Console.ReadKey();
        }
    }
}
    

Если приведенный выше код скомпилировать и выполнить, это приведет к следующему результату:

    
Переменная num: 3