La clase Object
Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy — lección 24 de 87.
En Java, cada clase que creas hereda automáticamente de una clase especial llamada Object. Incluso si no escribes extends en ningún lugar, tu clase sigue siendo una hija de Object. Esto convierte a Object en la raíz de toda la jerarquía de clases.
public class Person {
// Esto extiende implícitamente a Object
}
// Es equivalente a:
public class Person extends Object {
}Debido a que cada clase hereda de Object, cada objeto en Java tiene acceso a varios métodos integrados. Los más utilizados incluyen:
| Método | Propósito |
|---|---|
toString() | Devuelve una representación en cadena del objeto |
equals(Object obj) | Compara dos objetos para determinar su igualdad |
hashCode() | Devuelve un valor de código hash para el objeto |
getClass() | Devuelve la clase en tiempo de ejecución del objeto |
Por defecto, estos métodos tienen implementaciones genéricas. Por ejemplo, toString() devuelve el nombre de la clase seguido de la dirección de memoria del objeto, lo cual no es muy útil:
Person p = new Person();
System.out.println(p.toString()); // Salida: Person@1a2b3c4dEsta es la razón por la que a menudo sobrescribirás estos métodos en tus propias clases para proporcionar un comportamiento significativo. Comprender que Object es el padre universal ayuda a explicar por qué puedes almacenar cualquier objeto en una variable Object y por qué ciertos métodos están disponibles en cada objeto que creas.
Desafío
FácilExploremos cómo la clase Object sirve como el padre universal de todas las clases de Java construyendo un sistema simple de inventario de dispositivos que demuestre los métodos heredados de Object.
Crearás tres archivos para organizar tu código:
Gadget.java: Crea una clase que represente un dispositivo electrónico. Tu clase debe tener:- Campos privados para
name(String) yyear(int) - Un constructor que inicialice ambos campos
- Métodos getter
getName()ygetYear()
- Campos privados para
Smartphone.java: Crea una subclase que extienda a Gadget y añada características específicas de un smartphone:- Un campo privado para
brand(String) - Un constructor que reciba name, year y brand; usa
super(name, year)para la parte del padre - Un método
getBrand()que devuelva la marca - Sobrescribe el método
toString()para que devuelva:Smartphone: [brand] [name] ([year])
- Un campo privado para
Main.java: Demuestra la diferencia entre los métodos deObjectpor defecto y los sobrescritos. Recibirás tres entradas: un nombre de dispositivo, el año y la marca. Crea tanto unGadgetcomo unSmartphoneusando el mismo nombre y año (más la marca para el smartphone), luego:- Imprime el nombre de la clase del gadget usando
getClass().getSimpleName() - Imprime si el
toString()por defecto del gadget contiene el símbolo "@" (imprimetrueofalse) - Imprime el smartphone usando su
toString()sobrescrito
- Imprime el nombre de la clase del gadget usando
Recibirás tres entradas: el nombre del gadget/smartphone (String), el año (int) y la marca (String).
¡Este desafío muestra por qué es importante sobrescribir los métodos de Object: el toString() por defecto te da algo como Gadget@1a2b3c, mientras que tu versión personalizada proporciona información significativa!
Hoja de referencia
En Java, cada clase hereda automáticamente de la clase Object, convirtiéndola en la raíz de toda la jerarquía de clases:
public class Person {
// Esto extiende implícitamente a Object
}
// Es equivalente a:
public class Person extends Object {
}Cada objeto en Java tiene acceso a varios métodos integrados heredados de Object:
| Método | Propósito |
|---|---|
toString() | Devuelve una representación en cadena del objeto |
equals(Object obj) | Compara dos objetos para determinar su igualdad |
hashCode() | Devuelve un valor de código hash para el objeto |
getClass() | Devuelve la clase en tiempo de ejecución del objeto |
Por defecto, toString() devuelve el nombre de la clase seguido de la dirección de memoria del objeto:
Person p = new Person();
System.out.println(p.toString()); // Salida: Person@1a2b3c4dPuedes sobrescribir estos métodos en tus propias clases para proporcionar un comportamiento significativo. Puedes almacenar cualquier objeto en una variable de tipo Object ya que todas las clases heredan de ella.
Pruébalo tú mismo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Leer entradas
String name = scanner.nextLine();
int year = scanner.nextInt();
scanner.nextLine(); // consumir nueva línea
String brand = scanner.nextLine();
// TODO: Crear un objeto Gadget con name y year
// TODO: Crear un objeto Smartphone con name, year y brand
// TODO: Imprimir el nombre de la clase del gadget usando getClass().getSimpleName()
// TODO: Imprimir si el toString() del gadget contiene "@" (true o false)
// TODO: Imprimir el smartphone (usa el toString() sobrescrito)
}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosIntroducción a la OOPClases vs. ObjetosLa palabra clave thisMétodosCampos (Atributos)Método constructorSobrecarga de constructoresResumen - Calculadora simple4Herencia
Herencia básica (extends)La palabra clave superSobrescritura de métodos (@Override)Encadenamiento de constructoresLa clase ObjectHerencia simple y multinivelPor qué no hay herencia múltiple de clasesResumen - Jerarquía de empleados7Métodos especiales y la clase Object
Método toString()equals() y hashCode()Método clone()compareTo() y ComparableInterfaz ComparatorResumen - Ordenamiento personalizado2Modificadores de acceso y encapsulamiento
Visión general de los niveles de accesoMétodos Getter y SetterOcultamiento de informaciónLa palabra clave finalResumen - Gestor de cuentas bancarias5Polimorfismo
Fundamentos de sobrecarga de métodosSobrescritura de métodos (tiempo de ejecución)Upcasting y DowncastingEl operador instanceofClases y métodos abstractosResumen - Calculadora de figuras8Conceptos avanzados de POO
Composición vs. HerenciaAgregación vs. ComposiciónClases internas, anidadas y anónimasEnums y métodos de EnumRecords (Java 16+)Clases selladas (Java 17+)11Patrones de diseño - Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón BuilderPatrón ObserverPatrón Strategy3Propiedades de clase y miembros estáticos
Variables de instancia vs. estáticasMétodos estáticosBloques estáticosConstantes (static final)Repaso - Contador y utilidad6Interfaces y Clases Abstractas
Introducción a las InterfacesImplementación de InterfacesImplementación de Múltiples InterfacesMétodos Default y Static en InterfacesClases Abstractas vs InterfacesInterfaces FuncionalesResumen - Sistema de Pagos9Genéricos
Introducción a los genéricosClases genéricasMétodos genéricosParámetros de tipo delimitadosComodines (?, extends, super)Resumen - Contenedor genérico12Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Iterator