В С# производный класс создается постановкой двоеточия после имени производного класса и указанием имени базового класса:



Классы и объекты

Структуры и классы

Все типы в С# разделяются на две основные разновидности: структурные типы (value-based) и ссылочные типы (reference-based). К структурным типам относятся все числовые типы данных (int, float и пр.), а также перечисления и структуры. Память для структурных типов выделяется из стека. При присвоении одного структурного типа другому присваивается не сам тип (как область в памяти), а его побитовая копия.

 

 

Пример. Приложение ValandRef из Э.Троелсен, стр. 89.

namespace ValandRef

{

using System;

 

struct FOO

{

public int x, y;

}

 

// Структурный тип

struct PERSON

{

public string Name;

public int Age;

public override string ToString()

{

  return "Name: " + Name + ", Age: " + Age;

}

public PERSON(string n, int a)

{

  Name = n; Age = a;

}

};

 

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

class Person

{

public string Name;

public int Age;

public override string ToString()

{

    return "Name: " + Name + ", Age: " + Age;

}

public Person(string n, int a)

{

    Name = n; Age = a;

}

};

 

class ValRefClass

{

public static int Main(string[] args)

{

    FOO f1 = new FOO();// Здесь new можно не использовать.

    f1.x = 100;

    f1.y = 100;

 

    FOO f 2 = f 1; // Скопировали одну структуру в другую.

        

    Console.WriteLine("F1.x = {0}", f1.x);

    Console.WriteLine("F1.y = {0}", f1.y);

            

    Console.WriteLine("F2.x = {0}", f2.x);

    Console.WriteLine("F2.y = {0}", f2.y);

 

    // Изменяем f2.x. Это не влияет на f1.x.

    Console.WriteLine("Изменили f2.x");  

    f2.x = 900;

 

    Console.WriteLine("F2.x = {0}", f2.x);

    Console.WriteLine("F1.x = {0}", f1.x);

 

    // Создаем объект, т.е. ссылку в управляемой куче

    Person fred; = new Person("Fred", 9);

    Console.WriteLine(fred);

 

    // Создаем значение в стеке

    PERSON mary = new PERSON("Mary", 18);

    Console.WriteLine(mary);

 

//Создаем побитовую копию:

    PERSON jane = mary;

    jane.Age = 20;

    Console.WriteLine(jane);

    Console.WriteLine(mary);

 

// А здесь всего лишь дополнительная ссылка на тот же объект

    Person fredRef = fred;

    fred.Age = 20;

    Console.WriteLine(fred);

    Console.WriteLine(fredRef);  

    return 0;

}

}

}

Структуры выглядят как классы, но реализованы по-другому. Структуры обрабатываются как типы со значением и хранятся в стеке. Это означает, что если экземпляр структуры выходит из области видимости, он автоматически удаляется из памяти. Объекты хранятся в куче и удаляются из памяти при выполнении операции под названием “сборка мусора”. Это основное различие между структурами и объектами.

Также как и классы структуры могут иметь данные, методы и конструкторы.

Укажем отличия:

Структуры не поддерживают наследования.

Для структур нельзя определить конструктор по умолчанию. В C # для структур существует конструктор по умолчанию и его нельзя переопределить.

Для структур нельзя определить деструктор.

Нельзя использовать инициализаторы для установки значений полей.

Структура объявляется при помощи ключевого слова struct, класс – при помощи ключевого слова class.

 

 

Как создать новый класс

В окне Solution Explorer выберем приложение и щелкнем правой кнопкой мыши, в контекстном меню откроем пункт “Add”, а затем пункт “Add Class…”

В следующем окне зададим имя нового класса, в нашем примере, это HelloApp:

 

 

Пример.  Решение квадратного уравнения.

Файл Equation.cs.

using System;

 

namespace MathExample1

{

/// <summary>

/// Summary description for Equation.

/// </summary>

public class Equation

{

    double a,b,c; // Коэффициенты квадратного уравнения

    double x1, x2; //Корни уравнения

        

    public Equation(double a_, double b_, double c_)

    {

         a=a_;b=b_;c=c_;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

    }

    public Equation()

    {

         a=b=c=0;x1=x2=0;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

    }

    public double Determinant()

    {

         return b * b - 4 * a* c;

    }

    public void SolveEquation()

    {

         double r;

// А если a=0?

         r = Determinant();

         if (r<0) Console.WriteLine("Нет корней!");

         else

              if (r>0) {

              r=Math.Sqrt(r);

              x1=(-b+r)/(2*a);

              x2=(-b-r)/(2*a);

         }

         else {x1=x2=-b/(2*a);}

    }

    public void DisplayRoots()

    {

         SolveEquation();

         Console.WriteLine("x1={0} x2={1}",x1,x2);

    }

}

}

 

Файл EquationExample.cs

using System;

 

namespace MathExample1

{

/// <summary>

/// Summary description for Class1.

/// </summary>

class EquationExample

{

    /// <summary>

    /// The main entry point for the application.

    /// </summary>

    [STAThread]

    static void Main(string[] args)

    {

         Equation eq1 = new Equation(1,4,-5);

         eq1.DisplayRoots();

    }

}

}

 

 

В С# все типы данных (как структурные, так и ссылочные) производятся от единого общего предка: класса System.Object. Класс System.Object определяет общее полиморфическое поведение для всех типов данных

Подробности см. Э.Троелсен, стр. 90.

 

Модификаторы доступа

 

В С# для каждого метода существует свой уровень доступа, который определяет, откуда можно будет обратиться к данному методу. Для указания уровня доступа при объявлении метода используются специальные модификаторы.

 

public  Модификатор общедоступности метода

private Метод будет доступен только из класса, в котором определен данный метод. Если при объявлении метода модификатор явно не указан, по умолчанию используется модификатор private

protected Метод будет доступен как из класса, в котором он определен, так и из любого производного класса. Для остальных вызовов из внешнего мира этот метод будет недоступен

internal Метод будет доступен из всех классов внутри сборки, в которой он определен. Из-за пределов этой сборки обратиться к нему будет нельзя.

 

 

Атрибуты и операции

 

Класс в С#, как и в других языках программирования, — это пользовательский тип данных (user defined type, UDT), который состоит из данных (часто называемых атрибутами или свойствами) и функциями для выполнения с этими данными различных действий (эти функции обычно называются методами или операциями).

 

Ключевое слово this используется для ссылки на текущий экземпляр объекта.

 

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

Пример.

public class Equation

{

    double a,b,c; // Коэффициенты квадратного уравнения

    double x1, x2; //Корни уравнения

        

    public Equation(double a_, double b_, double c_)

    {

         a=a_;

b=b_;

c=c_;   

    }

Или

public class Equation

{

    double a,b,c; // Коэффициенты квадратного уравнения

    double x1, x2; //Корни уравнения

        

    public Equation(double a, double b, double c)

    {

         this.a=a;

this.b=b;

this . c = c ;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

    }

 

Зарезервированное слово this в С# можно также использовать для передачи вызова от одного конструктора к другому. Вот пример (См. Э.Троелсен, стр. 142):

class Employee

{

// Внутренние закрытые данные класса

private string fullName;

private int empID;

private float currPay;

 

public Emp1oyee(string fullName, int empID, float currPay)

{

this.fullName =fullname;

this.empID = empID;

this.currPay = currPay;

}

// При вызове следующего конструктора на самом деле будет вызван

// конструктор с тремя параметрами

public Employee(string fullName)

:this(fullName, 123, 0) {}

public Employee(string fullName, int empID)

:this(fullName, empID, 0) {}

 

 

}

 

 

Для каждого члена класса необходимо указать область видимости с помощью одного из следующих ключевых слов: public , private , protected и internal. Однако область видимости задается не только для членов класса, но и для самих классов . Разница между областью видимости для членов классов и областью видимости для самих классов заключается в том, что в первом случае мы определяем те члены класса, которые будут доступны через экземпляры объектов, а во втором — те области программы, из которых будет возможно обращение к данным классам.

Для класса в С# используется только два ключевых слова для определения области видимости: publiс и intern al. Объекты классов, определенных как public (открытых), могут быть созданы как из своего собственного двоичного файла, так и из других двоичных файлов С# (то есть из другой сборки).

 

Объекты классов определенных как internal,  могут создаваться только объектами из той же сборки, в которой они были определены. Внутренние классы часто рассматриваются как вспомогательные (helper classes), поскольку они используются типами данной сборки для помощи в выполнении каких-либо действий. См. пример (Э.Троелсен, стр. 144).

 

 

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

 

Термин поле (field) используется для открытых данных класса (объявленных как public).

 

В С# инкапсуляция реализуется на уровне синтаксиса при помощи ключевых слов public, private и protected.

 

Для обращения к внутренним данным необходимо создать пару методов. С помощью первого метода производится получение информации (это get method или accessor). С помощью второго метода вносятся изменения (это set method или mutator). 

// пример (Э.Троелсен, стр. 151).

public class Employee

{

private string fullName;

// Метод доступа

public string GetFullName() {return fullName; }

// Метод изменения

public void SetFullName (string n)

{

// Логика для удаления неположенных символов (!. @, #. $. %

// Логика для проверки максимальной длины и прочего

fullName = n;

}

}

// Применение методов доступа и изменения

public static int Main(string[] args)

{

Employee p = new Employee();

p.SetFullName(“Fred");

Console. WriteLine( "Employee Is named: " + p. GetFullName());

// Ошибка! К закрытым данным нельзя обращаться напрямую

// через экземпляр объекта!

// p.FullName:

return 0;

}

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

 

 

Свойства

Свойство в C# состоит из двух блоков – блока доступа (get block) и блока изменения (set block).

 

Пример .

public class Employee

{

private int empID;//данные

// Свойство

    public int EmpID

    {

        get{

return empID;

}           

        set{

empID=value;

}

    }

}

public int getempID(){}//

public void setempID(int aa){empID=aa;}

 

 

static Main()

{

Employee stud=new Employee();

stud.EmpID=123;// можно и так: stud.setempID(123);

// На самом деле будет вызван stud.get_EmpID(123);

Console.WriteLine(stud.EmpID);// stud.getempID()

}

 

Обращаться к объекту value можно только в пределах программного блока set внутри определения свойства. Попытка обратиться к этому объекту из любого другого места приведет к ошибке компилятора.

 

 

Замечание.

Для внутреннего представления свойства используют методы с приставками get_ и set_, так в в нашем примере свойство автоматически будет отображено в методы get_EmpID() и set_EmpID().

Это мешает использованию для имен методов доступа и изменения привычных приставок  get_ и set.

 

 

Если в свойстве оставить только блок get, то это свойство только для чтения.

using System;

namespace CSharpLessons

{

public class Square

{

private double _side;

 

   // This is a new property

   public double Side

   {

       get

       {

           return _side;

       }

   }

}

}

 

Можно определить поле только для чтения, используя ключевое слово readonly

 

public readonly string SSNfield;

 

 

Примеры . Из FunctionX. (The C_Sharp_Tutorials.doc), стр. 214-218.

Свойство для чтения

using System;

 

namespace CSharpLessons

{

public class DepartmentStore

{

   private string itemNo;

   private string cat;

   private string name;

   private string size;

   private double price;

 

   // A property for the stock number of an item

   public string ItemNumber

   {

Get

       {

           if( itemNo == "" )

               return "Invalid Item";

           else

               return itemNo;

       }

   }

 

   // A property for the category of item

   public string Category

   {

Get

       {

           if( cat == "" )

               return "Unknown Category";

           else

               return cat;

       }

   }

 

   // A property for an item's name of an item

   public string ItemName

   {

Get

       {

           if( name == "" )

               return "Item no Description";

           else

               return name;

       }

   }

 

   // A property for size of a merchandise

   public string Size

   {

       get

       {

           if( size == "" )

               return "Unknown Size or Fits All";

           else

               return size;

       }

   }

 

   // A property for the marked price of an item

   public double UnitPrice

   {

Get

       {

           if( price == 0 )

               return 0.00;

           else

               return price;

       }

   }

      

   public DepartmentStore(string nbr,

                          string ctg,

                          string nme,

                          string siz,

                          double prc)

   {

       itemNo = nbr;

       cat = ctg;

       name = nme;

       size = siz;

       price = prc;

   }

 

}

 

public class Exercise

{

   static void Main()

   {

       DepartmentStore store = new DepartmentStore("53564",

                                                   "Men",

                                                   "Khaki Pants Sahara",

                                                   "34",

                                                   24.95);

       int quantity = 4;

       double totalPrice = store.UnitPrice * quantity;

 

       Console.WriteLine("Customer Invoice");

       Console.WriteLine("Item #: {0}", store.ItemNumber);

       Console.WriteLine("Category: {0}", store.Category);

       Console.WriteLine("Description: {0}", store.ItemName);

       Console.WriteLine("Item Size: {0}", store.Size);

       Console.WriteLine("Unit Price: {0}", store.UnitPrice.ToString("C"));

       Console.WriteLine("Quantity: {0}", quantity);

       Console.WriteLine("Total Price: {0}\n", totalPrice.ToString("C"));

   }

}

}

Наследование

Главная задача наследования — обеспечить повторное использование кода. Существует два основных вида наследования: классическое наследование (отношение «быть» — is-a) и включение-делегирование (отношение «иметь» — has-a).

Основная идея классического наследования заключается в том, что производные классы должны получать функциональность от базового класса-предка и дополнять ее новыми возможностями.

 

В С# производный класс создается постановкой двоеточия после имени производного класса и указанием имени базового класса:

public class Sphere : Circle

 

В С# при создании производного класса в качестве базового класса можно указать только один класс.

 


Дата добавления: 2020-04-08; просмотров: 128; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!