2010-02-16 13 views
6

Esta pregunta parece extraña, pero me encontré con esta pregunta en una de las entrevistas recientemente.¿Hay alguna manera de ocultar los métodos parcialmente en clases para niños?

Me han preguntado, ¿hay alguna manera en C# para ocultar los métodos parcialmente en una clase hija heredada ?. Suponga que la clase base A, expuso 4 métodos. La Clase B implementa A y solo tendrá acceso a los primeros 2 métodos y los implementos de Clase C A solo tendrán acceso a los 2 últimos métodos.

Sé que podemos hacerlo de esta manera

public interface IFirstOne 
{ 
    void method1();   
    void method2(); 
} 

public interface ISecondOne 
{ 
    void method3(); 
    void method4(); 
} 

class baseClass : IFirstOne, ISecondOne 
{ 
    #region IFirstOne Members 

    public void method1() 
    { 
     throw new NotImplementedException(); 
    } 

    public void method2() 
    { 
     throw new NotImplementedException(); 
    } 

    #endregion 

    #region ISecondOne Members 

    public void method3() 
    { 
     throw new NotImplementedException(); 
    } 

    public void method4() 
    { 
     throw new NotImplementedException(); 
    } 

    #endregion 
} 

class firstChild<T> where T : IFirstOne, new() 
{ 
    public void DoTest() 
    { 

     T objt = new T(); 
     objt.method1(); 
     objt.method2(); 
    } 
} 


class secondChild<T> where T : ISecondOne, new() 
{ 
    public void DoTest() 
    { 
     T objt = new T(); 
     objt.method3(); 
     objt.method4(); 
    } 
} 

Pero lo que querían es diferente. Querían ocultar estas clases sobre heredar de clases base. algo como esto

class baseClass : IFirstOne, ISecondOne 
{ 
    #region IFirstOne Members 

    baseClass() 
    { 
    } 

    public void method1() 
    { 
     throw new NotImplementedException(); 
    } 

    public void method2() 
    { 
     throw new NotImplementedException(); 
    } 

    #endregion 

    #region ISecondOne Members 

    public void method3() 
    { 
     throw new NotImplementedException(); 
    } 

    public void method4() 
    { 
     throw new NotImplementedException(); 
    } 

    #endregion 
} 

class firstChild : baseClass.IFirstOne //I know this syntax is weird, but something similar in the functionality 
{ 
    public void DoTest() 
    { 
     method1(); 
     method2(); 

    } 
} 


class secondChild : baseClass.ISecondOne 
{ 
    public void DoTest() 
    {   
     method3(); 
     method4(); 
    } 
} 

hay una manera en C# podemos lograr algo como esto ...

Respuesta

2

Aunque no se puede hacer exactamente lo que quiere, se puede utilizar la implementación de interfaz explícita para ayudar, en que los miembros de la interfaz solo están expuestos si se expulsa explícitamente a esa interfaz ...

+0

@thecoop, sí podemos hacerlo de esa manera ..., pero el problema es que los métodos deben ocultarse al heredar la clase base en sí ... – RameshVel

0

¿Quizás el entrevistador se haya estado refiriendo a method hiding?

Aquí es donde declara un método con la misma firma que en su clase base, pero no usa la palabra clave override (ya sea porque no lo hace o no puede hacerlo) como cuando el método en la base la clase no es virtual).

La ocultación de métodos, a diferencia de overriding, le permite definir un método completamente diferente, uno que solo se puede llamar a través de una referencia a la clase derivada. Si se llama a través de una referencia a la clase base, se llamará al método original en la clase base.

0

No usar herencia. Hace que las instalaciones públicas o protegidas de la clase base estén disponibles directamente en la clase derivada, por lo que simplemente no desea lo que desea.

En su lugar, haga que la clase derivada implemente la interfaz pertinente y (si es necesario) reenvíe los métodos a una instancia privada de la clase subyacente. Es decir, usa la composición (o "agregación") en lugar de la herencia para extender la clase original.

class firstChild : IFirstOne 
{ 
    private baseClass _owned = new baseClass(); 

    public void method1() { _owned.method1(); } 
    // etc. 
} 

Por cierto, los nombres de las clases deberían comenzar con una letra mayúscula.

0

Hay 2 soluciones para ocultar los métodos heredados de una clase base:

  • Como se ha mencionado por thecoop, se puede implementar la interfaz explícitamente declarando los métodos que desea ocultar.
  • O simplemente puede crear estos métodos en la clase base (no heredados de ninguna interfaz) y marcarlos como privados.

Saludos.

0

¿Qué pasa con la clase base de inyección como IFirst?

interface IFirst { 
    void method1(); 
    void method2(); 
} 

interface ISecond { 
    void method3(); 
    void method4(); 
} 

abstract class Base : IFirst, ISecond { 
    public abstract void method1(); 
    public abstract void method2(); 
    public abstract void method3(); 
    public abstract void method4(); 
} 

class FirstChild : IFirst { 
    private readonly IFirst _first; 
    public FirstChild(IFirst first) { 
     _first = first; 
    } 
    public void method1() { _first.method1(); } 
    public void method2() { _first.method2(); } 
} 

Inyección evita que infrinja el Interface Segregation Principle.Pure inheritance significa que su FirstChild depende de una interfaz que no utiliza. Si desea conservar solo la funcionalidad IFirst en Base, pero ignore el resto, entonces no puede heredar simplemente de Base.

3

Lo hice teniendo 1 base de clase principal y 2 bases secundarias.

// Start with Base class of all methods 
public class MyBase 
{ 
    protected void Method1() 
    { 

    } 

    protected void Method2() 
    { 

    } 

    protected void Method3() 
    { 

    } 

    protected void Method4() 
    { 

    } 
} 

// Create a A base class only exposing the methods that are allowed to the A class 
public class MyBaseA : MyBase 
{ 
    public new void Method1() 
    { 
     base.Method1(); 
    } 

    public new void Method2() 
    { 
     base.Method2(); 
    } 
} 

// Create a A base class only exposing the methods that are allowed to the B class 
public class MyBaseB : MyBase 
{ 
    public new void Method3() 
    { 
     base.Method3(); 
    } 

    public new void Method4() 
    { 
     base.Method4(); 
    } 
} 

// Create classes A and B 
public class A : MyBaseA {} 

public class B : MyBaseB {} 

public class MyClass 
{ 
    void Test() 
    { 
     A a = new A(); 

     // No access to Method 3 or 4 
     a.Method1(); 
     a.Method2(); 

     B b = new B(); 

     // No Access to 1 or 2 
     b.Method3(); 
     b.Method4(); 


    } 
} 
Cuestiones relacionadas