2010-09-02 17 views
16

¿Es posible hacer que mis funciones miembro final estén en Java, para que las clases derivadas no puedan anularlas?Cómo definir las funciones miembro 'final' para una clase

+0

Pregunta interesante para hacer en una entrevista ... ya que la respuesta es no hacer nada. (Creo). – Stephen

+0

No Funciones especiales en C++ evitar en sobrescribir, simplemente declarar virtual y anular. – ratty

+1

La pregunta no es muy clara. Que se haya molestado en preguntarlo implicaba, a mi entender, que estaba hablando de funciones virtuales, en cuyo caso la respuesta es no: una clase derivada de cualquier clase con una función virtual especificada en un ancestro puede anular la función. Como otros han señalado, sin "virtual", no se pueden anular todas las funciones. No sé Java, así que no estoy seguro de qué permite cuando .... –

Respuesta

9

Es muy posible que sea, de hecho, el comportamiento predeterminado. Es decir. si no declara los métodos de instancia de clase explícitamente como virtual, no pueden ser overridden en subclases (solo hidden, que es un caso diferente, y casi siempre erróneo).

Eficaz C++ tercera edición, el artículo 36 se ocupa de esto en detalle. Considere

class B { 
public: 
    virtual void vf(); 
    void mf(); 
    virtual void mf(int); 
    ... 
}; 

class D: public B { 
public: 
    virtual void vf();    // overrides B::vf 
    void mf();      // hides B::mf; see Item33 
    ... 
}; 

D x;        // x is an object of type D 
B *pB = &x;      // get pointer to x 
D *pD = &x;      // get pointer to x 

pD->vf();       // calls D::mf, as expected 
pB->vf();       // calls D::mf, as expected 
pD->mf();       // calls D::mf, as expected 
pB->mf();       // calls B::mf - surprise! 
pD->mf(1);      // error - D::mf() hides B::mf(int)! 
pB->mf(1);      // calls B::mf(int) 

Así que esto no es exactamente cómo se comporta final en Java, pero sólo se puede obtener esta estrecha con C++. Una alternativa podría ser evitar la subclasificación por completo. La solución técnica - de trabajo, pero no agradable - es declarar todos sus constructores private (y proporcionar un método de fábrica estático si desea permitir la creación de instancias de su clase, por supuesto).

+0

si no entendí mal, entonces 'Anulación' es ocultar la copia de la clase base, lo cual es muy posible en este caso. Lo que quiero es forzar a las clases derivadas a usar/llamar siempre la copia de la función de la clase base. – Hemant

+0

@Hemant, vea los enlaces y el ejemplo de código que agregué. –

+0

No sé Java, pero por lo que escuché, pensé en Java que ni siquiera se podía declarar 'D :: mf()'. – sbi

3

Comprobar this de Bjarne (¿Puedo detener personas que deriva de mi clase?)

+0

Un enlace [directo] (http://www2.research.att.com/~bs/bs_faq2.html#no-derivation) podría haber sido más útil: p. – Stephen

+0

@Stephen: Lo puse. @chubsdad: espero que no te importe. – sbi

+0

@sbi: Ah, sí, editar derechos. Tengo esos ahora. Olvidé. > _ <. – Stephen

1

En realidad es posible si está utilizando MSVC. Hay una palabra clave sealed. Aquí hay un example from msdn.

21

C++ 11 añade una palabra clave contextual final para apoyar esta:

class B 
{ 
    public: 
    virtual void foo() final; 
}; 
class D : B 
{ 
    public: 
    virtual void foo(); // error: declaration of 'foo' overrides a 'final' function 
}; 

final se admite en GCC 4.7 y 3.0 Clang. Y como señala Sergio en su respuesta, MSVC++ lo admite (con la ortografía sealed), desde MSVC++ 2005. Entonces, si encapsula en una minimacro macro y lo configura dependiendo de su compilador, puede estar en camino con esto. Solo asegúrese de que en realidad es usando tal compilador al menos cada cierto tiempo, por lo que detectará cualquier error con anticipación.

1

¡El nuevo estándar C++ 11 ahora admite anulaciones explícitas y final de las funciones de miembro!

Cuestiones relacionadas