Prefacio
El título "El problema de reducir la accesibilidad de las subclases sobre las funciones de clase principal en Java y C ++" parece ser más académico, pero de hecho es un problema que es fácil de ignorar. Este artículo se esfuerza por explicar la diferencia entre este tema en Java y C ++.
Primero, presentaremos lo que es "reducción de accesibilidad de los subclases sobre la cobertura de la función de clase principal". Para la herencia, las subclases pueden anular las "funciones virtuales" de la clase principal, aunque no hay funciones virtuales de término en Java, todas las funciones de Java pueden considerarse como funciones virtuales, porque todas las funciones de Java pueden ser anuladas por subclases. Aquí solo tomamos prestado el significado del término "función virtual" y no profundizamos en los detalles del idioma. Tanto Java como C ++ permiten cambiar la accesibilidad de las funciones al anular. La llamada "accesibilidad" es utilizar caracteres de control de acceso como público, protegido y privado para modificarlo para controlar si se puede acceder a la función. Por lo general, el orden de accesibilidad es (ya que no hay un concepto de paquetes en C ++, el control de acceso al paquete no se considera por el momento, lo que no afecta la discusión aquí):
público> protegido> privado
Tome Java como ejemplo:
clase base {protegido void sayshello () {System.out.println ("Hello in Base"); }} class Child extiende la base {public void sayshello () {System.out.println ("Hello in Child"); }} Nota: La función sayHello() aquí. En la base de clase principal, esta función se modifica utilizando el carácter de control de acceso protegido. Y las subclases usan público en su lugar, no habrá problema. Cuando los subclases anulan las funciones de la clase principal, expandir la accesibilidad generalmente no es un problema.
Java y C ++ adoptan diferentes estrategias cuando las subclases reducen la anulación de accesibilidad a las funciones de clase principal.
Primero, tome Java como ejemplo y mire el siguiente código:
clase base {public void sayshello () {System.out.println ("Hello in Base"); }} La clase Child extiende la base {private void sayshello () {System.out.println ("Hello in Child"); }}En el código anterior, habrá un error de compilación en la línea 8 resaltada: ¡este código no se puede compilar en absoluto! Java no permite que las subclases reduzcan la accesibilidad al sobrescribir las funciones de la clase principal. En cuanto a las razones, podemos usar un ejemplo para ilustrar. Por ejemplo, escribimos el siguiente código fuera de la clase:
Base base = nueva base (); base.sayhello (); base = nuevo child (); base.sayhello ();
Si se puede compilar el código anterior, existe la posibilidad de que cuando se pueda acceder a la base a la nueva base (), se puede acceder a Sayhello (), pero cuando se puede acceder a Base a New Child (), Sayhello (). En opinión de Java, esto es una contradicción, y este problema debe evitarse. Por lo tanto, Java estipula desde la perspectiva del compilador de que no podemos escribir el código anterior.
Para C ++, la situación es diferente. Ejemplo de C ++ Ejemplo: Ejemplo:
clase base {public: virtual void sayshello () {std :: cout << "Hello in Base"; }} Class Child: Public Base {private: void sayshello () {std :: cout << "Hola en el niño"; }}Este código es completamente correcto en C ++. Tenga en cuenta que la subclase aquí reduce la accesibilidad al sobrescribir las funciones de la clase principal. Si no ve ningún problema, podemos escribir el siguiente código fuera de la clase:
Niño niño; niño.sayhello (); // no se puede compilar porque Sayshello () es el static_cast <Base &> (niño) .sayhello (); // no se puede compilar porque Sayshello () es público
La llamada de la línea 2 falla porque en el niño, sayHello() es privado y no se puede llamar externamente. Sin embargo, cuando lanzamos a los niños al objeto base usando static_cast, las cosas cambian: para base, sayHello() es público, por lo que puede llamarse normalmente.
Para este fin, el siguiente ejemplo se puede encontrar en la sección Acceso a las funciones virtuales del Capítulo de control de acceso de miembro estándar C ++:
clase B {public: virtual int f ();}; clase d: public b {private: int f ();}; void f () {d d; B* pb = & d; D* pd = & d; pb-> f (); // ok: b :: f () es público, d :: f () se invoca pd-> f (); // Error: d :: f () es privado}En este sentido, el estándar C ++ da una explicación:
El acceso se verifica en el punto de llamada utilizando el tipo de expresión utilizada para denotar el objeto para el cual se llama la función miembro (b* en el ejemplo anterior). El acceso de la función miembro en la clase en la que se definió (d en el ejemplo anterior) en general se desconoce.
Hay dos puntos clave para una traducción simple:
Debido a esto, las personas que llaman C ++ parecen ser capaces de llamar "hábilmente" funciones que originalmente eran inaccesibles a través de algunas transformaciones hábiles. Un ejemplo más práctico es: en Qt, QObject::event() es pública, y su función de event() se cambia a protegido. Para más detalles, puede leer el código relevante de Qt.
En resumen, cuando las subclases anulan las funciones de los padres, Java limita estrictamente que las subclases no pueden reducir la accesibilidad de la función, pero C ++ no tiene esta limitación. Personalmente, creo que desde la perspectiva de la ingeniería de software, las regulaciones de Java, sin duda, tienen más importancia de ingeniería, y las llamadas de funciones son más consistentes. El estándar C ++ simplificará significativamente la implementación del compilador, pero no es una buena referencia para la ingeniería.
PD: La versión oficial del estándar C ++ requiere compra, pero el borrador se puede descargar de forma gratuita. La dirección de descarga del borrador estándar de C ++ se puede encontrar en la página siguiente: https://isocpp.org/std/the-standard
Resumir
Lo anterior es todo el contenido de este artículo. Espero que el contenido de este artículo tenga cierto valor de referencia para el estudio o el trabajo de todos. Si tiene alguna pregunta, puede dejar un mensaje para comunicarse. Gracias por su apoyo a Wulin.com.