2011-01-28 9 views
5
class DonkeyBattler { 

    static void doBattle(){ 
     System.out.println("Weaponized donkey battling"); 
    } 

} 

class FunkyBattler extends DonkeyBattler { 

    static void doBattle(){ 
     System.out.println("Weaponized donkey battling with bellbottoms"); 

    } 
} 

método doBattle se supone que es una redefinición o una anulación? Oh, esto es Java por cierto.¿Cuál es la diferencia entre redefinir un método y anular un método?

+0

Redefinición. La anulación solo funciona con métodos de instancia heredados. – helpermethod

+1

¿Qué es "redefinición"? Defínelo o proporcione un enlace para ponernos en la misma página. –

Respuesta

5

El término "redefinición" no se utiliza por lo general en lo que respecta a los métodos de Java y la herencia. Hay dos términos que se usan comúnmente: "anular" como dijiste, y "sobrecargar". Sobrecargar en Java es crear dos métodos en la misma clase con el mismo nombre pero diferentes firmas (número y/o tipos de argumentos). Por ejemplo:

public interface MyInterface 
{ 
    public int doStuff(int first, int second); 
    public int doStuff(double only); 
} 

Para anular es hacer algo parecido a lo que está haciendo en su ejemplo: crear una clase de niño con un método que tiene el mismo nombre y firma como un método de la clase padre que será ser utilizado para todas las instancias de la clase hija pero no de la clase principal o cualquier otra clase hija de ese padre.

El único problema con su ejemplo lo que se refiere a la sobrecarga es el uso de la palabra clave static. La anulación se determina dinámicamente, pero los métodos estáticos por definición no lo son.

+2

¿Tener dos métodos estáticos con el mismo nombre es como si tuviera dos métodos completamente diferentes? – overmann

+1

Si están en clases diferentes, sí, porque tienen * espacios de nombres * totalmente diferentes (que incluyen el nombre de la clase). Para fines de legibilidad puede o no ser útil dependiendo de qué tan relacionados estén. – justkt

+0

El método estático de la clase padre se puede volver a declarar por clase secundaria, lo que oculta el método estático de la clase padre. Esto se conoce como redefinición en Java. – Ghos3t

12

Nunca he oído hablar de "redefinir" como un término OO tal como se aplica a Java.

Sin embargo, el ejemplo que das es no primordial, porque los métodos estáticos no se heredan, pero se envían de forma estática en función del tipo de la variable (en oposición a la distribución dinámica que se produce con métodos miembro).

Yo no diría que es una definición re, sin embargo - que tenía un método llamado DonkeyBattler.doBattle, y ahora se ha definido un método separado compiletely llamada FunkyBattler.doBattle.

2

Es totalmente un concepto erróneo de que un método sólo se puede sobrecargar en la misma clase. En su lugar, el método puede ser una sobrecarga en la subclase también.

0

La redefinición es válida para Java y es para métodos estáticos. Si desea cambiar lo que hace un método estático para su clase, puede redefinirlo. Esto no se ve afectado por el polimorfismo ya que eso no se aplica a los métodos estáticos.

Usando su ejemplo todas las llamadas al nombre de la clase o clases de todos los sub obtendrán el método original doBattle(). Una llamada específica al FunkyBattler.doBattle() invocará el método estático redefinido en la clase FunkyBattler.

3

intención de primordial es en realidad redefiniendo el método heredado de la clase padre.

Redefining implica:

  1. reemplazo

    1. **Replacement** is the case in which child class is overriding 
    

    El método heredado de la clase padre con un comportamiento (funcionalidad) que es completamente diferente de método de matriz y una señal correspondiente para este proceso no es llamando a super.method() en el cuerpo del método hijo.

  2. Refinamiento

    2. Refinement is the case in which child is overriding inherited 
    

    El método de padre con una funcionalidad relacionada con funcionalidad método matriz, signo de este proceso está llamando generalmente super.method() en el cuerpo del método niño.

0

Tienes método "doBattle" cuales es estática y en los métodos estáticos de Java no puede ser cambiada, esto no significa que no pueden ser redefinidos en una subclase, Así que aquí está redefiniendo el método doBattle en FunkyBattler clase una subclase de DonkeyBattler

-1

Redefining y desbordamiento viene con en los mismos escenarios. La única diferencia es que si los métodos utilizados son estáticos, se redefinirán.

ejemplo:

Anulación:

Class A{ 
     public void show(){ 
      SOP("class a"); 
     } 
    } 

    Class B extends A{ 
    public void show(){ 
     SOP("class B"); 
    } 
    } 

Redefiniendo:

Class A{ 
     public static void show(){ 
      SOP("class a"); 
     } 
    } 

    Class B extends A{ 
    public static void show(){ 
     SOP("class B"); 
    } 
    } 

Nota: Los métodos estáticos parece como si se sobre-Rided pero que en realidad se redefinen.

  1. Redefiniendo es con métodos estáticos.
  2. Los métodos estáticos están asociados con Class y no con Object, por lo que no reemplazamos según la instancia por el tiempo de ejecución.
  3. En caso de estática, solo estamos redefiniendo el método.
0
public class Animal{ 
      public static void doStuff(){ 
       System.out.println("In animal"); 
      } 
    } 

    public class Dog extends Animal { 


    //redifinition of the method, since it is... Static 
    static void doStuff() { 
     System.out.println("In Dog..."); 
    } 

    public static void main(String[] args) { 
     Animal animal = new Dog(); 

     animal.doStuff(); 
    } 
} 

La salida será 'En animales', incluso si se llama al método estático de referencia para el perro, usted debe deducir entonces que el polimorfismo en tiempo de ejecución no funciona igual que con orden.

2

Overriding y Redefining (también conocido como escondite) son casi los alguna cosa excepto:

primordial es para los métodos de instancia y redefiniendo o escondite es para métodos de clase. La redefinición es solo en el caso de los métodos estáticos ya que los métodos estáticos no tienen un polimorfismo de tiempo de ejecución.

Consulte la siguiente código de aclaración:

class Foo { 
    public static void classMethod() 
    { 

     SOP("classMethod() in Foo"); 
    } 

    public void instanceMethod() 
    { 
     SOP ("instanceMethod() in Foo"); 
    } 
     } 

class Bar extends Foo { 
    public static void class Method() 
    { 
     SOP ("classMethod() in Bar"); 
    } 

    public void instanceMethod() { 
     SOP ("instanceMethod() in Bar"); 
    } 
      } 

class Test { 
    public static void main(String[] args) { 
     Foo f = new Bar(); 
     f.instanceMethod(); 
     f.classMethod(); 
    } 
} 

la salida correspondiente a este código es: instanceMethod() en la barra de classmethod() en Foo

La razón para esta salida:

Dado que instanceMethod() es un método de instancia, en el que Bar reemplaza el método de Foo, en tiempo de ejecución, la JVM usa la clase real de la instancia f para determinar qué método ejecutar. Aunque f se declaró como un Foo, la instancia real que creamos fue una nueva barra().Entonces en tiempo de ejecución, el J.V.M. encuentra que f es una instancia de Bar, por lo que llama a instanceMethod() en Bar en lugar de invocar a Foo.

Con classMethod(), como es un método de clase, el compilador y J.V.M. no espere necesitar una instancia real para invocar el método. E incluso si proporciona uno, el J.V.M. nunca lo miraré. El compilador solo verá el tipo declarado de la referencia y usará ese tipo declarado para determinar, en tiempo de compilación, a qué método llamar. Como f se declara como tipo Foo, el compilador examina f.classMethod() y decide que significa Foo. método de clase No importa que la instancia referida por f sea en realidad una barra; para los métodos estáticos, el compilador solo usa el tipo declarado de la referencia.

Es por eso que dije al principio que un método estático no tiene polimorfismo en tiempo de ejecución.

Cuestiones relacionadas