[英]Exposing only some inherited methods in the derived class
我偶然发现了与OOPS有关的面试问题。 这是一个问题:有一个基类A
有5种方法。 现在我应该如何设计类,以便如果B
类继承A
类,则只暴露3个方法。 如果C
类继承了A
类,则会暴露其余的2个方法。
有什么想法吗 ??
它不应该在任何面向对象的语言中,否则它将打破Liskov替换原则 。 用B
代替A
不应该降低其正确性(意味着方法不应该突然不可用)
然而,在允许一些“开箱即用”的思考的问题中仍然存在一些模糊性。 以下是我要向采访者提出的问题:
基于这些答案,您可以使用internal
,显式接口实现等提出可能的选项。
如果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
{
}
}
我认为这是一个诡计甚至是愚蠢的问题。 为实现这一目标,我们必须打破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();
}
我能想到的唯一方法就是让它们在A中都是私有的 ,然后通过B和C中的封装来暴露它们......但是它们没有暴露,只是被执行......所以它是半对的。
我也认为这是不可能的。
但要给出一个近似的答案:
在A虚拟中创建3个方法,然后在B中实现它们。然后在C中覆盖这2个方法。
没有人说在编写A类时应该暴露出A类的5种方法。 在C#
您可以简单地在A类中编写5个受保护的方法,并通过使用new修饰符编写一些隐藏方法来公开您希望可访问的方法 - 尽管这实际上不会直接暴露方法,它们只是被包装。
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();
}
}
在您的评论中,您提到您感兴趣的是否可以使用任何其他语言进行此操作。 你可以通过使用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...
我知道,回应是迟到的。 只是想分享我的想法:
将A类定义为基类。 有中间子类A1 - > M1,M2,M3和A2 - > M4,M5来自A类
现在,您可以拥有1)B类继承A1 2)C类继承A2
这两个类仍然来自A类。
而且我们也没有打破liskov替代原则。
希望,这清楚了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.