views:

178

answers:

6

This question seems weird, but i came across this question in one of the interviews recently.

I ve been asked, is there a way in c# to hide the methods partially in a inherited child classes?. Assume the base class A, exposed 4 methods. Class B implements A and it will only have the access to first 2 methods and Class C implements A will only have the access to last 2 methods.

I know we can do this way

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

But what they wanted is different. They wanted to hide these classes on inheriting from baseclasses. something like this

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

is there a way in c# we can achieve something like this...

+2  A: 

Although you can't do exactly what you want, you could use explicit interface implementation to help, in which the interface members are only exposed if it is explicitly cast to that interface...

thecoop
@thecoop, yes we can do that way.., but the problem is the methods has to be hidden when inheriting the baseclass itself...
Ramesh Vel
A: 

Perhaps the interviewer may have been referring to method hiding?

This is where you declare a method with the same signature as on in your base class - but you do not use the override keyword (either because you don't or you can't - as when the method in the base class is non-virtual).

Method hiding, as opposed to overriding, allows you to define a completely different method - one that is only callable through a reference to the derived class. If called through a reference to the base class you will call the original method on the base class.

LBushkin
A: 

Don't use inheritance. It makes the public or protected facilities of the base class available directly in the derived class, so it simply isn't want you want.

Instead, make the derived class implement the relevant interface, and (if necessary) forward the methods on to a private instance of the underlying class. That is, use composition (or "aggregation") instead of inheritance to extend the original class.

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

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

By the way, class names should start with an upper case letter.

Daniel Earwicker
A: 

There is 2 solutions to hide methods inherited from a base class:

  • As mentioned by thecoop, you can explicitely implement the interface declaring the methods you want to hide.
  • Or you can simply create these methods in the base class (not inherited from any interface) and mark them as private.

Regards.

Ucodia
A: 

What about injecting base class as an 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 keeps you from violating the Interface Segregation Principle. Pure inheritance means that your FirstChild is depending on an interface that it doesn't use. If you want to retain only the IFirst functionality in Base, but ignore the rest of it, then you cannot purely inherit from Base.

Jarrett Meyer
+3  A: 

I did it by having 1 main base class and 2 sub bases.

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


    }
}
David Basarab