我发现有一个关于OOPS的面试问题,问题如下:
有一个基类
A
有5个方法。现在如果一个类B
继承自类A
,那么只有3个方法会被公开。如果一个类C
继承自类A
,那么剩下的2个方法会被公开。
你有什么想法吗?A
有5个方法。现在如果一个类B
继承自类A
,那么只有3个方法会被公开。如果一个类C
继承自类A
,那么剩下的2个方法会被公开。
你有什么想法吗?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
{
}
}
internal
、显式接口实现等来提出可能的选项。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中创建3个虚方法,然后在B中实现它们。接着在C中重写这2个方法。
我知道,回复已经晚了。只是想分享我的想法:
将类A定义为基类。 有中间子类A1 -> M1,M2,M3和A2 -> M4,M5从类A派生
现在,您可以有 1)类B继承A1 2)类C继承A2
这两个类仍然是从类A派生的。
而且我们也没有违反里氏替换原则。
希望这能给您带来清晰度。
没有人说在编写类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();
}
}
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;
};
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
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...
new public void Foo()
是否算作“暴露”protected void Foo()
? - Alexei Levenkov