有没有办法在子类中隐藏部分方法?

时间:2010-02-16 13:36:44

标签: c# inheritance interface

这个问题看起来很奇怪,但我最近在一次采访中遇到了这个问题。

有人问过,c#中有没有办法在继承的子类中部分隐藏方法?假设基类A,暴露4种方法。 B类实现A,它只能访问前2个方法,而C类实现A只能访问最后2个方法。

我知道我们可以这样做

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

但他们想要的是不同的。他们希望隐藏这些类继承自基类。像这样的东西

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

在c#中有没有办法可以实现这样的目标......

6 个答案:

答案 0 :(得分:3)

我通过拥有1个主要基类和2个子基础来实现它。

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


    }
}

答案 1 :(得分:2)

虽然您无法完全按照自己的意愿行事,但您可以使用显式接口实现来提供帮助,只有在显式转换为该接口时才会公开接口成员...

答案 2 :(得分:0)

也许面试官可能指的是method hiding

这是您在基类中使用与on相同的签名声明方法的地方 - 但是您不使用override关键字(因为您没有或不能使用 - 就像方法一样)在基类中是非虚拟的。)

overriding相反,方法隐藏允许您定义一个完全不同的方法 - 一个只能通过对派生类的引用来调用的方法。如果通过对基类的引用调用,则将在基类上调用原始方法。

答案 3 :(得分:0)

不要使用继承。它使得基类的公共或受保护设施可以直接在派生类中使用,因此它根本不是您想要的。

相反,使派生类实现相关接口,并且(如果需要)将方法转发到底层类的私有实例。也就是说,使用组合(或“聚合”)而不是继承来扩展原始类。

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

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

顺便说一下,类名应该以大写字母开头。

答案 4 :(得分:0)

隐藏从基类继承的方法有两种解决方案:

  • 正如thecoop所提到的,您可以明确地实现声明要隐藏的方法的界面。
  • 或者您可以在基类中创建这些方法(不是从任何接口继承)并将它们标记为私有。

问候。

答案 5 :(得分:0)

如何将基类注入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(); }
}

注射可以防止您违反Interface Segregation Principle。纯继承意味着您的FirstChild依赖于它不使用的接口。如果您只想保留IFirst中的Base功能,但忽略其余部分,那么您就不能完全继承Base