2010-02-16 4 views
6

Diese Frage scheint seltsam, aber ich bin in einem der Interviews kürzlich auf diese Frage gestoßen.Gibt es eine Möglichkeit, die Methoden teilweise in untergeordneten Klassen zu verbergen?

Ich wurde gefragt, gibt es einen Weg in C#, um die Methoden teilweise in einer ererbten Kindklasse zu verstecken ?. Angenommen, die Basisklasse A, exposed 4 Methoden. Klasse B implementiert A und hat nur Zugriff auf die ersten 2 Methoden und Klasse C implementiert. A hat nur Zugriff auf die letzten 2 Methoden.

Ich weiß, dass wir auf diese Weise tun können

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(); 
    } 
} 

Aber was wollten sie ist anders. Sie wollten diese Klassen verbergen, indem sie von Basisklassen erbten. so etwas wie dieses

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(); 
    } 
} 

gibt es eine Möglichkeit in C# wir so etwas wie dies erreichen können ...

Antwort

2

Auch wenn Sie nicht genau das tun können, was Sie wollen, Sie explizite Schnittstellenimplementierung, zu helfen, nutzen könnten in die Schnittstellenelemente werden nur offen gelegt, wenn sie explizit an diese Schnittstelle übergeben werden ...

+0

@thecoop, ja, wir können das machen .., aber das Problem ist, dass die Methoden versteckt werden müssen, wenn die Basisklasse selbst erben wird ... – RameshVel

0

Vielleicht hat sich der Interviewer auf method hiding bezogen?

Hier deklarieren Sie eine Methode mit der gleichen Signatur wie in Ihrer Basisklasse - aber Sie verwenden nicht das Schlüsselwort override (entweder weil Sie nicht oder nicht - wie bei der Methode in der Basis) Klasse ist nicht virtuell).

Die Methode Verbergen, im Gegensatz zu overriding, ermöglicht es Ihnen, eine völlig andere Methode zu definieren - eine Methode, die nur durch einen Verweis auf die abgeleitete Klasse aufgerufen werden kann. Wenn Sie über einen Verweis auf die Basisklasse aufgerufen werden, rufen Sie die ursprüngliche Methode für die Basisklasse auf.

0

Verwenden Sie keine Vererbung. Es stellt die öffentlichen oder geschützten Einrichtungen der Basisklasse direkt in der abgeleiteten Klasse zur Verfügung, so dass es einfach nicht erwünscht ist.

Stattdessen muss die abgeleitete Klasse die relevante Schnittstelle implementieren und (falls erforderlich) die Methoden an eine private Instanz der zugrunde liegenden Klasse weiterleiten. Das heißt, verwenden Sie Komposition (oder "Aggregation") anstelle von Vererbung, um die ursprüngliche Klasse zu erweitern.

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

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

Übrigens sollten Klassennamen mit einem Großbuchstaben beginnen.

0

Es gibt zwei Lösungen Methoden verbergen von einer Basisklasse geerbt:

  • Wie thecoop erwähnt, können Sie explizit die Schnittstelle implementieren, um die Methoden zu erklären Sie ausblenden möchten.
  • Oder Sie können einfach diese Methoden in der Basisklasse erstellen (nicht von irgendeiner Schnittstelle geerbt) und sie als privat markieren.

Grüße.

0

Was ist mit der Injektion der Basisklasse als 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(); } 
} 

Injection verhindert die Verletzung der Interface Segregation Principle.Eine reine Vererbung bedeutet, dass Ihre FirstChild von einer Schnittstelle abhängt, die sie nicht verwendet. Wenn Sie nur die IFirst Funktionalität in Base beibehalten möchten, aber den Rest davon ignorieren, dann können Sie nicht rein von Base erben.

3

Ich tat es, indem ich 1 Hauptgrundklasse und 2 Unterbasen hatte.

// 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(); 


    } 
} 
Verwandte Themen