Этот вопрос кажется странным, но я столкнулся с этим вопросом в одном из интервью недавно.
Меня спросили, там путь в c# для сокрытия методов частично в наследованные дочерние классы?. Примите базовый класс A, выставил 4 метода. Класс B реализует A, и он будет только иметь доступ к первым 2 методам, и A реализаций Класса C будет только иметь доступ для длительности 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#, мы можем достигнуть чего-то вроде этого...
Хотя вы не можете делать именно то, что хотите, вы можете использовать явную реализацию интерфейса, чтобы помочь, в которой элементы интерфейса отображаются только в том случае, если они явно приведены к этому интерфейсу ...
Хотя вы не можете делать именно то, что хотите, вы можете использовать явную реализацию интерфейса, чтобы помочь, в которой члены интерфейса доступны только в том случае, если он явно приведен к этому интерфейсу...
-121--4435011-Ошибка «отсутствующий тип» означает, что соответствующий тип не найден в пути построения. InputStream будет находиться в контейнере пути к классам JRE. Вы удалили контейнер пути к классам JRE или он может ссылаться на неправильное расположение?
Второй хит при поиске
«отсутствующего типа» входного потока
в google также может быть полезен.
-121--4268310-Возможно, интервьюер ссылался на метод , скрывающий ?
Здесь объявляется метод с той же сигнатурой, что и в базовом классе, но не используется ключевое слово override
(либо потому, что нет, либо нет - как если метод в базовом классе не является виртуальным).
Скрытие метода, в отличие от переопределения , позволяет определить совершенно другой метод - метод, вызываемый только через ссылку на производный класс. При вызове через ссылку на базовый класс вызывается исходный метод в базовом классе.
Не используйте наследование. Он делает общедоступные или защищенные объекты базового класса доступными непосредственно в производном классе, поэтому он вам просто не нужен.
Вместо этого заставьте производный класс реализовать соответствующий интерфейс и (при необходимости) перенаправить методы в частный экземпляр базового класса. То есть используйте композицию (или «агрегацию») вместо наследования для расширения исходного класса.
class firstChild : IFirstOne
{
private baseClass _owned = new baseClass();
public void method1() { _owned.method1(); }
// etc.
}
Кстати, имена классов должны начинаться с заглавной буквы.
Существует 2 решения для скрытия методов, унаследованных от базового класса:
С уважением.
А как насчет внедрения базового класса в качестве 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(); }
}
Внедрение не дает вам нарушить Принцип разделения интерфейса . Чистое наследование означает, что ваш FirstChild
зависит от интерфейса, который он не использует. Если вы хотите сохранить только функциональность IFirst
в Base
, но игнорировать остальную часть, то вы не можете наследовать только от Base
.
Я сделал это, имея 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();
}
}