2016-07-08 2 views
0

Я знаю, что вопрос запутан, но трудно подумать о хорошем заголовке для этой проблемы, поэтому я опишу здесь еще раз.C# Есть ли способ, которым мой базовый класс и производный класс могут реализовывать интерфейсные методы отдельно?

У меня есть интерфейс А с 2-мя методами, IsValidRow() и IsFileValid() у меня есть базовый класс B и производный класс С Цель здесь состоит в том, что я хочу, это базовый класс для реализации IsFileValid(), поэтому он может быть унаследован всеми классы, полученные из базового класса и каждого производного класса для реализации IsValidRow().

Проблема в том, что IsFileValid() звонки IsValidRow() внутри. Если я

B:A 

IsValidRow() требует, чтобы быть реализован в В.

В настоящее время мой производный класс C наследует от базового класса и интерфейса атм.

Я не возражаю против реструктуризации всего, пока выполняются требования к двум методам (один будет реализован один раз в базовом классе или что-то еще и наследует, а другой будет реализован в каждом производном классе)

interface IFileValidator 
{ 
    Pair<bool, string> IsValidRow(List<string> row); 

    bool IsFileValid(string file); 
} 

class FileValidator : IFileValidator 
{ 
    public bool IsFileValid(string file) 
    { 
     // calls IsValidRow() 
     IsValidRow(); 
    } 
} 

class FacilitiesCalendarValidator : FileValidator, IFileValidator 
{ 

    public Pair<bool, string> IsValidRow(List<string> row) 
    { 
      //stuff 
    } 
} 
+1

Если 'B' объявлен как' abstract', я не думаю, что он должен предоставить реализацию для всех методов, даже если они приходят от интерфейса. –

ответ

4

Возможно в обоих случаях.

Для необязательно переопределяемых методов объявите методы базового класса как virtual и override в дочернем классе.

Для методов, которые должны иметь реализацию, предоставленную дочерним классом, отметьте класс и метод как abstract.

Вам не нужно переопределять метод virtual в дочернем классе, поэтому реализация наследуется, если вы явно не решите override.

Например:

interface IInterface 
{ 
    int Transform(int a, int b); 
    int AnotherTransform(int a, int b); 
} 

abstract class A : IInterface 
{ 
    public virtual int Transform(int a, int b) 
    { 
     return a + b; 
    } 

    public abstract int AnotherTransform(int a, int b); 
} 

class B : A 
{ 
    public override int Transform(int a, int b) 
    { 
     return a - b; 
    } 

    public override int AnotherTransform(int a, int b) 
    { 
     return a * b; 
    } 
} 
+0

Похоже, что OP также необходимо сделать абстрактное представление класса/метода, вы можете также добавить эту информацию. – Luaan

+0

Не уверен, что он делает, поскольку он специально не сказал, что B не должен быть реанимированным. ;) Однако ему нужно прояснить вопрос о 'IsValidRow()', поскольку он читает так, как будто он говорит, что он должен быть реализован в дочернем классе, а не опционально реализован. – toadflakz

+0

Mmm. для класса A, что, если я не намерен реализовывать что-либо в Transform(), я буду использовать Transform() только в классе B? Я имею в виду, что я мог видеть, как я возвращаю мусор в виртуальном методе базового класса и переопределяю его во всех полученных – ygongdev

0

Вы можете отметить метод IsValidRow(), как abstract:

namespace test 
{ 
    interface A 
    { 
     bool IsFileValue(); 
     bool IsValidRow(); 
    } 

    abstract class B : A 
    { 
     public bool IsFileValue() 
     { 
      return IsValidRow(); 
     } 

     public abstract bool IsValidRow(); 
    } 

    class C : B 
    { 
     public override bool IsValidRow() 
     { 
      return true; 
     } 
    } 
} 
0

У меня есть решение для вас использовать принцип интерфейс сегрегация. что это означает, объявить два interfaces. Первые из них имеет один метод, который является IsFileValid() и второй интерфейс реализации первого интерфейса и имеет другой метод, который является IsFileValid() как этого

Interface A { void IsFileValid(); } 
    Interface B : A { void IsValidRow();} 

и базовый класс реализует интерфейс A и все производные классы реализуют интерфейс B как это.

public class Base : A 
{ 
     void IsFileValid(){ // immplementaion details} 
} 

public class Child : Base, B 
{ 
     void IsValidRow(){// immplementaion details}  
} 

Счастливый Coding

+0

Это не решит проблему OP, так как базовому классу нужно вызвать 'IsValidRow', но реализовать его в дочернем классе. –

+0

Да, вы правы, но я думаю, он говорит, что ему нужно вызвать IsValidRow только из дочерних классов. –

+0

Нет OP утверждает, что 'IsValidRow' вызывается из' IsFileValid' и этот базовый класс реализует 'IsFileValid', а дочерний класс реализует' IsValidRow' –

Смежные вопросы