这个问题看起来很奇怪,但我最近在一次采访中遇到了这个问题。
有人问过,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#中有没有办法可以实现这样的目标......
答案 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)
隐藏从基类继承的方法有两种解决方案:
问候。
答案 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
。