Опубликован: 15.09.2010 | Доступ: свободный | Студентов: 4807 / 630 | Оценка: 3.97 / 3.80 | Длительность: 14:45:00
Лекция 8:

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

< Лекция 7 || Лекция 8: 123 || Лекция 9 >

Класс object

Корневой класс System.Object всей иерархии объектов .NET, называемый в C# object, обеспечивает всех наследников несколькими важными методами. Производные классы могут использовать эти методы непосредственно или переопределять их.

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

Открытые методы класса System.Object перечислены ниже.

  • Метод Equals с одним параметром возвращает значение true, если параметр и вызывающий объект ссылаются на одну и ту же область памяти. Синтаксис:
    public virtual bool Equals(object obj);
  • Метод Equals с двумя параметрами возвращает значение true, если оба параметра ссылаются на одну и ту же область памяти. Синтаксис:
    public static bool Equals(object ob1, object ob2);
  • Метод GetHashCode формирует хэш-код объекта и возвращает число, однозначно идентифицирующее объект. Это число используется в различных структурах и алгоритмах библиотеки. Если переопределяется метод Equals, необходимо перегрузить и метод GetHashCode. Синтаксис:
    public virtual int GetHashCode();
  • Метод GetType возвращает текущий полиморфный тип объекта, то есть не тип ссылки, а тип объекта, на который она в данный момент указывает. Возвращаемое значение имеет тип Type. Это абстрактный базовый класс иерархии, использующийся для получения информации о типах во время выполнения. Синтаксис:
    public Type GetType();
  • Метод ReferenceEquals возвращает значение true, если оба параметра ссылаются на одну и ту же область памяти. Синтаксис:
    public static bool ReferenceEquals(object ob1, object ob2);
  • Метод ToString по умолчанию возвращает для ссылочных типов полное имя класса в виде строки, а для значимых — значение величины, преобразованное в строку. Этот метод переопределяют для того, чтобы можно было выводить информацию о состоянии объекта. Синтаксис:
    public virtual string ToString()

В производных объектах эти методы часто переопределяют. Например, можно переопределить метод Equals для того, чтобы задать собственные критерии сравнения объектов.

Пример применения и переопределения методов класса object для класса Monster приведен в листинге 8.5.

using System;
namespace ConsoleApplication1
{
    class Monster
    {
        public Monster( int health, int ammo, string name )
        {
            this.health = health;
            this.ammo   = ammo;
            this.name   = name;
        }

        public override bool Equals( object obj )
        {
            if ( obj == null || GetType() != obj.GetType() ) return false;

            Monster temp = (Monster) obj;
            return  health == temp.health &&
                    ammo   == temp.ammo   &&
                    name   == temp.name;
        }

        public override int GetHashCode()
        {
            return name.GetHashCode();
        }

        public override string ToString()
        {
            return string.Format( "Monster {0} \t health = {1} ammo = {2}", 
                    name, health, ammo );
        }

        string name;
        int health, ammo;
    }
    
    class Class1
    {   static void Main()
        {
            Monster X = new Monster( 80, 80, "Вася" );
            Monster Y = new Monster( 80, 80, "Вася" );
            Monster Z = X;
        
            if ( X == Y ) Console.WriteLine(" X == Y ");
            else          Console.WriteLine(" X != Y ");

            if ( X == Z ) Console.WriteLine(" X == Z ");
            else          Console.WriteLine(" X != Z ");

            if ( X.Equals(Y) ) Console.WriteLine( " X Equals Y " );
            else               Console.WriteLine( " X not Equals Y " );

            Console.WriteLine(X.GetType());
        }
    }
}
Листинг 8.5. Перегрузка методов класса object

Результат работы программы:

X != Y
X == Z
X Equals Y
ConsoleApplication1.Monster

Анализируя результат работы программы, можно увидеть, что в операции сравнения на равенство сравниваются ссылки, а в перегруженном методе Equals — значения. Для концептуального единства можно переопределить и операции отношения.

Вопросы и задания для самостоятельной работы студента

  1. Для чего используется наследование?
  2. Опишите синтаксис производного класса. Какие спецификаторы доступа применяются в иерархиях?
  3. Как вызвать метод базового класса из производного?
  4. Опишите порядок вызова конструкторов базовых классов при работе конструктора производного класса.
  5. Какие ключевые слова используется при переопределении методов базового класса в производном?
  6. Опишите механизмы раннего и позднего связывания.
  7. Опишите процесс вызова виртуального метода. Для чего применяются виртуальные методы?
  8. Все ли методы следует описывать как виртуальные?
  9. Для чего используются абстрактные классы?
  10. Какие методы и операции класса object часто перегружают в его потомках?
  11. Назовите альтернативы наследованию классов.
  12. Изучите по справочной системе свойства и методы класса object.
  13. Изучите разделы стандарта C#, касающиеся наследования.

Лабораторная работа 9. Наследование

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

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

Задание

Создать абстрактный класс Pair (пара значений) с виртуальными арифметическими операциями и методом вывода на экран. На его основе реализовать классы Money (деньги) и Complex (комплексное число).

В классе Money денежная сумма представляется в виде двух целых, в которых хранятся рубли и копейки соответственно. При выводе части числа снабжаются словами "руб." и "коп.". В классе Complex предусмотреть при выводе символ мнимой части (i).

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

< Лекция 7 || Лекция 8: 123 || Лекция 9 >
Владимир Сиников
Владимир Сиников
Россия