Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Язык программирования C# и платформа .NET [CSharp & .NET] 2001.10.03


Служба Рассылок Subscribe.Ru

C Sharp and Dot NET

  • Письма
    • Про перевод книги Гуннерсона
    • Программирование в командах
  • Синтаксис C# [5/6]
    • Операторы, функции, классы и пространства имен.
    • Пространства имен
    • классы, структуры и интерфейсы
    • Наследование
    • Интерфейсы

Письма

Про перевод книги Гуннерсона

-----Original Message-----
 From: Serg Vorontsov
 Sent: Sunday, September 30, 2001 12:30 AM

Hi !

взгляни на форуме сайта http://dotsite.spb.ru , как шел расклад по теме конструктора в С# :

=== начало вырезки ===

Выдержка из Гуннерсона: "В С# конструктор по умолчанию не генерируется автоматически. При необходимости программист может сам написать конструктор по умолчанию (т.е. конструктор вызываемый по умолчанию)"

смотрите контрпример (компилится и работает)


class A
{
    public string m1()
    {
        return "";
    }
}

class sample
{
    public static void Main(string[] args)
    {
        A a=new A();
        a.m1();
    }
}

(выдержка из спеки):
"If no constructor is supplied for a class, then an empty constructor with no parameters is automatically provided."

это вполне может быть ошибка переводчика

=== конец вырезки ===

Программирование в командах

-----Original Message-----
From: Fiery Dragon
Sent: Saturday, September 29, 2001 6:13 PM

Добрый день, Сергей!

Сначала легкое, возможно, спорное, замечание по поводу рассылки. Мне кажется, что не стоит смешивать описанием языка С# и системы .Net с описание технологии разработки программных проектов. Это две большие и достаточно сложные темы для того, чтобы "размазывать" их по одной рассылке. Имеет смысл, мне кажется, выпускать две разные рассылки.

Теперь по поводу "оврагов" в http://www.firststeps.narod.ru/csharp/1.html :))

  1. Мне кажется, Вы напрасно передали в ведение программиста-оформителя функцию разработки плана тестирования в связи с тем, что это - прерогатива менеджера по качеству. Имено менеджер по качеству, основываясь на ГОСТах и/или ISO-9000, а также на предпроектной и проектной документации должен составлять план тестирования программного продукта и проводить собственно тестирование.
  2. Именно менеджер по качеству (а потом уже оформитель) должен иметь решающий голос в вопросах дизайна именно потому, что в его распоряжении находятся такие документы, как требования пользователя, ГОСТов и проектных решений.
  3. Кроме того, менеджер по качеству должен оценивать
    • а) качество разработки документации и проверять ее соответствие:
      • требованиям пользователя;
      • требованиям ГОСТов;
      • требованиям проекта;
    • б) качество разработки программного продукта и соответствие, опять-таки:
      • требованиям пользователя;
      • требованиям ГОСТов и принятой технологии разработки;
      • а также соответствие программного продукта и пользовательской документации.
Надо отметить, что в последнее время практически все программистские фирмы создают у себя группы управления качеством, совершенно независимые от разрабатываемых проектов, на которые возлагаются функции оценки качества программного продукта на основе предпроектной и проектной документации, а также проведения полного и независимого (от разработчиков) тестирования программного продукта, и по их заключению принимается решение о выпуске программного продукта "в свет". Правда, сам я такой оценкой качества не занимался в связи с тем, что обычно занимаюсь проектированием и имплементацией программных продуктов. :))

Всего наилучшего.
Юрий Васин

Синтаксис C# [5/6]

Операторы, функции, классы и пространства имен.

Давным давно, весь код состоял из команд и меток. В простых языках программы так же состояли из операторов и меток (примеров не знаю, разве что машина Тьюринга).

По мере усложнения программ начали использовать служебные подпрограммы, а в архитектуру компьютера ввели стек возвратов. Подпрограммы помечались меткой начала, а завершались командой возврата (пример - BASIC в ZX Spectrum).

Без комментариев было трудно выяснить, значение каких переменных программы нужно задать перед вызовом подпрограммы, и какие переменные меняются в процессе ее работы. Тогда подпрограммы начали называть функциями и ввели понятия глобальных и локальных переменных и параметров. Теперь стало нужно явно указывать, какие переменные передаются в функцию и какие используются внутри (пример - язык "чистый C").

Программы становились сложнее. Стали создаваться наборы функций, предназначенных для выполнения частей единой задачи и использующих набор общих глобальных переменных. Вскоре выяснилось, что пользователю нужно знать только часть функций, а вспомогательные функции и данные желательно скрыть. Так появились модули (пример - модули в Turbo Pascal 6.0). А чтобы модули можно было различать, им давали имена.

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

А программы все усложнялись ;) И стало много классов, каждый со своим именем. А так как программы пишут коллективы людей, то неудивительно, что имена разных классов могли случайно совпасть. И тогда придумали пространства имен, а каждому пространству стали давать свое имя. Это как разные комнаты - разные предметы с одинаковым названием (люстры например) могут находиться в доме, но эти предметы можно различить по номеру комнаты. (Примеры языков с пространствами имен - C#, стандартный C++)

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

Пространства имен

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

namespace SomeName
{
    // ... content of namespace resides there
}

Им дали возможность быть вложенными, как папкам в файловой системе.


namespace SomeOtherName
{
    namespace NameOfNestedNamespace
    {
    }
}

Существует еще глобальное пространство имен, туда помещаются те классы, которые не находятся внутри конструкции namespace.

Можно присоединить к глобальному пространству имен все public имена из другого пространства имен при помощи конструкции using. Строки с using обычно пишутся подряд в начале текстового файла.


using SomeName;
using SomeOtherName;
 ...
other text of file

классы, структуры и интерфейсы

Определяются соответственно ключевыми словами class, struct и interface.


class NameOfClass
{
    // members and methods of class
}

interface NameOfInterface
{
    // methods of interface
}

struct NameOfStruct
{
    // members of struct
}

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

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

Принцип наследования отностится только к классам объектов.

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

Наследование бывает двух видов:

  • одиночное - когда каждый класс имеет одного и только одного предка;
  • множественное - когда каждый класс может иметь любое количество предков.

В C# есть только одиночное наследование (и только public для тех, кто знает C++).


class Base
{
}

class Derived : Base
{
}

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

Существование принципа полиморфизма является естественным следствием существования принципа наследования: наследование без изменения набора свойств не имеет смысла. Кроме того, без полиморфизма невозможно реализовать объединение различных объектов (классов) по некоторому набору свойств (невозможно абстрагироваться от части свойств объектов).

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

abstract - пишется перед словом class и говорит о том, что класс может использоваться только для целей наследования. Нельзя создать объекты абстрактного класса.
abstract может быть написано перед методом, тогда не нужно будет писать реализацию метода (метод станет виртуальным, а класс - абстрактым).

sealed - пишется перед словом class и говорит о том, что класс может использоваться только создания объектов. Нельзя отнаследовать новый класс от sealed-класса. Это позволяет компилятору провести оптимизации для такого класса (в частности делать прямые вызовы, а не вызовы через таблицу виртуальных методов)
sealed может быть написано перед методом, тогда этот метод нельзя будет переопределить.

new - пишется перед методом производного класса, в том случае, если имя метода в производном классе совпадает с именем метода в базовом классе. Это явно указывает компилятору и программисту, на тот факт, что метод замещен в производном классе.

virtual - пишется перед методом базового класса. Если обращаться к такому методу из программы, то будет вызвана реализация метода из производного класса.

override - пишется перед методом производного класса для того, чтобы показать, что метод переопределен.

Разницу между виртуальными и невиртуальными методами демонстрирует следующий пример: 

class A
{
   public void F()
   {
       Console.WriteLine("A.F");
   }
   public virtual void G()
   {
       Console.WriteLine("A.G");
   }
}

class B: A
{
    new public void F()
    {
        Console.WriteLine("B.F");
    }
    public override void G()
    {
        Console.WriteLine("B.G");
    }
}

class Test
{
   static void Main()
   {
      B b = new B();
      A a = b;
      a.F();
      b.F();
      a.G();
      b.G();
   }
}

Будет напечатано:

A.F
B.F
B.G
B.G

Интерфейсы

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

Класс может реализовывать сколько угодно интерфейсов

interface IMoveable {
    void MoveTo(double x, double y);
    void MoveRel(double x, double y);
}

interface IActive
{
    string GetResponse(string input);
}

class Terminal : IMoveable, IActive
{
    void MoveTo(double x, double y)
    {
    }
    void MoveRel(double x, double y)
    {
    }
    string GetResponse(string input)
    {
        return input;
    }
}

Если Вам есть что сказать или о чем спросить - пишите на адрес mailto:level3@mail.ru

С уважением и наилучшими пожеланиями,
Сергей Радкевич.



http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу
Рейтингуется SpyLog

В избранное