Menu
Coddy logo textTech

Класс Object

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

В Java каждый создаваемый вами класс автоматически наследуется от специального класса, называемого Object. Даже если вы нигде не пишете extends, ваш класс все равно является потомком Object. Это делает Object корнем всей иерархии классов.

public class Person {
    // Это неявно наследует Object
}

// Эквивалентно:
public class Person extends Object {
}

Поскольку каждый класс наследуется от Object, каждый объект в Java имеет доступ к нескольким встроенным методам. Наиболее часто используемые из них включают:

МетодНазначение
toString()Возвращает строковое представление объекта
equals(Object obj)Сравнивает два объекта на равенство
hashCode()Возвращает значение хэш-кода для объекта
getClass()Возвращает класс объекта во время выполнения

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

Person p = new Person();
System.out.println(p.toString());  // Вывод: Person@1a2b3c4d

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

challenge icon

Задание

Легко

Давайте изучим, как класс Object служит универсальным родителем для всех классов Java, создав простую систему инвентаризации гаджетов, которая демонстрирует методы, унаследованные от Object.

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

  • Gadget.java: Создайте класс, представляющий электронный гаджет. Ваш класс должен иметь:
    • Приватные поля для name (String) и year (int)
    • Конструктор, который инициализирует оба поля
    • Методы-геттеры getName() и getYear()
    Не переопределяйте никакие методы из Object — мы хотим сначала увидеть поведение по умолчанию.
  • Smartphone.java: Создайте подкласс, который расширяет Gadget и добавляет специфические для смартфона функции:
    • Приватное поле для brand (String)
    • Конструктор, который принимает name, year и brand — используйте super(name, year) для родительской части
    • Метод getBrand(), который возвращает бренд
    • Переопределите метод toString(), чтобы он возвращал: Smartphone: [brand] [name] ([year])
  • Main.java: Продемонстрируйте разницу между стандартными и переопределенными методами Object. Вы получите три входных значения: название гаджета, год и бренд. Создайте объекты Gadget и Smartphone, используя одно и то же имя и год (плюс бренд для смартфона), затем:
    • Выведите имя класса гаджета, используя getClass().getSimpleName()
    • Выведите, содержит ли стандартный метод toString() гаджета символ "@" (выведите true или false)
    • Выведите объект smartphone, используя его переопределенный метод toString()

Вы получите три входных значения: название гаджета/смартфона (String), год (int) и бренд (String).

Эта задача показывает, почему переопределение методов Object имеет значение: стандартный toString() выдает что-то вроде Gadget@1a2b3c, в то время как ваша пользовательская версия предоставляет осмысленную информацию!

Шпаргалка

В Java каждый класс автоматически наследуется от класса Object, что делает его корнем всей иерархии классов:

public class Person {
    // Это неявно расширяет Object
}

// Эквивалентно:
public class Person extends Object {
}

Каждый объект в Java имеет доступ к нескольким встроенным методам, унаследованным от Object:

МетодНазначение
toString()Возвращает строковое представление объекта
equals(Object obj)Сравнивает два объекта на равенство
hashCode()Возвращает значение хэш-кода для объекта
getClass()Возвращает класс объекта во время выполнения

По умолчанию toString() возвращает имя класса, за которым следует адрес объекта в памяти:

Person p = new Person();
System.out.println(p.toString());  // Вывод: Person@1a2b3c4d

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

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

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Чтение входных данных
        String name = scanner.nextLine();
        int year = scanner.nextInt();
        scanner.nextLine(); // поглощение символа новой строки
        String brand = scanner.nextLine();
        
        // TODO: Создайте объект Gadget с name и year
        
        // TODO: Создайте объект Smartphone с name, year и brand
        
        // TODO: Выведите имя класса gadget, используя getClass().getSimpleName()
        
        // TODO: Выведите, содержит ли toString() объекта gadget символ "@" (true или false)
        
        // TODO: Выведите smartphone (использует переопределенный toString())
        
    }
}
quiz iconПроверьте себя

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

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