在派生类中仅显示一些继承的方法

时间:2015-05-21 14:53:44

标签: c# oop inheritance

我偶然发现了与OOPS有关的面试问题。这是一个问题: 有一个基类A有5种方法。现在我应该如何设计类,以便如果类B继承类A,则只暴露3个方法。如果一个类C继承了类A,则会暴露其余的两个方法。

有什么想法吗?

8 个答案:

答案 0 :(得分:3)

任何面向对象的语言中都不可能,否则会破坏Liskov substitution principle。用B代替A不应该降低其正确性(意味着方法不应突然不可用)

然而,在这个问题中仍然存在一些含糊不清的问题,这些问题允许一些开箱即用的问题。思维。以下是我要向采访者提出的问题:

  • 你是什么意思"暴露"?
  • A中的5种方法是否必须公开?
  • "博览会" C需要隐含或可以明确暴露(例如传递)

根据这些答案,您可以使用internal,显式接口实现等提出可能的选项。

答案 1 :(得分:3)

如果A是部分的,那么你有2个名称空间:

namespace the_impossible
{
class Program
{
    static void Main(string[] args)
    {
        B b = new B();
        C c = new C();

        b.m1();
        b.m2();
        b.m3();

        c.m4();
        c.m5();
    }
}

namespace A_1
{
    public partial class A
    {
        public  void m1() { }
        public  void m2() { }
        public  void m3() { }
    }
}

namespace A_2
{
    public partial class A
    {
        public void m4() { }
        public void m5() { }
    }
}

class B : A_1.A 
{

}

class C : A_2.A
{ 

}
}

enter image description here enter image description here

答案 2 :(得分:1)

我认为这是一个诡计甚至是愚蠢的问题。为实现这一目标,我们必须打破Liskov替代原则。你不应该预先设定类的层次结构。

也许你应该使用接口代替:

public class A {} //why we even need this class?

public class B : A, I3Methods
{
    public void Method1() { }
    public void Method2() { }   
    public void Method3() { }
}

public class C : A, I2Methods
{
    public void Method4() { }
    public void Method5() { }
}

public interface I3Methods
{
    void Method1();
    void Method2();
    void Method3();
}

public interface I2Methods
{
    void Method4();
    void Method5();
}

答案 3 :(得分:1)

我能想到的唯一方法是将它们全部隐藏在 A 中,然后通过 B C 中的封装展示它们。 ..但他们没有暴露,只是执行......所以它是对的。

答案 4 :(得分:0)

我也认为这是不可能的。

但要给出一个近似的答案:

在A虚拟中创建3个方法,然后在B中实现它们。然后在C中覆盖这2个方法。

答案 5 :(得分:0)

没有人说A类的5种方法在编写时应该暴露出来。在C#中,您可以简单地在A类中编写5个受保护的方法,并通过使用new modifier编写一些隐藏方法来公开您希望可访问的方法 - 尽管这实际上不会暴露方法直接他们只是被包裹着。

class A
{
    protected void M1() { }
    protected void M2() { }
    protected void M3() { }
    protected void M4() { }
    protected void M5() { }
}

class B : A
{
    public new void M1()
    {
        base.M1();
    }

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

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

}

class C : A
{
    public new void M4()
    {
        base.M4();
    }
    public new void M5()
    {
        base.M5();
    }
}

答案 6 :(得分:0)

在您的评论中,您提到您感兴趣的是否可以使用任何其他语言进行此操作。您可以通过使用using关键字在C ++中执行此操作。所以,从A类开始:

class A {
public:
    int Method1() {     return 1;   }
    int Method2() {     return 2;   }
    int Method3() {     return 3;   }
    int Method4() {     return 4;   }
    int Method5() {     return 5;   }
};

然后使用私有继承定义类B(基本上你不能从B自动转换为A,A中的所有公共方法都成为B中的私有方法。)

class B: private A {
public:
    // We want to expose methods 1,2,3 as public so change their accessibility
    // with the using keyword
    using A::Method1;
    using A::Method2;
    using A::Method3;

};

对C类做同样的事情,而是公开其他两种方法:

class C: private A {
public:
    using A::Method4;
    using A::Method5;

};

或者,如果你应该通过C公开所有方法,只需使用公共继承,一切都存在:

class C: public A {
public:

};

用法:

B *b = new B();
b->Method1();  // This works, Method1 is public
b->Method4();  // This fails to compile, Method4 is inaccessible

我之所以说上述原因,是因为您可以通过将B的实例明确地转换为A来解决它:

A *brokena = b;  // This wouldn't compile because the typecast is inaccessible

A *a = (A*)b;    // This however does work because you're explicitly casting
a->Method4();    // And now you can call Method4 on b...

答案 7 :(得分:0)

我知道,回应是迟到的。只是想分享我的想法:

将A类定义为基类。 有中间子类A1 - > M1,M2,M3和A2 - > M4,M5来自A类

现在,你可以拥有 1)B类继承A1 2)C类继承A2

这两个类仍然来自A类。

而且我们也没有打破liskov替换原则。

希望,这清楚了。