Menu
Coddy logo textTech

Базовый класс 'object'

Часть раздела Объектно-ориентированное программирование путешествия по C# на Coddy — урок 23 из 70.

В C# каждый создаваемый вами класс автоматически наследуется от специального класса, называемого object. Даже если вы явно не указываете базовый класс, вашим конечным предком все равно остается object. Это означает, что каждый тип в C# имеет общий набор методов.

Класс object предоставляет несколько виртуальных методов, которые вы можете переопределить в своих собственных классах:

public class Person
{
    public string Name { get; set; }
    
    // Переопределение из object
    public override string ToString()
    {
        return $"Person: {Name}";
    }
    
    public override bool Equals(object obj)
    {
        if (obj is Person other)
            return Name == other.Name;
        return false;
    }
    
    public override int GetHashCode()
    {
        return Name?.GetHashCode() ?? 0;
    }
}

Три наиболее часто переопределяемых метода — это ToString() для строкового представления, Equals() для сравнения объектов и GetHashCode() для коллекций на основе хеша. По умолчанию ToString() возвращает имя типа, а Equals() проверяет ссылочное равенство.

Поскольку всё наследуется от object, вы можете хранить любой тип в переменной object:

object item1 = new Person { Name = "Alice" };
object item2 = 42;
object item3 = "Hello";

Console.WriteLine(item1.ToString());  // Person: Alice

Этот универсальный базовый класс — это то, что делает возможными такие функции, как коллекции, содержащие смешанные типы, и именно поэтому каждый объект в C# имеет доступ к таким методам, как ToString() и GetType().

challenge icon

Задание

Легко

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

Вы создадите два файла для организации своего кода:

  • Book.cs: Определите класс Book в пространстве имен Library. Ваша книга должна иметь свойства Title (string) и Author (string), а также конструктор, который устанавливает оба значения. Переопределите три ключевых метода, унаследованных от object:
    • ToString() должен возвращать "{Title} by {Author}"
    • Equals(object obj) должен возвращать true, если другой объект является Book с тем же Title и Author
    • GetHashCode() должен комбинировать хэш-коды обоих свойств
  • Program.cs: В основном файле создайте две книги, используя входные значения. Выведите каждую книгу с помощью ToString(), затем проверьте, равны ли они, и напечатайте результат. Наконец, продемонстрируйте, что вы можете сохранить Book в переменной типа object и при этом получить осмысленный вывод при вызове ToString().

Вы получите четыре входных значения:

  • Название первой книги
  • Автор первой книги
  • Название второй книги
  • Автор второй книги

Выведите результат в следующем формате:

Book 1: {ToString result}
Book 2: {ToString result}
Are they equal? {True/False}
Stored as object: {ToString result of first book stored in object variable}

Например, если входные данные — 1984, George Orwell, 1984 и George Orwell, вывод должен быть следующим:

Book 1: 1984 by George Orwell
Book 2: 1984 by George Orwell
Are they equal? True
Stored as object: 1984 by George Orwell

Если входные данные — 1984, George Orwell, Brave New World и Aldous Huxley, вывод должен быть следующим:

Book 1: 1984 by George Orwell
Book 2: Brave New World by Aldous Huxley
Are they equal? False
Stored as object: 1984 by George Orwell

Обратите внимание, как переопределенные методы придают объектам Book осмысленное поведение — они красиво отображаются в виде строк и могут сравниваться по их содержимому, а не только по ссылкам в памяти!

Шпаргалка

В C# каждый класс автоматически наследуется от класса object, который предоставляет несколько виртуальных методов, которые можно переопределить:

Общие методы Object для переопределения

  • ToString() - Возвращает строковое представление объекта (по умолчанию возвращает имя типа)
  • Equals(object obj) - Сравнивает объекты на равенство (по умолчанию проверяет ссылочное равенство)
  • GetHashCode() - Возвращает хэш-код для использования в хэш-коллекциях

Переопределение методов Object

public class Person
{
    public string Name { get; set; }
    
    // Переопределение ToString для пользовательского строкового представления
    public override string ToString()
    {
        return $"Person: {Name}";
    }
    
    // Переопределение Equals для сравнения на основе содержимого
    public override bool Equals(object obj)
    {
        if (obj is Person other)
            return Name == other.Name;
        return false;
    }
    
    // Переопределение GetHashCode для хэш-коллекций
    public override int GetHashCode()
    {
        return Name?.GetHashCode() ?? 0;
    }
}

Универсальный базовый класс

Любой тип может быть сохранен в переменной object:

object item1 = new Person { Name = "Alice" };
object item2 = 42;
object item3 = "Hello";

Console.WriteLine(item1.ToString());  // Person: Alice

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

Попробуйте сами

using System;
using Library;

class Program
{
    public static void Main(string[] args)
    {
        // Считать ввод для двух книг
        string title1 = Console.ReadLine();
        string author1 = Console.ReadLine();
        string title2 = Console.ReadLine();
        string author2 = Console.ReadLine();

        // TODO: Создать два объекта Book, используя введенные значения

        // TODO: Вывести Книгу 1, используя ToString()
        // Формат: "Book 1: {ToString result}"

        // TODO: Вывести Книгу 2, используя ToString()
        // Формат: "Book 2: {ToString result}"

        // TODO: Проверить, равны ли книги, и вывести результат
        // Формат: "Are they equal? {True/False}"

        // TODO: Сохранить первую книгу в переменную типа object и вывести ее
        // Формат: "Stored as object: {ToString result}"
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование