una sirve resueltos que para metodos metodo interfaces implementacion ejercicios ejemplo definicion crear clases clase abstractos abstracto abstractas abstracta java inheritance override abstract-class abstract-methods

sirve - metodos abstractos java



¿Hay alguna manera de hacer un método que no sea abstracto sino que debe ser anulado? (12)

¿Hay alguna forma de obligar a las clases de niños a anular un método de superclase no abstracto?

Necesito poder crear instancias de clase padre, pero si una clase amplía esta clase, debe dar su propia definición de algunos métodos.


¡Hay una razón por la que no es posible!

La clase derivada podría simplemente llamar a la implementación de la clase base al anular el método.

Entonces, ¿qué sentido tiene obligar a la clase a anular su método? No creo que haya ningún beneficio.


¿Qué tal esto?: Dentro de la implementación predeterminada del método, utilice la reflexión para obtener la clase exacta del objeto. Si la clase no coincide exactamente con tu clase base, lanza una RuntimeException o equivalente.

public class Parent { public void defaultImpl(){ if(this.getClass() != Parent.class){ throw new RuntimeException(); } } }


Como han señalado otros, no puedes hacer esto directamente.

Pero una forma de hacerlo es usar el patrón de Estrategia , de esta manera:

public class Base { private final Strategy impl; // Public factory method uses DefaultStrategy // You could also use a public constructor here, but then subclasses would // be able to use that public constructor instead of the protected one public static Base newInstance() { return new Base(new DefaultStrategy()); } // Subclasses must provide a Strategy implementation protected Base(Strategy impl) { this.impl = impl; } // Method is final: subclasses can "override" by providing a different // implementation of the Strategy interface public final void foo() { impl.foo(); } // A subclass must provide an object that implements this interface public interface Strategy { void foo(); } // This implementation is private, so subclasses cannot access it // It could also be made protected if you prefer private static DefaultStrategy implements Strategy { @Override public void foo() { // Default foo() implementation goes here } } }


Considera hacer una interfaz con este método. Los descendientes de la clase tendrán que implementarlo.


Creo que la manera más fácil es crear una clase abstracta que herede de la clase base:

public class Base { public void foo() { // original method } } abstract class BaseToInheritFrom extends Base { @Override public abstract void foo(); } class RealBaseImpl extends BaseToInheritFrom { @Override public void foo() { // real impl } }


La respuesta sería un no. Puede rediseñar usando el patrón de diseño de plantilla. Puede ser de ayuda.

Alternativamente, puede hacer que sus clases secundarias implementen una interfaz. La interfaz puede o no ser implementada por la súper clase.


No hay una forma directa de hacer cumplir esto, hasta donde yo sé.

Podría evitarlo haciendo que la clase padre no sea ​​instanciable, sino que proporcione un método de fábrica que cree una instancia de alguna subclase (posible privada) que tenga la implementación predeterminada:

public abstract class Base { public static Base create() { return new DefaultBase(); } public abstract void frobnicate(); static class DefaultBase extends Base { public void frobnicate() { // default frobnication implementation } } }

Ahora no puede escribir new Base() nuevo, pero puede hacer Base.create() para obtener la implementación predeterminada.


No, ese es el objetivo de un método abstracto. ¿Cuál es tu caso de uso? Tal vez podamos pensar sobre eso en base a la necesidad subyacente.


Reflejaré las otras respuestas y diré que no existe una forma forzada por el compilador de forzar a las clases derivadas a que anulen un método no abstracto. El objetivo de hacer un método abstracto es definir que debe existir un método con esta firma, pero no se puede especificar en el nivel base y, por lo tanto, debe especificarse en un nivel derivado. Si hay una implementación operativa, no trivial (ya que no está vacía y no arroja una excepción o muestra un mensaje) de un método en el nivel base, entonces esto no es estrictamente necesario para una llamada a el método de un consumidor de la clase derivada para tener éxito. Por lo tanto, el compilador no tiene que forzar la anulación de un método que puede ejecutarse con bastante éxito en los niveles base o derivados.

En situaciones donde desearía que una clase derivada anulara su implementación en funcionamiento, debería ser bastante obvio que la implementación base no hace lo que los consumidores de la clase derivada querrán; la clase base no tiene suficiente implementación, o la incorrecta. En esos casos, debe confiar en que un programador derivado de su clase sabrá lo que está haciendo y, por lo tanto, sabrá que el método debe ser anulado porque no produce la respuesta correcta en el contexto del uso de su nuevo objeto.

Puedo pensar en una cosa que podrías hacer. Requeriría una base abstracta, con una implementación "predeterminada" sellada (final para Javaheads). De esta forma, hay una implementación básica del método que está disponible para usar como si fuera una clase "base", pero para definir una clase diferente para un nuevo escenario, debe volver a la clase abstracta, y se ven obligados a volver a implementar el método. Este método podría ser lo único abstracto en la clase, por lo que aún le permite hacer uso de implementaciones básicas de otros métodos:

public abstract class BaseClass { public abstract void MethodYouMustAlwaysOverride(); public virtual void MethodWithBasicImplementation() { ... } } public final class DefaultClass:BaseClass { public override void MethodYouMustAlwaysOverride() { ... } //the base implementation of MethodWithBasicImplementation //doesn''t have to be overridden } ... public class DerivedClass:BaseClass { //Because DefaultClass is final, we must go back to BaseClass, //which means we must reimplement the abstract method public override void MethodYouMustAlwaysOverride() { ... } //again, we can still use MethodWithBasicImplementation, //or we can extend/override it public override void MethodWithBasicImplementation() { ... } }

Sin embargo, esto tiene dos inconvenientes. Primero, como no tiene acceso a la implementación de DefaultClass a través de la herencia, no puede extender la implementación de DefaultClass, lo que significa que para hacer lo que DefaultClass hace, más un poco más, debe volver a escribir el código de DefaultClass, violando DRY. En segundo lugar, esto solo funciona para un nivel de herencia, porque no puede forzar la anulación si permite la herencia de DerivedClass.


Siempre puede hacer que la clase base tenga un método que arroje una excepción.

Técnicamente, la clase base ha definido el método, pero no es utilizable sin anular el método. En tal caso, prefiero una excepción de tiempo de ejecución ya que no requieren una declaración explícita de versiones. Un ejemplo sigue

public class Parent { public void doStuff() { throw new RuntimeException("doStuff() must be overridden"); } } public class Child extends Parent { @Override public void doStuff() { ... all is well here ... } }

La desventaja es que esto no impide la creación de objetos Base ; sin embargo, cualquiera que intente utilizar uno de los métodos "debe ser reemplazado" pronto encontrará que debe haber anulado la clase.

Si bien esta solución cumple con la descripción de la solicitud, su aplicación probablemente se beneficie al no requerir una solución como esta. Es mucho mejor evitar bloqueos en tiempo de ejecución con comprobaciones de compilación, que es lo que proporciona la palabra clave abstracta.


tal vez esto ayude:

class SuperClass { void doStuff(){ if(!this.getClass().equals(SuperClass.class)){ throw new RuntimeException("Child class must implement doStuff Method"); }else{ //ok //default implementation } } } class Child extends SuperClass{ @Override void doStuff() { //ok } } class Child2 extends SuperClass{ } new SuperClass().doStuff(); //ok new Child().doStuff(); //ok new Child2().doStuff(); //error


vale, vamos a aprenderlo de esta manera. Me atengo a las pautas de estilo de Java y uso la sintaxis de Java. Por lo tanto, se supone que las plantillas de herencia múltiple y C ++ no están disponibles.

hacer que el método de clase padre sea abstracto no es obligatorio, en OOP se usa el concepto de polimorfismo. puedes usar el mismo método de dos o más maneras diferentes. Esto se llama anulación de método.

Tomemos un ejemplo.

public class Animal{ public void makeSound(){ System.out.println("Animal doesn''t know how to make sound"); } } public class PussyCat extends Animal{ public void makeSound(){ System.out.println("meowwww !!!"); } public static void main(String args[]){ PussyCat aCat=new PussyCat(); aCat.makeSound(); } }

esto imprimirá "meowww !!!" en la pantalla.

pero esto no implica que el método makeSound deba anularse en la clase secundaria.

Si necesita obligar a la clase secundaria a anular los métodos, mejor implemente una interfaz por clase.

public Interface audible{ public void makeSound(); } public class pussyCat implements audible{ // now you must implement the body of makeSound method here public void makeSound(){ System.out.println("meowwww !!!"); } public static void main(String args[]){ PussyCat aCat=new PussyCat(); aCat.makeSound(); } }

esto también imprimirá "meowwww !!!" en la pantalla