java - sintaxis - Polimorfismo vs Anulación vs Sobrecarga
polimorfismo java sintaxis (22)
En términos de Java, cuando alguien pregunta:
¿Qué es el polimorfismo?
¿Sería una respuesta aceptable la sobrecarga o la anulación ?
Creo que hay un poco más que eso.
SI tenía una clase base abstracta que definía un método sin implementación, y definió ese método en la subclase, ¿eso todavía está anulado?
Creo que la sobrecarga no es la respuesta correcta con seguridad.
¿Qué es el polimorfismo?
De java tutorial
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 puede aplicarse 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, se debe aceptar la anulación de la respuesta.
Respecto a tu segunda consulta:
SI tenía una clase base abstracta que definía un método sin implementación, y definió ese método en la subclase, ¿eso todavía está anulado?
Debería llamarse anulación.
Eche un vistazo a este ejemplo para comprender los diferentes tipos de anulación.
- La clase base no proporciona implementación y la subclase tiene que anular el método completo - (resumen)
- La clase base proporciona implementación predeterminada y la subclase puede cambiar el comportamiento
- La
super.methodName()
agrega extensión a la implementación de la clase base al llamar asuper.methodName()
como primera declaración - 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:
Anulación cuando heredamos la clase base y creamos una clase derivada, si en la clase derivada hay un método que tiene el mismo nombre que el método (mismo nombre, mismo argumento, mismo tipo de retorno) definido en la clase base, se llama Overriding.
class Vehicle{
void run()
{
System.out.println("Vehicle is running");
}
}
class Bike2 extends Vehicle{
void run()
{
System.out.println("Bike is running safely");
}
public static void main(String args[]){
Bike2 obj = new Bike2();
obj.run();
}
Salida: la bicicleta se está ejecutando de manera segura ........ Para comprender la anulación con mayor claridad, visite: http://javabyroopam.blogspot.in/
Sobrecarga Simplemente dos métodos que tienen el mismo nombre pero tienen una lista de argumentos diferente se llama sobrecarga.
class Calculation{
void sum(int a,int b){System.out.println(a+b);}
void sum(int a,int b,int c){System.out.println(a+b+c);}
public static void main(String args[]){
Calculation obj=new Calculation();
obj.sum(10,10,10);
obj.sum(20,20);
}
}
salida 30,20
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 Principal no conoce el tipo del animal y depende del comportamiento de una implementación particular del método MakeNoise ().
Edición: Parece que Brian me dio una paliza. Divertido usamos el mismo ejemplo. Pero el código anterior debería ayudar a aclarar los conceptos.
Aunque, el polimorfismo ya se explica con gran detalle en este post, 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.
Suponiendo que usted es un ingeniero de software en una empresa de televisión y se le pide que escriba software para los controladores de Volumen, Brillo y Color para aumentar y disminuir sus valores en el comando del usuario.
Se comienza con clases de escritura para cada una de estas características agregando
- configurar: - Para establecer un valor de un controlador. (Suponiendo que esto tenga un código específico del controlador)
- obtener: - Para obtener un valor de un controlador. (Suponiendo que esto tiene un código específico del controlador)
- ajustar: - Para validar la entrada y configurar un controlador. (Validaciones genéricas ... independientes de los controladores)
- Asignación de entrada de usuario con controladores: - Para obtener la entrada del usuario y la invocación de los controladores en consecuencia.
Versión de la 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 aplicación de trabajo lista para ser implementada. Tiempo para analizar el trabajo realizado hasta el momento.
Problemas en la versión de la aplicación de TV 1
- El código de ajuste (valor int) está duplicado en las tres clases. Le gustaría minimizar la duplicidad del código. (Pero no pensaste en el código común y lo moviste a una súper clase para evitar el código duplicado)
Decides vivir con eso mientras tu aplicación funcione como se espera.
Después de algunas veces, su jefe vuelve a usted y le pide que agregue la funcionalidad de restablecimiento a la aplicación existente. El reinicio establecería los tres 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 de usuario para esta nueva característica.
Versión de la 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;
}
}
}
}
Así que tienes tu aplicación lista con la función de reinicio. Pero, ahora empiezas a darte cuenta de que
Problemas en la aplicación de TV versión 2
- Si se introduce un nuevo controlador en el producto, debe cambiar el código de función Restablecer.
- Si el recuento del controlador aumenta mucho, tendría problemas para mantener las referencias de los controladores.
- El código de función de restablecimiento está estrechamente acoplado con el código de todos los controladores (para obtener y establecer valores predeterminados).
- La clase de función de restablecimiento (ResetFunctionV2) puede acceder a otro método de la clase Controlador (ajuste) que no es deseable.
Al mismo tiempo, le informamos a Boss que podría tener que agregar una función en la que cada controlador, en el inicio, necesita verificar la última versión del controlador desde el repositorio de controladores de la compañía a través de Internet.
Ahora empieza a pensar que esta nueva función que se agregará se parece a la función Restablecer y los problemas de aplicación (V2) se multiplicarán si no vuelve a factorizar su aplicación.
Empieza a pensar en usar la herencia para poder aprovechar la capacidad polimórfica de JAVA y agregar una nueva clase abstracta (ControllerV3) a
- Declara la firma del método get y set.
- Contiene la implementación del método de ajuste que se replicó anteriormente entre todos los controladores.
- Declare el método setDefault para que la función de restablecimiento se pueda implementar fácilmente aprovechando el polimorfismo.
Con estas mejoras, tiene la versión 3 de su aplicación de TV preparada con usted.
Versión de la 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 trataron, excepto
Problemas en la aplicación de TV versión 3
- La clase de función de restablecimiento (ResetFunctionV3) puede acceder a otro método de la clase Controlador (ajuste) que no es deseable.
Nuevamente, piensa en resolver este problema, ya que ahora también tiene otra característica (actualización del controlador en el inicio) para implementar. Si no lo arreglas, también se replicará en las nuevas funciones.
Entonces, divide el contrato definido en la clase abstracta y escribe 2 interfaces para
- Restablecer la función.
- Actualización del controlador.
Y haz que tu primera clase concreta los implemente como se muestra a continuación
Versión de la 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 se solucionó todo el problema al que te enfrentaste y te diste cuenta de que con el uso de Herencia y Polimorfismo podrías
- Mantenga varias partes de la aplicación acopladas de manera flexible. (Los componentes de la función Reinicio 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 Reinicio o Actualización del controlador componentes respectivamente).
- La mejora de la aplicación se hace 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 muy fácil agregar nuevos)
- Mantenga la capa de abstracción. (Ahora la función Restablecer puede ver solo 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 :-)
Creo que ustedes están mezclando conceptos. El polimorfismo es la capacidad de un objeto para comportarse de manera diferente en el tiempo de ejecución. Para lograr esto, necesitas dos requisitos:
- Vinculación tardía
- Herencia.
Habiendo dicho que la sobrecarga significa algo diferente a la cancelación dependiendo del idioma que esté utilizando. Por ejemplo, en Java no existe la invalidación sino la sobrecarga . Los métodos sobrecargados con diferente firma a su clase base están disponibles en la subclase. De lo contrario, se anularían (por favor, ver que me refiero ahora al hecho de que no hay manera de llamar a su método de 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 invalida . 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.
Así que la respuesta es cuando se habla de la sobrecarga de uso de Java. En cualquier otro idioma puede ser diferente como sucede en c ++
El ejemplo clásico, los perros y los gatos son animales, los animales tienen el método makeNoise. Puedo recorrer una serie de animales que llaman makeNoise en ellos y esperar que hagan la implementación correspondiente.
El código de llamada no tiene que saber qué animal específico son.
Eso es lo que yo considero como polimorfismo.
El polimorfismo es la capacidad para que un objeto aparezca en múltiples formas. Esto implica el uso de funciones virtuales y de herencia para construir una familia de objetos que se pueden intercambiar. La clase base contiene los prototipos de las funciones virtuales, posiblemente no implementadas o con implementaciones predeterminadas según lo dicta la aplicación, y las diferentes clases derivadas las implementan de manera diferente para afectar diferentes comportamientos.
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 súper clase para describir todas las cosas que pueden volar? Debería pensar que no. Sería mejor servirlo para 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 de métodos como una forma menor de polimorfismo.
El término sobrecarga se refiere a tener varias 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 usted 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 lo describió en su pregunta
Específicamente decir que la sobrecarga o la 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 para diferentes tipos de parámetros. Un buen ejemplo es la sobrecarga del operador. Puede definir "+" para aceptar diferentes tipos de parámetros (por ejemplo, cadenas o int) y, en función de esos tipos, "+" se comportará de manera diferente.
El polimorfismo también incluye la herencia y los métodos de anulación, aunque pueden ser abstractos o virtuales en el tipo base. En términos de polimorfismo basado en la herencia, Java solo admite la herencia de una sola clase, lo que limita su comportamiento polimórfico al de una sola cadena de tipos básicos. Java admite la implementación de múltiples interfaces, que es otra forma de comportamiento polimórfico.
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 método goPee()
no es definible para humanos. Solo es definible para las subclases Hombre y Mujer. Además, Humano es un concepto abstracto: no puedes crear un humano que no sea Hombre ni Mujer. Tiene que ser uno o el otro.
Entonces diferimos 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 sala llena de humanos que vayan a orinar.
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 daría lugar a:
Stand Up
Sit Down
...
Ninguno:
La sobrecarga es cuando tienes el mismo nombre de función que toma diferentes parámetros.
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, los métodos de la clase base (padre) se llaman, pero no hasta que el tiempo de ejecución sepa la aplicación cuál es el objeto real; puede ser una clase secundaria cuyos métodos son diferentes. Esto se debe a que se puede usar cualquier clase secundaria donde se define una clase base.
En Java ves mucho el polimorfismo con la biblioteca de colecciones:
int countStuff(List stuff) {
return stuff.size();
}
Lista es la clase base, el compilador no tiene ni idea de si está contando una lista vinculada, vector, 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 elegirá la versión correcta de countStuff () para que coincida con los parámetros.
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
- Método de anulación
- 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 que pasan 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 padre se usa en la clase hija
En Java para lograr polimorfismo, una variable de referencia de superclase puede contener el objeto de subclase.
Para lograr el polimorfismo, todos los desarrolladores deben usar los mismos nombres de métodos en el proyecto.
Tanto la anulación como la sobrecarga se utilizan para lograr el polimorfismo.
Podría tener un método en una clase que se invalida en una o más subclases. El método hace diferentes cosas dependiendo de qué clase se utilizó 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 diferentes cosas 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);
}
}
Tienes razón en que la sobrecarga no es la respuesta.
Ninguna de las dos es primordial. Anular 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 el llamador de un objeto que exhibe polimorfismo no es consciente de qué tipo específico es el objeto.
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 (método super), esto agrega un comportamiento polimórfico a la clase. en otras palabras, la decisión de elegir el método de nivel a llamar se tomará en tiempo de ejecución y no en tiempo de compilación. Esto lleva al concepto de interfaz e implementación.
la sobrecarga es cuando se definen 2 métodos con el mismo nombre pero diferentes parámetros
la anulación es cuando cambia el comportamiento de la clase base a través de una función con el mismo nombre en una subclase.
Por lo tanto, el polimorfismo está relacionado con la anulación, pero no la sobrecarga.
Sin embargo, si alguien me dio una respuesta simple de "anulación" para la pregunta "¿Qué es el polimorfismo?" Pediría una explicación más detallada.
El 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.
Una anulación es un tipo de función que se produce 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. Refiriéndose al ejemplo anterior, puede definir su propia clase y anular la función toString (). Debido a que esta función se hereda de Objeto, aún estará disponible si copia una instancia de esta clase en una variable de tipo Objeto. Normalmente, si llama a toString () en su clase mientras pretende ser un Objeto, la versión de toString que realmente se activará es la definida en el propio Objeto. Sin embargo, debido a que la función es una anulación, la definición de toString () de su clase se usa incluso cuando el tipo verdadero de la instancia de la clase está oculto detrás del polimorfismo.
La sobrecarga es la acción de definir múltiples métodos con el mismo nombre, pero con diferentes parámetros. No tiene relación con la anulación o el polimorfismo.
El polimorfismo es más probable en lo que se refiere a su significado ... a la anulación en Java
Se trata del comportamiento diferente del MISMO objeto en diferentes situaciones (de manera programada ... puedes llamar a diferentes ARGUMENTOS)
Creo que el siguiente ejemplo te ayudará a entender ... Aunque no es un código Java PURE ...
public void See(Friend)
{
System.out.println("Talk");
}
Pero si cambiamos el ARGUMENTO ... el COMPORTAMIENTO será cambiado ...
public void See(Enemy)
{
System.out.println("Run");
}
La Persona (aquí el "Objeto") es la misma ...
El polimorfismo es una implementación múltiple de un objeto o se podrían decir múltiples formas de un objeto. digamos que tienes clase Animals
como 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 se mueven de manera diferente, algunos de ellos con 2 patas, otros con 4 y otros sin patas, etc. Para definir los diferentes movement()
animales de la tierra, debemos aplicar polimorfismo. Sin embargo, debe definir más clases, es decir, clases, Dogs
Cats
Fish
etc. Luego, debe ampliar esas clases de la clase base Animals
y anular su método movement()
con una nueva funcionalidad de movimiento basada en cada animal que tenga. También puedes usarInterfaces
para lograr eso. La palabra clave aquí es anular, la sobrecarga es diferente y no se considera como polimorfismo. con la sobrecarga puede definir múltiples métodos "con el mismo nombre" pero con diferentes parámetros en el mismo objeto o clase.
El polimorfismo se relaciona con la capacidad de un lenguaje para tratar diferentes objetos de manera uniforme mediante el uso de una sola interfaz; como tal, está relacionado con la anulación, así 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 utilizando 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 de forma estática . y el tipo verdadero no se verifica en el tiempo de ejecución, por lo que el polimorfismo incluye la capacidad de un objeto para 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 sea virtual)
java no ofrece realmente este nivel de polimorfismo (también denominado 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 a la clase perro
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());
}
}