tipos superclase polimorfismo metodos herencia ejercicios ejemplos con calculadora java inheritance subclass superclass

java - polimorfismo - ¿Es posible llamar a los métodos de subclases en un objeto de superclase?



superclase java (9)

"Dije 2 ya que estamos verificando si el objeto es un perro; como perro es la clase con el método de la corteza, si es entonces lo llamamos que imprimirá: s"

Tu razonamiento es correcto, pero no es así como funciona.

Java es un lenguaje de tipo estático que significa que la validez de los métodos a los que un objeto puede responder se verifica en el momento de la compilación .

Usted puede pensar el cheque:

if( a instanceof Dog )

Lo haría, pero en realidad no lo hace. Lo que hace el compilador es verificar la "interfaz" del tipo declarado (Animal en este caso). La "interfaz" se compone de los métodos declarados en la clase Animal.

Si el método de corteza () no está definido en la súper clase Animal, el compilador dice: "Oye, eso no funcionará".

Esto es útil, porque "a veces" hacemos errores tipográficos al codificar (por ejemplo, tecleando barck ())

Si el compilador no nos advierte sobre esto, tendría que encontrarlo en "runtime" y no siempre con un mensaje claro (por ejemplo, javascript en IE dice algo como "objeto inesperado")

Aún así, el lenguaje de tipo estático como java nos permite forzar la llamada. En este caso está utilizando el operador "cast" ()

Me gusta esto

1. Animal a = new Dog(); 2. if (a instanceof Dog){ 3. Dog imADog = ( Dog ) a; 4. imADog.bark(); 5. }

En la línea 3 estás "lanzando" a un tipo de perro, por lo que el compilador puede verificar si la corteza es un mensaje válido.

Esta es una instrucción para que el compilador diga "Hola, yo soy el programador aquí, sé lo que estoy haciendo". Y el compilador, cheques, Ok, dog, puede recibir el mensaje bark (), proceder. Sin embargo, si en tiempo de ejecución el animal no es un perro, surgirá una excepción de tiempo de ejecución.

El reparto también podría abreviarse como:

if( a instanceof Dog ) { ((Dog)a).bark(); }

Eso correrá.

Entonces, la respuesta correcta es 4: " la llamada a ladrar provoca un error de tiempo de compilación "

Espero que esto ayude.

Animal es una superclase de Perro y Perro tiene un método llamado corteza.

public void bark() { System.out.println("woof"); }

Considera lo siguiente:

Animal a = new Dog(); if (a instanceof Dog){ a.bark(); }

¿Lo que sucederá?

  1. la tarea no está permitida
  2. se permite la llamada a ladrar y se imprime "woof" en tiempo de ejecución
  3. Se permite la llamada a ladrar pero no se imprime nada.
  4. la llamada a la corteza causa un error de compilación
  5. la llamada a ladrar da como resultado un error de tiempo de ejecución

Dije 2 ya que estamos comprobando si el objeto es un perro; como perro es la clase con el método de ladrido, si es así, lo llamamos que imprimirá: s

¿Mi entendimiento es correcto aquí?


En Head First Java utilizan la muy buena analogía de un control remoto de TV para una referencia y su TV como el objeto al que apunta la referencia. Si su control remoto solo tiene botones (métodos) para encendido, apagado, subir y bajar de canal y subir y bajar de volumen, no importa qué características geniales tenga su televisor. Aún puedes hacer esas pocas cosas básicas desde tu control remoto. No puede silenciar su TV, por ejemplo, si su control remoto no tiene botón de silencio.

La referencia de los animales solo conoce los métodos de los animales. No importa qué otros métodos tenga el objeto subyacente, no puede acceder a ellos desde una referencia de Animal.


En java (solo el idioma que conozco) puede crear un método vacío y llamarlo en súper clase. Luego puedes anularlo en la subclase para hacer lo que quieras. De esta manera la súper clase llama al método de su subclase.

public class Test { public static void main(String[] args){ Snake S = new Snake(); Dog d = new Dog(); } } class Animal{ //Super Class public Animal(){ bark(); //calls bark when a new animal is created } public void bark(){ System.out.println("this animal can''t bark"); } } class Dog extends Animal{ //Subclass 1 @Override public void bark(){ System.out.println("Woof"); } } class Snake extends Animal{//Subclass 2 public void tss(){ } }

Este código llama a un objeto de Snake y luego llama a un objeto de Dog. Escribe esto a la consola:

this animal can''t bark Woof

Snake no tiene ningún método de ladrido, así que se llama método de súper clase. Escribe la primera línea en la consola. El perro tiene un método de ladrido, así que la súper clase lo llama. Escribe la segunda línea en la consola.


Es 4. No puedes pedirle a un Animal genérico, que es lo que tu código dice que es, ladrar. Porque podrías haber dicho tan fácilmente

Animal a = new Cat();

y la línea de la corteza no tiene una manera de saber que usted no lo hizo.


Esto no se compilará ya que Animal no tiene un método llamado corteza. Piénsalo de esta manera, todos los perros son animales, pero no todos los animales son perros. Todos los perros ladran, pero no todos los animales ladran.


La clave está en la siguiente línea:

Animal a = new Dog();

Aunque se creó una nueva instancia de Dog , su referencia es por a que se declara de tipo Animal . Por lo tanto, cualquier referencia a a hace que el new Dog sea ​​manejado como un Animal .

Por lo tanto, a menos que Animal tenga un método de bark , la siguiente línea causará un error de compilación:

a.bark();

Aunque a se prueba para ver si es una instancia de Dog , y a instanceof Dog realmente devuelve true , la variable a todavía es de tipo Animal , por lo que el bloque dentro de la sentencia if aún se maneja como un Animal .

Esta es una característica de los lenguajes de tipo estático donde las variables se asignan un tipo por adelantado y se verifican en tiempo de compilación para ver si coinciden los tipos. Si este código se realizó en un lenguaje de tipo dinámico , donde los tipos se verifican en tiempo de ejecución, se podría permitir algo como lo siguiente:

var a = new Dog(); if (a instanceof Dog) a.bark();

Se garantiza que a.bark() solo se ejecuta cuando la instancia es un Dog , por lo que la llamada a bark siempre funcionará. Sin embargo, Java es un lenguaje de tipo estático, por lo que este tipo de código no está permitido.


Para su información, este no es un buen diseño.

Casi en cualquier momento tienes código de este formulario:

if (x instanceof SomeClass) { x.SomeMethod(); }

Estás abusando del sistema de tipos. Esta no es la forma de usar clases, no es la forma de escribir código orientado a objetos que se pueda mantener. Es frágil Está enrevesado. Es malo.

Puede crear métodos de plantilla en una clase base, pero tienen que llamar a métodos que existen en la clase base y que se anulan en subclases.


Si la idea es imprimir el método de subclase desde un objeto de superclase, esto funcionará:

En lugar de Animal a = new Dog(); if (a instanceof Dog){ a.bark(); } Animal a = new Dog(); if (a instanceof Dog){ a.bark(); } Animal a = new Dog(); if (a instanceof Dog){ a.bark(); } cambiar a

Animal a = new Dog(); if (a instanceof Dog){ Dog d = (Dog) a; d.bark(); }

Esto convierte la superclase en subclase y la imprime. aunque es un mal diseño, es una forma de saber a qué objeto de clase secundaria apunta dinámicamente.


no - la respuesta es;

4) la llamada a la corteza causa un error de tiempo de compilación

el método de corteza no se define como un método en el tipo de animal asignado, que por lo tanto resultará en un problema de tiempo de compilación; Esto podría ser resuelto por fundición;

((Dog)a).bark();