Класс 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 и почему определенные методы доступны в каждом создаваемом вами объекте.
Задание
ЛегкоДавайте изучим, как класс Object служит универсальным родителем для всех классов Java, создав простую систему инвентаризации гаджетов, которая демонстрирует методы, унаследованные от Object.
Вы создадите три файла для организации вашего кода:
Gadget.java: Создайте класс, представляющий электронный гаджет. Ваш класс должен иметь:- Приватные поля для
name(String) иyear(int) - Конструктор, который инициализирует оба поля
- Методы-геттеры
getName()иgetYear()
- Приватные поля для
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())
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово thisМетодыПоля (атрибуты)Метод-конструкторПерегрузка конструкторовИтоги — Простой калькулятор4Наследование
Основы наследования (extends)Ключевое слово superПереопределение методов (@Override)Цепочка конструкторовКласс ObjectОдиночное и многоуровневое наследованиеПочему нет множественного наследования классовИтоги — Иерархия сотрудников7Специальные методы и класс Object
Метод toString()equals() и hashCode()Метод clone()compareTo() и ComparableИнтерфейс ComparatorПовторение — Кастомная сортировка2Модификаторы доступа и инкапсуляция
Обзор уровней доступаМетоды геттеры и сеттерыСокрытие данныхКлючевое слово finalИтоги — Менеджер банковского счета5Полиморфизм
Основы перегрузки методовПереопределение методов (Run-Time)Upcasting и DowncastingОператор instanceofАбстрактные классы и методыИтоги: Калькулятор фигур8Продвинутые концепции ООП
Композиция против наследованияАгрегация против композицииВнутренние, вложенные и анонимные классыEnums и методы перечисленийRecords (Java 16+)Sealed-классы (Java 17+)11Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн BuilderПаттерн ObserverПаттерн Strategy3Свойства класса и статические члены
Переменные экземпляра и статические переменныеСтатические методыСтатические блокиКонстанты (static final)Итоги: Счетчик и утилиты6Интерфейсы и абстрактные классы
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовDefault и Static методы в интерфейсахАбстрактные классы vs ИнтерфейсыФункциональные интерфейсыИтоги — Платежная система9Обобщения
Введение в обобщенияОбобщенные классыОбобщенные методыОграниченные параметры типаСимволы подстановки (Wildcards: ?, extends, super)Итоги — Обобщенный контейнер12Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»Паттерн «Итератор»