Читаем Интернет-журнал "Домашняя лаборатория", 2007 №9 полностью

Несмотря на то, что обстоятельный разговор о наследовании, родителях и потомках нам еще предстоит, лучше с самого начала понимать отношения между родительским классом и классом-потом ком, отношения между объектами этих классов. Класс-потомок при создании наследует все свойства и методы родителя. Родительский класс не имеет возможности наследовать свойства и методы, создаваемые его потомками. Наследование — это односторонняя операция от родителя к потомку. Ситуация с присваиванием симметричная. Объекту родительского класса присваивается объект класса-потомка. Объекту класса-потомка не может быть присвоен объект родительского класса. Присваивание — это односторонняя операция от потомка к родителю. Одностороннее присваивание реально означает, что ссылочная переменная родительского класса может быть связана с любыми объектами, имеющими тип потомков родительского класса.

Например, пусть задан некоторый класс Parent, а класс Child — его потомок, объявленный следующим образом:

class Child: Parent {…}

Пусть теперь в некотором классе, являющемся клиентом классов Parent и Child, объявлены переменные этих классов и созданы связанные с ними объекты:

Parent p1 = new Parent(), р2 = new Parent();

Child ch1 = new Child(), ch2 = new Child();

Тогда допустимы присваивания:

p1 = р2; р2= p1; ch1=ch2; ch2 = ch1; p1 = ch1; p1 = ch2;

Но недопустимы присваивания:

ch1 = p1; ch2 = p1; ch2 = p2; ch1 = p2;

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

p1 = ch1;… ch1 = (Child)p1;

Семантика присваивания справедлива и для другого важного случая — при рассмотрении соответствия между формальными и фактическими аргументами процедур и функций. Если формальный аргумент согласно объявлению имеет тип T, а выражение, задающее фактический аргумент, имеет тип T1 то имеет место согласование типов формального и фактического аргумента, если и только если класс Т1 является потомком класса T. Отсюда незамедлительно следует, что если формальный параметр процедуры принадлежит классу Object, то фактический аргумент может быть выражением любого типа.


Преобразование к типу object

Рассмотрим частный случай присваивания х = е; когда х имеет тип object, в этом случае гарантируется полная согласованность по присваиванию — выражение е может иметь любой тип. В результате присваивания значением переменной х становится ссылка на объект, заданный выражением е. Заметьте, текущим типом х становится тип объекта, заданного выражением е. Уже здесь проявляется одно из важных различий между классом и типом. Переменная, лучше сказать сущность х, согласно объявлению принадлежит классу Object, но ее тип — тип того объекта, с которым она связана в текущий момент, — может динамически изменяться.


Примеры преобразований

Перейдем к примерам. Класс Testing, содержащий примеры, представляет собой набор данных разного типа, над которыми выполняются операции, иллюстрирующие преобразования типов. Вот описание класса Testing;

using System;

namespace Types

{

    ///

    /// Класс Testing включает данные разных типов. Каждый его

    /// открытый метод описывает некоторый пример,

    /// демонстрирующий работу с типами.

    /// Открытые методы могут вызывать закрытые методы класса.

    /// 

    public class Testing

    {

         /// 

         /// набор скалярных данных разного типа.

         /// 

         byte b = 255;

         int x = 11;

         uint ux = 1111;

         float у = 5.5f;

         double dy = 5.55;

         string s = "Hello!";

         string s1 = "25";

         object obj = new Object ();

         // Далее идут методы класса, приводимые по ходу

        // описания примеров

    }

В набор данных класса входят скалярные данные арифметического типа, относящиеся к значимым типам, переменные строкового типа и типа object, принадлежащие ссылочным типам. Рассмотрим закрытый (private) метод этого класса — процедуру WhoIsWho с формальным аргументом класса Object. Процедура выводит на консоль переданное ей имя аргумента, его тип и значение. Вот ее текст:

/// 

/// Метод выводит на консоль информацию о типе и

/// значении фактического аргумента. Формальный

/// аргумент имеет тип object. Фактический аргумент

/// может иметь любой тип, поскольку всегда

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

/// 

///  — Имя второго аргумента

///  — Допустим аргумент любого типа

void WhoIsWho(string name, object any)

{

      Console.WriteLine("type {0} is {1}, value is {2}",

           name, any.GetType(), any.ToString ());

}

Вот открытый (public) метод класса Testing, в котором многократно вызывается метод WhoIsWho с аргументами разного типа:

/// 

/// получаем информацию о типе и значении

/// переданного аргумента — переменной или выражения ///

public void WhoTest()

{

     WhoIsWho("x",x);

     WhoIsWho("ux",ux);

     WhoIsWho("y",y);

     WhoIsWho("dy",dy);

     WhoIsWho ("s",s);

     WhoIsWho("11 + 5.55 + 5.5f",11 + 5.55 + 5.5f);

     obj = 11 + 5.55 + 5.5 f;

     WhoIsWho("obj",obj);

}

Перейти на страницу:

Похожие книги

Гостиная
Гостиная

Эта книга предназначена для тех, кто хотел бы собственными руками обустроить свою гостиную, сделав ее уютной и удобной. Здесь вы найдете исчерпывающие советы по созданию гармоничного интерьера, удобному освещению, размещению ковров, цветов и картин, а также других мелочей, которые превратят вашу гостиную в комфортабельную комнату, удовлетворяющую потребностям каждого члена семьи.В этой книге также даны подробные рекомендации по ремонту гостиной, которые помогут осуществить задуманное вами преобразование. Методы, описанные здесь, вполне доступны каждому. Надеемся, что эта книга поможет вам подойти к обустройству гостиной творчески, а ремонтные работы доставят истинное удовольствие.

Линиза Жалпанова , Линиза Жувановна Жалпанова , Наталья Михайловна Сухинина , Наталья Сухинина

Сделай сам / Дом и досуг