La base de la fuerza llamada al método

Hay una construcción en Java o C# que las fuerzas de heredar de las clases para llamar a la base de la aplicación? Usted puede llamar a super() o (base), pero es posible que lo tiene a tiro un error en tiempo de compilación si no se llama así? Que sería muy conveniente..

–edit–

Principalmente estoy curioso acerca de la sustitución de métodos.

  • ¿Te refieres a partir de un constructor de cuando se reemplaza un método?
InformationsquelleAutor irwinb | 2010-10-20

12 Kommentare

  1. 18

    No hay y no debe ser nada para hacer eso.

    La cosa más cercana que se me ocurre de la mano si algo les gusta tener este en la clase base:

    public virtual void BeforeFoo(){}
    
    public void Foo()
    {
    
    this.BeforeFoo();
    //do some stuff
    this.AfterFoo();
    
    }
    
    public virtual void AfterFoo(){}

    Y permitir que heredar de la clase reemplazar BeforeFoo y/o AfterFoo

    • Lo que usted sugiere parece ser la solución común al problema. A pesar de tener la fuerza (o automáticamente llaman), de la que hereda de la clase para llamar sería conveniente y haría que ciertos errores fáciles de encontrar. Podría usted comentar sobre por qué no no ser cualquier característica hace esto? No es ir contra los conceptos de polimorfismo y si lo hace, ¿por qué?
    • Si tengo una clase que extiende a otra clase que me obligó a llamar a la base.Foo() en algún lugar de mi Foo, que es bastante limitante. Yo llame a la base.Foo() si quiero que la funcionalidad, o que no puedo usar la clase para ampliar la mina. El compilador debe cumplir un conjunto mínimo de reglas básicas. Usted debe comprobar fuera de los contratos de código para .NET msdn.microsoft.com/en-us/devlabs/dd491992.aspx
    • No veo cómo su limitación, si usted tiene una clase que debe llamar a la base del método es una opción de diseño, si la base de la llamada al método es opcional, entonces usted no utilice el hipotético palabra clave que obliga a una base de llamada. En los casos donde el método base siempre DEBE ser llamado sin excepciones no veo cómo su limitación.. ya que el diseñador específicamente la eligió para ser de esa manera.
  2. 9

    No en Java. Podría ser posible en C#, pero alguien tendrá que hablar para que.

    Si entiendo correctamente, usted desea que esta:

    class A {
        public void foo() {
            //Do superclass stuff
        }
    }
    
    class B extends A {
        public void foo() {
            super.foo();
            //Do subclass stuff
        }
    }

    Lo que usted puede hacer en Java para garantizar el uso de la superclase foo es algo así como:

    class A {
        public final void foo() {
            //Do stuff
            ...
            //Then delegate to subclass
            fooImpl();
        }
    
        protected abstract void fooImpl();
    }
    
    class B extends A {
        protected void fooImpl() {
            //Do subclass stuff
        }
    }

    Es feo, pero logra lo que desea. De lo contrario, usted sólo tiene que tener cuidado para asegurarse de que usted llame al método de la superclase.

    Tal vez usted podría jugar con su diseño para solucionar el problema, en lugar de utilizar una solución técnica. Puede que no sea posible, pero es probablemente vale la pena pensar.

    EDIT: tal vez no he entendido la pregunta. Estás hablando sólo de los constructores o métodos en general? Supuse métodos en general.

    • +1: yo no creo que sea feo. Es el método de plantilla de patrón, y el enfoque adecuado. El nombre fooImpl() es feo, pero esto es sólo un ejemplo…
  3. 3

    El siguiente ejemplo se lanza un InvalidOperationException cuando la base de la funcionalidad no es hereditario cuando se reemplaza un método.

    Esto puede ser útil para escenarios donde el método es invocado por algunos internos de la API.

    es decir, donde Foo() no está diseñado para ser invocada directamente:

    public abstract class ExampleBase {
        private bool _baseInvoked;
    
        internal protected virtual void Foo() {
            _baseInvoked = true;
            //IMPORTANT: This must always be executed!
        }
    
        internal void InvokeFoo() {
            Foo();
            if (!_baseInvoked)
                throw new InvalidOperationException("Custom classes must invoke `base.Foo()` when method is overridden.");
        }
    }

    Obras:

    public class ExampleA : ExampleBase {
        protected override void Foo() {
            base.Foo();
        }
    }

    Grita:

    public class ExampleB : ExampleBase {
        protected override void Foo() {
        }
    }
  4. 2

    Si entiendo correctamente, usted desea exigir que su clase base el comportamiento no es anulada, pero aún así ser capaz de extender, entonces yo tendría que utilizar el método de plantilla de diseño en el patrón y en C# no incluir la palabra clave virtual en la definición del método.

  5. 1

    No. No es posible. Si usted tiene que tener una función que hace antes o después de la acción de hacer algo como esto:

    internal class Class1
    {
       internal virtual void SomeFunc()
       {
          //no guarantee this code will run
       }
    
    
       internal void MakeSureICanDoSomething()
       {
          //do pre stuff I have to do
    
          ThisCodeMayNotRun();
    
          //do post stuff I have to do
       }
    
       internal virtual void ThisCodeMayNotRun()
       {
          //this code may or may not run depending on 
          //the derived class
       }
    }
  6. 1

    No he leído TODAS las respuestas aquí; sin embargo, yo estaba considerando la misma pregunta. Después de revisar lo que yo REALMENTE quería hacer, me parecía que si me quieren FORZAR la llamada a la base del método que yo no debería haber declarado la base del método virtual (override-poder) en el primer lugar.

  7. 0

    No creo que haya ninguna solución factible incorporado. Estoy seguro de que hay separada herramientas de análisis de código que puede hacer que, a pesar de que.

  8. 0

    EDITAR Malinterpretar la construcción como constructor. Dejando como CW, ya que se ajusta a un muy limitado subconjunto del problema.

    En C# puede forzar este comportamiento mediante la definición de un único constructor de tener al menos un parámetro en el tipo base. Esto elimina el constructor por defecto y las fuerzas de los tipos derivados explcitly llamar a la base especificada o se obtiene un error de compilación.

    class Parent {
      protected Parent(int id) {
      }
    }
    
    class Child : Parent { 
      //Does not compile
      public Child() {}
      //Also does not compile
      public Child(int id) { }
      //Compiles
      public Child() :base(42) {}
    
    }
    • Creo que el OP está hablando acerca de ser capaz de obligar a public override void Method() {base.Method(); ...}, no se trata de constructores.
    • sí no entendí construir como constructor :). Respuesta actualizada.
  9. 0

    En java, el compilador sólo se puede aplicar en el caso de los Constructores.

    Un constructor debe ser llamado de todo el camino hasta la cadena de la herencia .. es decir, si el Perro extends Animal se extiende Cosa, el constructor para Perro debe llamar a un constructor para el Animal debe llamar a un constructor para la Cosa.

    Este no es el caso de los métodos de uso regular, donde el programador debe llamar explícitamente a un super aplicación, en caso necesario.

    La única manera de hacer cumplir algunas implementación de base de código a ejecutar es la de dividir override-capaz de código en un método independiente de la llamada:

    public class Super
    {
        public final void doIt()
        {
        //cannot be overridden
            doItSub();
        }
    
        protected void doItSub()
        {
         //override this
        }
    }
    
    public class Sub extends Super
    {
        protected void doItSub()
        {
         //override logic
        }
    }
  10. 0

    Me topé con este post y no necesariamente como cualquier respuesta en particular, así que pensé que iba a ofrecer mi propio …

    No hay ninguna manera en C# para exigir que la base del método es llamado. Por lo tanto la codificación como tal se considera un anti-patrón desde un seguimiento desarrollador no puede darse cuenta que debe llamar a la base del método de los demás de la clase será en un incompletas o mal estado.

    Sin embargo, he encontrado que en circunstancias donde este tipo de funcionalidad es necesaria y debe ser cumplido en consecuencia. Generalmente la clase derivada de las necesidades de un recurso de la clase base. Con el fin de obtener los recursos, que normalmente podrían estar expuestos a través de una propiedad, sino que está expuesta a través de un método. La clase derivada no tiene más remedio que llamar al método para obtener el recurso, por lo tanto, asegurar que el método de la clase base se ejecuta.

    La siguiente pregunta lógica que puede preguntarse es ¿por qué no poner en el constructor lugar? La razón es que puede ser un problema de orden de operaciones. En el momento en que la clase se construye, puede haber algunas entradas que aún falta.

    No esta lejos de la pregunta? Sí y no. Sí, es la fuerza de la clase derivada a un método de la clase base. No, no lo hace con la palabra clave override. Este podría ser útil para una persona que busca una respuesta a este post, tal vez.

    Yo no estoy predicando este evangelio como, y si las personas ven un inconveniente de este enfoque, me encantaría oír acerca de él.

  11. 0

    No fuerce la base de la llamada. Hacer que los padres método de hacer lo que quiera, mientras que llamar a un reemplazable (por ejemplo: abstracto) método protegido en su cuerpo.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea