2016-12-04 2 views
4

Лиск принцип замещения (LSP) говорят:Лиск замены, предпосылка и абстрактные методы

Предпосылки не могут быть усиленны в подтипе.

В C#, я мог нарушить весь принцип следующим образом:

public class A 
{ 
     public virtual void DoStuff(string text) 
     { 
      Contract.Requires(!string.IsNullOrEmpty(text)); 
     } 
} 

public class B : A 
{ 
     public override void DoStuff(string text) 
     { 
      Contract.Requires(!string.IsNullOrEmpty(text) && text.Length > 10); 
     } 
} 

Но что произойдет, если A.DoStuff бы abstract метод:

public class A 
{ 
     public abstract void DoStuff(string text); 
} 

public class B : A 
{ 
     public override void DoStuff(string text) 
     { 
      Contract.Requires(!string.IsNullOrEmpty(text)); 
     } 
} 

Теперь A.DoStuff является contractless. Или его контракт составляет всего все разрешено.

+0

'A.DoStuff' не имеет предопределения, в то время как' B.DoStuff' делает так, что вы его укрепили. – Lee

+0

@Lee Обсуждение могло бы состоять в том, что абстрактный метод, являющийся просто * метаданные *, не мог считаться не предусловием, потому что, поскольку он не имеет поведения, тот факт, что он не обеспечивает предварительное условие, не должен означать, что * у него нет предварительных условий *. Я считаю, что это простой случай, но может потребоваться комплексный анализ, чтобы определить, действительно ли он нарушает LSP ... –

+0

@InBetween, почему вы отбросили свой ответ? –

ответ

1

Да, вы можете легко разбить принцип, не только на C#.

Он только говорит:

Подтип Требование: Пусть фи (х) свойство доказуемо об объектах х типа T. Тогда фита (у) должно быть справедливо и для объектов у типа S где S является подтипом Т.

В вашем примере типа B не отвечает свойство предлагает метод DoStuff, который работает с короткими текстами, несмотря на супертипе А его исполнение. Таким образом, принцип нарушается.

Это касается программиста, который поддерживает принцип. Свойство также может быть «оно делает правильное дело», которое вы легко можете сломать, имея подтип с неправильной реализацией метода.

+0

Ну, я сказал C#, потому что я хотел представить фрагмент кода, используя C#! :) –

+0

Ум, когда вы говорите о моем примере, думаете ли вы об абстрактном случае? –

+0

Я бы сказал, что для абстрактного класса нет объектов. Таким образом, принцип не применяется. – fafl

0

Я бы сказал, что это не так. Абстрактный метод по определению не имеет никаких предварительных условий, поскольку реализация отсутствует. Было бы так же, как утверждать, что реализация интерфейса прерывает LSP.

Высказывание A.DoSomething() является непревзойденным, является неправдой. A.DoSomehing() не определено, поэтому у него не может быть контракта, кроме его подписи.

+0

Я считаю, что ваш ответ вводит хороший момент, чтобы перейти в правильное направление, когда вы сравниваете методы абстрактного и интерфейса. –

2

В зависимости от: что определяет контракт.

LSP - теоретическая конструкция, она не зависит от конкретного языка или реализации, например, от функции COD «Контракты кода» C#.

Договор может быть определен следующим образом:

  • имя метода
  • имен
  • метод параметров
  • метод комментария
  • возвращаемый тип и типы параметров метода
  • «явный» контракты, такие как Contract.Requires

На последних двух будет проверено компилятором. Тем не менее, первые три могут быть частью контракта! Рассмотрим следующий пример:

public interface StuffContainer 
{ 
    void Add(string text); 

    // Removes a string that has previously been added. 
    void Remove(string text); 
} 

Название и документация метода Remove определить четкую предпосылку. Проверка в реализации, которую ранее удалялась строка, которая была удалена, не нарушает LSP. Проверка того, что строка имеет не менее 5 символов, будет нарушать LSP.

+0

Обратите внимание, что я хотел объяснить всю озабоченность контрактами на C# и код, чтобы просто обсудить тему, основанную на фактическом образце. –

+0

В любом случае, ваш вердикт в том, что весь случай, который я объяснил в моем вопросе, не обязательно будет нарушать LSP? –

+0

@ MatíasFidemraizer: Если ваш метод действительно называется 'DoStuff' и не имеет дополнительной документации, то да, он нарушает LSP (как ваш первый, так и второй пример). Если ваш метод на самом деле называется 'DoStuffOnLongString', и вы где-то определили, что« длинная строка »- это строка с более чем 10 символами, то нет, LSP не был нарушен (ни в первом, ни во втором примере). – Heinzi

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