Polimorfismo vs anulación vs sobrecarga


347

En términos de Java, cuando alguien pregunta:

¿Qué es el polimorfismo?

¿Podría sobrecargar o anulando sería una respuesta aceptable?

Creo que hay algo más que eso.

SI tuvo una clase base abstracta que definió un método sin implementación, y definió ese método en la subclase, ¿eso todavía se anula?

Creo que la sobrecarga no es la respuesta correcta con seguridad.


Las respuestas a continuación explican muy bien sobre el polimorfismo. Pero tengo una fuerte objeción para decir que la sobrecarga es un tipo de polimorfismo, que traté de justificar en mi pregunta y respuesta que en realidad se concentra en la sobrecarga es polimorfismo o no. Intenté justificar la respuesta @The Digital Gabeg presente en este hilo. Consulte Elaboración: la sobrecarga de métodos es un enlace estático / tiempo de compilación pero no polimorfismo. ¿Es correcto correlacionar la unión estática con el polimorfismo?
PraveenKumar Lalasangi

Respuestas:


894

La forma más clara de expresar el polimorfismo es a través de una clase base abstracta (o interfaz)

public abstract class Human{
   ...
   public abstract void goPee();
}

Esta clase es abstracta porque el goPee() método no es definible para los humanos. Solo se puede definir para las subclases Masculino y Femenino. Además, Humano es un concepto abstracto: no se puede crear un ser humano que no sea Hombre ni Mujer. Tiene que ser uno u otro.

Entonces aplazamos la implementación usando la clase abstracta.

public class Male extends Human{
...
    @Override
    public void goPee(){
        System.out.println("Stand Up");
    }
}

y

public class Female extends Human{
...
    @Override
    public void goPee(){
        System.out.println("Sit Down");
    }
}

Ahora podemos decirle a toda una habitación llena de humanos que orinen.

public static void main(String[] args){
    ArrayList<Human> group = new ArrayList<Human>();
    group.add(new Male());
    group.add(new Female());
    // ... add more...

    // tell the class to take a pee break
    for (Human person : group) person.goPee();
}

Ejecutar esto produciría:

Stand Up
Sit Down
...

37
@yuudachi. Se me ocurrió este ejemplo cuando daba una clase. La clase canónica de "cuenta bancaria" no expresaba realmente la "abstracción" de la clase base. El otro ejemplo canónico (Animal, hacer ruido) era demasiado abstracto para su comprensión. Estaba buscando una base única con subclases demasiado obvias. En realidad, goPee () fue el único ejemplo que se me ocurrió que no era sexista o estereotípico. (aunque en clase, imprimí "al final del pasillo a la izquierda" en lugar de pararse o sentarse).
Chris Cudmore

100
Este ejemplo también destaca muy bien la dificultad de usar un sistema jerárquico para describir sistemas biológicos. Algunos humanos, como los muy pequeños, hacen pipí en casi cualquier posición, y no se les puede decir fácilmente a los bebés que vayan (). Algunos humanos son intersexuales, donde las etiquetas biológicas de "hombre" o "mujer" se vuelven bastante mal definidas; Los significados sociales son aún más complejos. Como ejemplo de enseñanza, muestra cómo los supuestos de modelado pueden tener resultados negativos, como la implicación de que alguien (por ejemplo, un estudiante de programación OO) que es incontinente o intersexual no es realmente humano.
Andrew Dalke

77
Puedo pensar en al menos un puñado de humanos que refutarían tu tesis de "no puedes crear un humano que no sea ni hombre ni mujer", aunque todavía sería cierto para tu código ... mala abstracción, supongo que estoy diciendo. ? ;)
Frank W. Zammetti

2
Creo que es importante señalar que solo es polimorfismo porque a qué versión de goPee () llamar solo se puede determinar en tiempo de ejecución. Si bien este ejemplo implica eso, es bueno señalar por qué exactamente eso es polimorfismo. Además, no requiere clases de hermanos. También puede ser una relación padre-hijo. O incluso clases completamente no relacionadas que casualmente tienen la misma función. Un ejemplo de esto puede ser la función .toString (). Que se puede llamar aleatoriamente en cualquier objeto, pero el compilador nunca puede saber exactamente qué tipo de objeto.
Tor Valamo

20
@AndrewDalke, +1 para notas sobre complejidad biológica. Además, goPeeno toma un campo gravitacional como entrada. Esta dependencia del estado global CatheterizedIntersexAstronautdificulta las pruebas unitarias y muestra que la subclasificación puede no ser siempre el mejor método para la composición de rasgos.
Mike Samuel

99

Polimorfismo es la capacidad de una instancia de clase de comportarse como si fuera una instancia de otra clase en su árbol de herencia, la mayoría de las veces una de sus clases ancestrales. Por ejemplo, en Java todas las clases heredan de Object. Por lo tanto, puede crear una variable de tipo Objeto y asignarle una instancia de cualquier clase.

Un anulaciónes un tipo de función que ocurre en una clase que hereda de otra clase. Una función de anulación "reemplaza" una función heredada de la clase base, pero lo hace de tal manera que se llama incluso cuando una instancia de su clase pretende ser un tipo diferente a través del polimorfismo. En referencia al ejemplo anterior, puede definir su propia clase y anular la función toString (). Dado que esta función se hereda de Object, seguirá estando disponible si copia una instancia de esta clase en una variable de tipo Object. Normalmente, si llama a toString () en su clase mientras finge ser un Object, la versión de toString que realmente se activará es la que se define en el Object. Sin embargo, debido a que la función es una anulación, la definición de toString () de su clase se usa incluso cuando la instancia de clase '

La sobrecarga es la acción de definir múltiples métodos con el mismo nombre, pero con diferentes parámetros. No está relacionado ni con la anulación ni con el polimorfismo.


8
Esto es antiguo, pero el polimorfismo no implica que la otra clase deba estar en el árbol de herencia. Lo hace en Java si considera que las interfaces son parte del árbol de herencia, pero no en Go, donde las interfaces se implementan implícitamente.
JN

55
En realidad, no necesitas clases de polimorfismo en absoluto.
StCredZero 01 de

3
Soy un novato, y corrígeme si me equivoco, pero no diría que la sobrecarga no está relacionada con el polimorfismo. Al menos en Java, el polimorfismo es cuando la implementación se elige en función del tipo de la persona que llama, y ​​la sobrecarga es cuando la implementación se elige en función del tipo de parámetros, ¿no es así? Ver la similitud entre los dos me ayuda a entenderlo.
csjacobs24

99
Incorrecto. Ad hoc polymorphismes lo que describiste en tu sección Sobrecarga y es un caso de polimorfismo.
Jossie Calderon

1
"No está relacionado ni con la anulación ni con el polimorfismo". Esta afirmación está mal.
Shailesh Pratapwar

45

Polimorfismo significa más de una forma, el mismo objeto realiza diferentes operaciones de acuerdo con el requisito.

El polimorfismo se puede lograr usando dos formas, esas son

  1. Método de anulación
  2. Método de sobrecarga

La sobrecarga de métodos significa escribir dos o más métodos en la misma clase usando el mismo nombre de método, pero los parámetros de paso son diferentes.

La anulación del método significa que usamos los nombres de los métodos en las diferentes clases, lo que significa que el método de la clase primaria se usa en la clase secundaria.

En Java para lograr el polimorfismo, una variable de referencia de superclase puede contener el objeto de subclase.

Para lograr el polimorfismo, cada desarrollador debe usar los mismos nombres de método en el proyecto.


44
+1 para una buena respuesta. La respuesta aceptada solo explica un tipo de polimorfismo. Esta respuesta está completa.
apadana

1
El polimorfismo es un paradigma (OOP), pero anular y sobrecargar son facilidades de lenguaje.
曾 其 威

El polimorfismo también se puede lograr por tipo genérico.
Minh Nghĩa

43

Aquí hay un ejemplo de polimorfismo en pseudo-C # / Java:

class Animal
{
    abstract string MakeNoise ();
}

class Cat : Animal {
    string MakeNoise () {
        return "Meow";
    }
}

class Dog : Animal {
    string MakeNoise () {
        return "Bark";
    }
}

Main () {
   Animal animal = Zoo.GetAnimal ();
   Console.WriteLine (animal.MakeNoise ());
}

La función Main no conoce el tipo de animal y depende del comportamiento de una implementación particular del método MakeNoise ().

Editar: Parece que Brian me ganó el golpe. Es curioso que utilizamos el mismo ejemplo. Pero el código anterior debería ayudar a aclarar los conceptos.


Es un ejemplo de polimorfismo en tiempo de ejecución. El polimorfismo en tiempo de compilación también es posible mediante la sobrecarga de métodos y los tipos genéricos.
Pete Kirkham el

Forma -> Paralelogramo -> Rectángulo -> Cuadrado
mpen

@ yankee2905 en este caso, creo que podría usar interfaces, ya que una clase podría implementar múltiples interfaces.
Sam003

1
@Zhisheng ¿O agregar un método de orinar en la clase padre abstracta? Usaría la interfaz para implementar algo más.
Joey Rohan

42

Tanto la anulación como la sobrecarga se utilizan para lograr el polimorfismo.

Podría tener un método en una clase que se anule en una o más subclases. El método hace cosas diferentes dependiendo de qué clase se usó para instanciar un objeto.

    abstract class Beverage {
       boolean isAcceptableTemperature();
    }

    class Coffee extends Beverage {
       boolean isAcceptableTemperature() { 
           return temperature > 70;
       }
    }

    class Wine extends Beverage {
       boolean isAcceptableTemperature() { 
           return temperature < 10;
       }
    }

También podría tener un método que esté sobrecargado con dos o más conjuntos de argumentos. El método hace cosas diferentes en función del tipo (s) de argumento (s) pasado (s).

    class Server {
        public void pour (Coffee liquid) {
            new Cup().fillToTopWith(liquid);
        }

        public void pour (Wine liquid) {
            new WineGlass().fillHalfwayWith(liquid);
        }

        public void pour (Lemonade liquid, boolean ice) {
            Glass glass = new Glass();
            if (ice) {
                glass.fillToTopWith(new Ice());
            }
            glass.fillToTopWith(liquid);
        }
    }

Supongo que fue rechazado porque históricamente la sobrecarga de métodos no se considera parte del polimorfismo en el paradigma orientado a objetos. La sobrecarga de métodos y el polimorfismo son dos características ortogonales e independientes de un lenguaje de programación.
Sergio Acosta

77
Como dije en mi respuesta aquí, no estoy de acuerdo: las dos características no son ortogonales, pero están estrechamente relacionadas. Polimorfismo! = Herencia. Tienes mi voto positivo.
Peter Meyer

2
En otras palabras, escriba polimorfismo versus polimorfismo ad-hoc. Estoy votando esta respuesta, incluso si no es tan completa como debería, porque indica correctamente que tanto la sobrecarga como la anulación están relacionadas con el polimorfismo. Decir que el polimorfismo en los lenguajes OOP solo se puede lograr mediante la herencia de clases es simplemente incorrecto: debemos recordar que hay otros lenguajes OOP además de Java y C ++, donde uno puede usar conceptos como despacho múltiple, polimorfismo ad hoc, polimorfismo paramétrico, etc. .
rsenna

2
@rsenna Esto podría estar incompleto pero responde la pregunta mucho mejor que el resto en mi humilde opinión. Además, es muy agradable que hayas mencionado el polimorfismo ad-hoc y paramétrico.
Valentin Radu

15

Tienes razón en que la sobrecarga no es la respuesta.

Ninguno de los dos es primordial. La anulación es el medio por el cual se obtiene el polimorfismo. El polimorfismo es la capacidad de un objeto para variar el comportamiento en función de su tipo. Esto se demuestra mejor cuando la persona que llama de un objeto que exhibe polimorfismo no es consciente de qué tipo específico es el objeto.


3
No debería ser el comportamiento del objeto lo que cambia, sino su implementación. El mismo comportamiento, implementación diferente, eso es polimorfismo.
QBziZ

@QBziZ Necesita definir el comportamiento , especialmente el mismo adjetivo . Si el comportamiento es el mismo, ¿por qué su implementación debería ser diferente? No es que alguien no esté satisfecho con una determinada implementación, por lo tanto, requiere una diferente.
Sнаđошƒаӽ

11

Específicamente decir sobrecarga o anulación no da la imagen completa. El polimorfismo es simplemente la capacidad de un objeto para especializar su comportamiento en función de su tipo.

No estaría de acuerdo con algunas de las respuestas aquí en que la sobrecarga es una forma de polimorfismo (polimorfismo paramétrico) en el caso de que un método con el mismo nombre pueda comportarse de manera diferente, dando diferentes tipos de parámetros. Un buen ejemplo es la sobrecarga del operador. Puede definir "+" para aceptar diferentes tipos de parámetros, digamos cadenas o int, y en función de esos tipos, "+" se comportará de manera diferente.

El polimorfismo también incluye métodos de herencia y anulación, aunque pueden ser abstractos o virtuales en el tipo base. En términos de polimorfismo basado en herencia, Java solo admite herencia de clase única limitando su comportamiento polimórfico al de una sola cadena de tipos base. Java admite la implementación de múltiples interfaces, que es otra forma de comportamiento polimórfico.


Tienes razón en términos de lo que significan las palabras involucradas en general, pero en un contexto de programación, cuando la gente dice "polimorfismo" siempre significa "polimorfismo basado en la herencia". Punto interesante, pero creo que describir el polimorfismo de esta manera confundirá a las personas.
The Digital Gabeg

Puede ser más fácil explicar el polimorfismo solo en términos de herencia, pero por la forma en que se hizo esta pregunta en particular, creo que es prudente describir también el polimorfismo paramétrico.
Patrick McElhaney

44
Para que quede claro, creo que las diferentes formas deberían enunciarse, lo que ni siquiera he hecho adecuadamente, porque aquí hay algunas respuestas que se presentan como absolutas. Respeto respetuosamente que en "contexto de programador ... 'polimorfismo' siempre significa 'polimorfismo basado en la herencia'"
Peter Meyer,

2
Creo que la sobrecarga se clasifica mejor como Ad-hoc_polymorphism en.wikipedia.org/wiki/…
Manu

Tiendo a estar de acuerdo con 'The Digital Gabeg' en lo siguiente. Si está discutiendo OOP, el polimorfismo generalmente significa polimorfismo de subtipo, y si está discutiendo sobre la teoría de tipos, significa cualquier tipo de polimorfismo. Pero como usted dice, con 'contexto de programador' es demasiado ambiguo para burlarse.
Manu

7

El polimorfismo simplemente significa "muchas formas".

No REQUIERE herencia para lograr ... ya que la implementación de la interfaz, que no es herencia en absoluto, satisface las necesidades polimórficas. Podría decirse que la implementación de la interfaz satisface las necesidades polimórficas "Mejor" que la herencia.

Por ejemplo, ¿crearías una superclase para describir todas las cosas que pueden volar? Debería pensar que no. Sería mejor para usted crear una interfaz que describa el vuelo y dejarlo así.

Entonces, dado que las interfaces describen el comportamiento, y los nombres de los métodos describen el comportamiento (para el programador), no es demasiado difícil considerar la sobrecarga del método como una forma menor de polimorfismo.


2
Definitivamente la mejor respuesta hasta ahora. El polimorfismo se puede aplicar a todas las construcciones del lenguaje, ya sean sustantivos (clases) o verbos (métodos).
Radu Gasler

6

El ejemplo clásico, los perros y los gatos son animales, los animales tienen el método makeNoise. Puedo iterar a través de una serie de animales llamando a makeNoise sobre ellos y esperar que hagan la implementación respectiva.

El código de llamada no tiene que saber qué animal específico son.

Eso es lo que yo pienso como polimorfismo.


4

El polimorfismo es la capacidad de un objeto de aparecer en múltiples formas. Esto implica el uso de la herencia y las funciones virtuales para construir una familia de objetos que pueden intercambiarse. La clase base contiene los prototipos de las funciones virtuales, posiblemente no implementadas o con implementaciones predeterminadas según lo dicte la aplicación, y las diversas clases derivadas las implementan de manera diferente para afectar diferentes comportamientos.


4

Ninguno:

La sobrecarga es cuando tienes el mismo nombre de función que toma parámetros diferentes.

La anulación es cuando una clase secundaria reemplaza el método de un padre por uno propio (esto en sí mismo no constituye polimorfismo).

El polimorfismo es un enlace tardío, por ejemplo, se llama a los métodos de la clase base (padre), pero no hasta que el tiempo de ejecución sepa cuál es el objeto real; puede ser una clase secundaria cuyos métodos son diferentes. Esto se debe a que cualquier clase secundaria se puede usar donde se define una clase base.

En Java, se ve mucho el polimorfismo con la biblioteca de colecciones:

int countStuff(List stuff) {
  return stuff.size();
}

La lista es la clase base, el compilador no tiene idea si está contando una lista vinculada, un vector, una matriz o una implementación de lista personalizada, siempre que actúe como una Lista:

List myStuff = new MyTotallyAwesomeList();
int result = countStuff(myStuff);

Si estuvieras sobrecargando tendrías:

int countStuff(LinkedList stuff) {...}
int countStuff(ArrayList stuff) {...}
int countStuff(MyTotallyAwesomeList stuff) {...}
etc...

y el compilador seleccionaría la versión correcta de countStuff () para que coincida con los parámetros.


4

Aunque, el polimorfismo ya se explica con gran detalle en esta publicación, pero me gustaría poner más énfasis en por qué parte de él.

Por qué el polimorfismo es tan importante en cualquier lenguaje OOP.

Intentemos crear una aplicación simple para un televisor con y sin herencia / polimorfismo. Publicar cada versión de la aplicación, hacemos una pequeña retrospectiva.

Supongamos que usted es ingeniero de software en una compañía de TV y se le pide que escriba software para controladores de volumen, brillo y color para aumentar y disminuir sus valores en el comando del usuario.

Comienza escribiendo clases para cada una de estas características agregando

  1. set: - Para establecer un valor de un controlador. (Suponiendo que este tenga un código específico del controlador)
  2. get: - Para obtener un valor de un controlador. (Suponiendo que esto tenga un código específico del controlador)
  3. ajustar: - Para validar la entrada y configurar un controlador. (Validaciones genéricas .. independientes de los controladores)
  4. mapeo de entrada del usuario con controladores: - Para obtener la entrada del usuario e invocar controladores en consecuencia.

Versión de aplicación 1

import java.util.Scanner;    
class VolumeControllerV1 {
    private int value;
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class  BrightnessControllerV1 {
    private int value;
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class ColourControllerV1    {
    private int value;
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}

/*
 *       There can be n number of controllers
 * */
public class TvApplicationV1 {
    public static void main(String[] args)  {
        VolumeControllerV1 volumeControllerV1 = new VolumeControllerV1();
        BrightnessControllerV1 brightnessControllerV1 = new BrightnessControllerV1();
        ColourControllerV1 colourControllerV1 = new ColourControllerV1();


        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println("Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV1.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV1.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV1.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV1.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV1.adjust(5);
                    break;
                }
                case 6: {
                colourControllerV1.adjust(-5);
                break;
            }
            default:
                System.out.println("Shutting down...........");
                break OUTER;
        }

    }
    }
}

Ahora tiene nuestra primera versión de la aplicación de trabajo lista para ser implementada. Tiempo para analizar el trabajo realizado hasta ahora.

Problemas en la aplicación de TV versión 1

  1. El código de ajuste (valor int) está duplicado en las tres clases. Desea minimizar la duplicidad del código. (Pero no pensó en el código común y lo movió a una superclase para evitar el código duplicado)

Decide vivir con eso siempre que su aplicación funcione como se espera.

Luego, a veces, su jefe vuelve a usted y le pide que agregue la funcionalidad de reinicio a la aplicación existente. Restablecer configuraría los 3 tres controladores a sus respectivos valores predeterminados.

Comienza a escribir una nueva clase (ResetFunctionV2) para la nueva funcionalidad y asigna el código de asignación de entrada del usuario para esta nueva función.

Versión de aplicación 2

import java.util.Scanner;
class VolumeControllerV2    {

    private int defaultValue = 25;
    private int value;

    int getDefaultValue() {
        return defaultValue;
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class  BrightnessControllerV2   {

    private int defaultValue = 50;
    private int value;
    int get()    {
        return value;
    }
    int getDefaultValue() {
        return defaultValue;
    }
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class ColourControllerV2    {

    private int defaultValue = 40;
    private int value;
    int get()    {
        return value;
    }
    int getDefaultValue() {
        return defaultValue;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}

class ResetFunctionV2 {

    private VolumeControllerV2 volumeControllerV2 ;
    private BrightnessControllerV2 brightnessControllerV2;
    private ColourControllerV2 colourControllerV2;

    ResetFunctionV2(VolumeControllerV2 volumeControllerV2, BrightnessControllerV2 brightnessControllerV2, ColourControllerV2 colourControllerV2)  {
        this.volumeControllerV2 = volumeControllerV2;
        this.brightnessControllerV2 = brightnessControllerV2;
        this.colourControllerV2 = colourControllerV2;
    }
    void onReset()    {
        volumeControllerV2.set(volumeControllerV2.getDefaultValue());
        brightnessControllerV2.set(brightnessControllerV2.getDefaultValue());
        colourControllerV2.set(colourControllerV2.getDefaultValue());
    }
}
/*
 *       so on
 *       There can be n number of controllers
 *
 * */
public class TvApplicationV2 {
    public static void main(String[] args)  {
        VolumeControllerV2 volumeControllerV2 = new VolumeControllerV2();
        BrightnessControllerV2 brightnessControllerV2 = new BrightnessControllerV2();
        ColourControllerV2 colourControllerV2 = new ColourControllerV2();

        ResetFunctionV2 resetFunctionV2 = new ResetFunctionV2(volumeControllerV2, brightnessControllerV2, colourControllerV2);

        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV2.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV2.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV2.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV2.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV2.adjust(5);
                    break;
                }
                case 6: {
                    colourControllerV2.adjust(-5);
                    break;
                }
                case 7: {
                    resetFunctionV2.onReset();
                    break;
                }
                default:
                    System.out.println("Shutting down...........");
                    break OUTER;
            }

        }
    }
}

Entonces tiene su aplicación lista con la función Restablecer. Pero ahora empiezas a darte cuenta de que

Problemas en la aplicación de TV versión 2

  1. Si se introduce un nuevo controlador en el producto, debe cambiar el código de función Restablecer.
  2. Si el recuento del controlador es muy alto, tendría problemas para mantener las referencias de los controladores.
  3. El código de función de reinicio está estrechamente vinculado con el código de la clase de todos los controladores (para obtener y establecer valores predeterminados).
  4. La clase de entidad de reinicio (ResetFunctionV2) puede acceder a otro método de la clase de controlador (ajuste) que no es deseable.

Al mismo tiempo, escuchas de tu jefe que es posible que tengas que agregar una función en la que cada uno de los controladores, en el arranque, necesita verificar la última versión del controlador del repositorio de controladores alojado de la compañía a través de Internet.

Ahora comienza a pensar que esta nueva característica que se agregará se asemeja a la función Restablecer y los problemas de la aplicación (V2) se multiplicarán si no vuelve a factorizar su aplicación.

Comienza a pensar en usar la herencia para poder aprovechar la capacidad polimórfica de JAVA y agrega una nueva clase abstracta (ControllerV3) a

  1. Declare la firma del método get y set.
  2. Contiene la implementación del método de ajuste que anteriormente se replicaba entre todos los controladores.
  3. Declare el método setDefault para que la función de reinicio se pueda implementar fácilmente aprovechando el polimorfismo.

Con estas mejoras, tiene lista la versión 3 de su aplicación de TV.

Versión de aplicación 3

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

abstract class ControllerV3 {
    abstract void set(int value);
    abstract int get();
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
    abstract void setDefault();
}
class VolumeControllerV3 extends ControllerV3   {

    private int defaultValue = 25;
    private int value;

    public void setDefault() {
        set(defaultValue);
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
}
class  BrightnessControllerV3  extends ControllerV3   {

    private int defaultValue = 50;
    private int value;

    public void setDefault() {
        set(defaultValue);
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }
}
class ColourControllerV3 extends ControllerV3   {

    private int defaultValue = 40;
    private int value;

    public void setDefault() {
        set(defaultValue);
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
}

class ResetFunctionV3 {

    private List<ControllerV3> controllers = null;

    ResetFunctionV3(List<ControllerV3> controllers)  {
        this.controllers = controllers;
    }
    void onReset()    {
        for (ControllerV3 controllerV3 :this.controllers)  {
            controllerV3.setDefault();
        }
    }
}
/*
 *       so on
 *       There can be n number of controllers
 *
 * */
public class TvApplicationV3 {
    public static void main(String[] args)  {
        VolumeControllerV3 volumeControllerV3 = new VolumeControllerV3();
        BrightnessControllerV3 brightnessControllerV3 = new BrightnessControllerV3();
        ColourControllerV3 colourControllerV3 = new ColourControllerV3();

        List<ControllerV3> controllerV3s = new ArrayList<>();
        controllerV3s.add(volumeControllerV3);
        controllerV3s.add(brightnessControllerV3);
        controllerV3s.add(colourControllerV3);

        ResetFunctionV3 resetFunctionV3 = new ResetFunctionV3(controllerV3s);

        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV3.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV3.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV3.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV3.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV3.adjust(5);
                    break;
                }
                case 6: {
                    colourControllerV3.adjust(-5);
                    break;
                }
                case 7: {
                    resetFunctionV3.onReset();
                    break;
                }
                default:
                    System.out.println("Shutting down...........");
                    break OUTER;
            }

        }
    }
}

Aunque la mayoría de los problemas enumerados en la lista de problemas de V2 se abordaron, excepto

Problemas en la aplicación de TV versión 3

  1. La clase de entidad de reinicio (ResetFunctionV3) puede acceder a otro método de la clase de controlador (ajuste) que no es deseable.

Nuevamente, piensa en resolver este problema, ya que ahora también tiene que implementar otra característica (actualización del controlador al inicio). Si no lo arregla, también se replicará a nuevas características.

Entonces divide el contrato definido en la clase abstracta y escribe 2 interfaces para

  1. Restablecer función.
  2. Actualización del controlador.

Y haga que su primera clase concreta los implemente de la siguiente manera

Versión de aplicación 4

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

interface OnReset {
    void setDefault();
}
interface OnStart {
    void checkForDriverUpdate();
}
abstract class ControllerV4 implements OnReset,OnStart {
    abstract void set(int value);
    abstract int get();
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}

class VolumeControllerV4 extends ControllerV4 {

    private int defaultValue = 25;
    private int value;
    @Override
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
    @Override
    public void setDefault() {
        set(defaultValue);
    }

    @Override
    public void checkForDriverUpdate()    {
        System.out.println("Checking driver update for VolumeController .... Done");
    }
}
class  BrightnessControllerV4 extends ControllerV4 {

    private int defaultValue = 50;
    private int value;
    @Override
    int get()    {
        return value;
    }
    @Override
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }

    @Override
    public void setDefault() {
        set(defaultValue);
    }

    @Override
    public void checkForDriverUpdate()    {
        System.out.println("Checking driver update for BrightnessController .... Done");
    }
}
class ColourControllerV4 extends ControllerV4 {

    private int defaultValue = 40;
    private int value;
    @Override
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
    @Override
    public void setDefault() {
        set(defaultValue);
    }

    @Override
    public void checkForDriverUpdate()    {
        System.out.println("Checking driver update for ColourController .... Done");
    }
}
class ResetFunctionV4 {

    private List<OnReset> controllers = null;

    ResetFunctionV4(List<OnReset> controllers)  {
        this.controllers = controllers;
    }
    void onReset()    {
        for (OnReset onreset :this.controllers)  {
            onreset.setDefault();
        }
    }
}
class InitializeDeviceV4 {

    private List<OnStart> controllers = null;

    InitializeDeviceV4(List<OnStart> controllers)  {
        this.controllers = controllers;
    }
    void initialize()    {
        for (OnStart onStart :this.controllers)  {
            onStart.checkForDriverUpdate();
        }
    }
}
/*
*       so on
*       There can be n number of controllers
*
* */
public class TvApplicationV4 {
    public static void main(String[] args)  {
        VolumeControllerV4 volumeControllerV4 = new VolumeControllerV4();
        BrightnessControllerV4 brightnessControllerV4 = new BrightnessControllerV4();
        ColourControllerV4 colourControllerV4 = new ColourControllerV4();
        List<ControllerV4> controllerV4s = new ArrayList<>();
        controllerV4s.add(brightnessControllerV4);
        controllerV4s.add(volumeControllerV4);
        controllerV4s.add(colourControllerV4);

        List<OnStart> controllersToInitialize = new ArrayList<>();
        controllersToInitialize.addAll(controllerV4s);
        InitializeDeviceV4 initializeDeviceV4 = new InitializeDeviceV4(controllersToInitialize);
        initializeDeviceV4.initialize();

        List<OnReset> controllersToReset = new ArrayList<>();
        controllersToReset.addAll(controllerV4s);
        ResetFunctionV4 resetFunctionV4 = new ResetFunctionV4(controllersToReset);

        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV4.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV4.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV4.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV4.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV4.adjust(5);
                    break;
                }
                case 6: {
                    colourControllerV4.adjust(-5);
                    break;
                }
                case 7: {
                    resetFunctionV4.onReset();
                    break;
                }
                default:
                    System.out.println("Shutting down...........");
                    break OUTER;
            }

        }
    }
}

Ahora, todos los problemas que enfrentó se abordaron y se dio cuenta de que con el uso de Herencia y Polimorfismo podría

  1. Mantenga varias partes de la aplicación ligeramente acopladas. (Los componentes de la función Restablecer o Actualización del controlador no necesitan conocer las clases de controlador reales (Volumen, Brillo y Color), cualquier clase que implemente OnReset o OnStart será aceptable para la función Restablecer o Actualización del controlador componentes respectivamente).
  2. La mejora de la aplicación se vuelve más fácil. (La nueva adición del controlador no afectará el restablecimiento o el componente de la función de actualización del controlador, y ahora es realmente fácil agregar nuevos)
  3. Mantenga la capa de abstracción. (Ahora la función Restablecer solo puede ver el método setDefault de los controladores y la función Restablecer solo puede ver el método checkForDriverUpdate de los controladores)

Espero que esto ayude :-)


3

El término sobrecarga se refiere a tener múltiples versiones de algo con el mismo nombre, generalmente métodos con diferentes listas de parámetros

public int DoSomething(int objectId) { ... }
public int DoSomething(string objectName) { ... }

Por lo tanto, estas funciones pueden hacer lo mismo, pero tiene la opción de llamarlo con una ID o un nombre. No tiene nada que ver con herencia, clases abstractas, etc.

La anulación generalmente se refiere al polimorfismo, como describiste en tu pregunta


2

sobrecarga es cuando define 2 métodos con el mismo nombre pero diferentes parámetros

la anulación es donde cambia el comportamiento de la clase base a través de una función con el mismo nombre en una subclase.

Entonces, el polimorfismo está relacionado con la anulación, pero no con la sobrecarga.

Sin embargo, si alguien me dio una respuesta simple de "anulación" para la pregunta "¿Qué es el polimorfismo?" Yo pediría más explicaciones.


2

anular es más como ocultar un método heredado al declarar un método con el mismo nombre y firma que el método de nivel superior (súper método), esto agrega un comportamiento polimórfico a la clase. en otras palabras, la decisión de elegir qué método de nivel se llamará se tomará en tiempo de ejecución, no en tiempo de compilación. Esto lleva al concepto de interfaz e implementación.


2

¿Qué es el polimorfismo?

Del tutorial de java

La definición del diccionario de polimorfismo se refiere a un principio en biología en el que un organismo o especie puede tener muchas formas o etapas diferentes. Este principio también se puede aplicar a la programación orientada a objetos y lenguajes como el lenguaje Java. Las subclases de una clase pueden definir sus propios comportamientos únicos y, sin embargo, compartir algunas de las mismas funciones de la clase principal.

Al considerar los ejemplos y la definición, anular debe aceptar la respuesta.

Con respecto a su segunda consulta:

SI tuvo una clase base abstracta que definió un método sin implementación, y definió ese método en la subclase, ¿eso todavía se anula?

Debería llamarse anulación.

Eche un vistazo a este ejemplo para comprender los diferentes tipos de anulación.

  1. La clase base no proporciona implementación y la subclase tiene que anular el método completo - (resumen)
  2. La clase base proporciona una implementación predeterminada y la subclase puede cambiar el comportamiento
  3. La subclase agrega extensión a la implementación de la clase base llamando super.methodName() primera instrucción
  4. La clase base define la estructura del algoritmo (método de plantilla) y la subclase anulará una parte del algoritmo

fragmento de código:

import java.util.HashMap;

abstract class Game implements Runnable{

    protected boolean runGame = true;
    protected Player player1 = null;
    protected Player player2 = null;
    protected Player currentPlayer = null;

    public Game(){
        player1 = new Player("Player 1");
        player2 = new Player("Player 2");
        currentPlayer = player1;
        initializeGame();
    }

    /* Type 1: Let subclass define own implementation. Base class defines abstract method to force
        sub-classes to define implementation    
    */

    protected abstract void initializeGame();

    /* Type 2: Sub-class can change the behaviour. If not, base class behaviour is applicable */
    protected void logTimeBetweenMoves(Player player){
        System.out.println("Base class: Move Duration: player.PlayerActTime - player.MoveShownTime");
    }

    /* Type 3: Base class provides implementation. Sub-class can enhance base class implementation by calling
        super.methodName() in first line of the child class method and specific implementation later */
    protected void logGameStatistics(){
        System.out.println("Base class: logGameStatistics:");
    }
    /* Type 4: Template method: Structure of base class can't be changed but sub-class can some part of behaviour */
    protected void runGame() throws Exception{
        System.out.println("Base class: Defining the flow for Game:");  
        while ( runGame) {
            /*
            1. Set current player
            2. Get Player Move
            */
            validatePlayerMove(currentPlayer);  
            logTimeBetweenMoves(currentPlayer);
            Thread.sleep(500);
            setNextPlayer();
        }
        logGameStatistics();
    }
    /* sub-part of the template method, which define child class behaviour */
    protected abstract void validatePlayerMove(Player p);

    protected void setRunGame(boolean status){
        this.runGame = status;
    }
    public void setCurrentPlayer(Player p){
        this.currentPlayer = p;
    }
    public void setNextPlayer(){
        if ( currentPlayer == player1) {
            currentPlayer = player2;
        }else{
            currentPlayer = player1;
        }
    }
    public void run(){
        try{
            runGame();
        }catch(Exception err){
            err.printStackTrace();
        }
    }
}

class Player{
    String name;
    Player(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

/* Concrete Game implementation  */
class Chess extends Game{
    public Chess(){
        super();
    }
    public void initializeGame(){
        System.out.println("Child class: Initialized Chess game");
    }
    protected void validatePlayerMove(Player p){
        System.out.println("Child class: Validate Chess move:"+p.getName());
    }
    protected void logGameStatistics(){
        super.logGameStatistics();
        System.out.println("Child class: Add Chess specific logGameStatistics:");
    }
}
class TicTacToe extends Game{
    public TicTacToe(){
        super();
    }
    public void initializeGame(){
        System.out.println("Child class: Initialized TicTacToe game");
    }
    protected void validatePlayerMove(Player p){
        System.out.println("Child class: Validate TicTacToe move:"+p.getName());
    }
}

public class Polymorphism{
    public static void main(String args[]){
        try{

            Game game = new Chess();
            Thread t1 = new Thread(game);
            t1.start();
            Thread.sleep(1000);
            game.setRunGame(false);
            Thread.sleep(1000);

            game = new TicTacToe();
            Thread t2 = new Thread(game);
            t2.start();
            Thread.sleep(1000);
            game.setRunGame(false);

        }catch(Exception err){
            err.printStackTrace();
        }       
    }
}

salida:

Child class: Initialized Chess game
Base class: Defining the flow for Game:
Child class: Validate Chess move:Player 1
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Child class: Validate Chess move:Player 2
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Base class: logGameStatistics:
Child class: Add Chess specific logGameStatistics:
Child class: Initialized TicTacToe game
Base class: Defining the flow for Game:
Child class: Validate TicTacToe move:Player 1
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Child class: Validate TicTacToe move:Player 2
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Base class: logGameStatistics:

2

Creo que ustedes están mezclando conceptos. El polimorfismo es la capacidad de un objeto de comportarse de manera diferente en el tiempo de ejecución. Para lograr esto, necesita dos requisitos:

  1. Enlace tardío
  2. Herencia.

Dicho esto, la sobrecarga significa algo diferente a la anulación dependiendo del idioma que esté utilizando. Por ejemplo, en Java no existe la anulación sino la sobrecarga . Los métodos sobrecargados con firma diferente a su clase base están disponibles en la subclase. De lo contrario, serían anulados (por favor, vea que quiero decir ahora el hecho de que no hay manera de llamar a su método de la clase base desde fuera del objeto).

Sin embargo, en C ++ eso no es así. Cualquier método sobrecargado , independientemente de si la firma es la misma o no (cantidad diferente, tipo diferente) también se anula . Es decir, el método de la clase base ya no está disponible en la subclase cuando se llama desde fuera del objeto de la subclase, obviamente.

Entonces la respuesta es cuando se habla de sobrecarga de uso de Java . En cualquier otro idioma puede ser diferente como sucede en c ++


1

El polimorfismo es más probable en lo que se refiere a su significado ... anular en Java

Se trata de diferentes comportamientos del mismo objeto en diferentes situaciones (en forma de programación ... puede llamar a diferentes ARGUMENTOS)

Creo que el siguiente ejemplo lo ayudará a comprender ... Aunque no es un código Java PURO ...

     public void See(Friend)
     {
        System.out.println("Talk");
     }

Pero si cambiamos el ARGUMENTO ... el COMPORTAMIENTO cambiará ...

     public void See(Enemy)
     {
        System.out.println("Run");
     }

La Persona (aquí el "Objeto") es la misma ...


1

El polimorfismo es una implementación múltiple de un objeto o podría decirse múltiples formas de un objeto. Digamos que tiene clase Animalscomo la clase base abstracta y tiene un método llamado movement()que define la forma en que se mueve el animal. Ahora, en realidad, tenemos diferentes tipos de animales y también se mueven de manera diferente, algunos de ellos con 2 patas, otros con 4 y algunos sin patas, etc. Para definir diferentes movement()animales en la tierra, necesitamos aplicar el polimorfismo. Sin embargo, debe definir más clases, es decir, clase, Dogs Cats Fishetc. Luego, debe extender esas clases desde la clase base Animalsy anular su método movement()con una nueva funcionalidad de movimiento basada en cada animal que tenga. También puedes usarInterfacespara lograr eso. La palabra clave aquí es primordial, la sobrecarga es diferente y no se considera polimorfismo. con sobrecarga puede definir múltiples métodos "con el mismo nombre" pero con diferentes parámetros en el mismo objeto o clase.


0

El polimorfismo se relaciona con la capacidad de un lenguaje de tener diferentes objetos tratados de manera uniforme mediante el uso de una sola interfaz; como tal, está relacionado con la anulación, por lo que la interfaz (o la clase base) es polimórfica, el implementador es el objeto que anula (dos caras de la misma medalla)

de todos modos, la diferencia entre los dos términos se explica mejor usando otros lenguajes, como c ++: un objeto polimórfico en c ++ se comporta como la contraparte de Java si la función base es virtual, pero si el método no es virtual, el salto de código se resuelve estáticamente , y el tipo verdadero no se verifica en tiempo de ejecución, por lo que el polimorfismo incluye la capacidad de un objeto de comportarse de manera diferente dependiendo de la interfaz utilizada para acceder a él; déjame hacer un ejemplo en pseudocódigo:

class animal {
    public void makeRumor(){
        print("thump");
    }
}
class dog extends animal {
    public void makeRumor(){
        print("woff");
    }
}

animal a = new dog();
dog b = new dog();

a.makeRumor() -> prints thump
b.makeRumor() -> prints woff

(suponiendo que makeRumor NO es virtual)

Java realmente no ofrece este nivel de polimorfismo (llamado también corte de objetos).

animal a = perro nuevo (); perro b = perro nuevo ();

a.makeRumor() -> prints thump
b.makeRumor() -> prints woff

en ambos casos solo imprimirá woff .. ya que ayb se refiere al perro de clase



animal a = perro nuevo (); a fue construido como un perro e imprimirá "woff". Si quieres que imprima el golpe, entonces debes subirlo. ((Animal) a) .makeRumor ()
Chris Cudmore

Eso es referencia de conversión, pero el objeto sigue siendo un perro. Si quieres que sea un animal, debes subir explícitamente el objeto.
Chris Cudmore

Lo averigué. La pregunta fue etiquetada Java. Respondiste C ++. Puede ser correcto en C ++. Definitivamente estoy en lo correcto en Java.
Chris Cudmore

debería suceder cada vez que se involucra un constructor de copias aquí hay una referencia fredosaurus.com/notes-cpp/oop-condestructors/… caso tres coincidencias; ignore el nuevo operador que solo existe para desambiguar la creación.
Lorenzo Boccaccia

0
import java.io.IOException;

class Super {

    protected Super getClassName(Super s) throws IOException {
        System.out.println(this.getClass().getSimpleName() + " - I'm parent");
        return null;
    }

}

class SubOne extends Super {

    @Override
    protected Super getClassName(Super s)  {
        System.out.println(this.getClass().getSimpleName() + " - I'm Perfect Overriding");
        return null;
    }

}

class SubTwo extends Super {

    @Override
    protected Super getClassName(Super s) throws NullPointerException {
        System.out.println(this.getClass().getSimpleName() + " - I'm Overriding and Throwing Runtime Exception");
        return null;
    }

}

class SubThree extends Super {

    @Override
    protected SubThree getClassName(Super s) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and Returning SubClass Type");
        return null;
    }

}

class SubFour extends Super {

    @Override
    protected Super getClassName(Super s) throws IOException {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and Throwing Narrower Exception ");
        return null;
    }

}

class SubFive extends Super {

    @Override
    public Super getClassName(Super s) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and have broader Access ");
        return null;
    }

}

class SubSix extends Super {

    public Super getClassName(Super s, String ol) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Perfect Overloading ");
        return null;
    }

}

class SubSeven extends Super {

    public Super getClassName(SubSeven s) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Perfect Overloading because Method signature (Argument) changed.");
        return null;
    }

}

public class Test{

    public static void main(String[] args) throws Exception {

        System.out.println("Overriding\n");

        Super s1 = new SubOne(); s1.getClassName(null);

        Super s2 = new SubTwo(); s2.getClassName(null);

        Super s3 = new SubThree(); s3.getClassName(null);

        Super s4 = new SubFour(); s4.getClassName(null);

        Super s5 = new SubFive(); s5.getClassName(null);

        System.out.println("Overloading\n");

        SubSix s6 = new SubSix(); s6.getClassName(null, null);

        s6 = new SubSix(); s6.getClassName(null);

        SubSeven s7 = new SubSeven(); s7.getClassName(s7);

        s7 = new SubSeven(); s7.getClassName(new Super());

    }
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.