Здравствуйте, Sinclair, Вы писали:
S>Возьмите в качестве интерфейса что-нибудь поинтереснее — например, пару из NeutralElement и Combine:
S>S>public interface IGroup<T>
S>{
S> public T NeutralElement {get;}
S> public T Combine(T a, T b)
S>}
S>public class IntAddition: IGroup<int>
S>{
S> public int NeutralElement { get => 0; }
S> public int Combine(int a, int b) => a + b;
S>}
S>public static class H
S>{
S> public static T Reduce<T>(this IEnumerable<T> input, IGroup<T> group)
S> {
S> var r = group.NeutralElement;
S> foreach(var i in input)
S> r = group.Combine(r, i);
S> return r;
S> }
S>}
S>public static class Program
S>{
S> public static void Main()
S> {
S> var t = new[] {4, 8, 15, 16, 23, 42};
S> var sum = t.Reduce(new IntAddition());
S> }
S>}
S>
S>Вот вам ООП подход.
Замечу, что здесь нет изменяемого состояния.
S>Вот как раз тут видно, почему ООП без изменяемого состояния — "не ООП".
Мне видно противоречие. Ваш вывод для меня неубедителен.
На первый взгляд в ООП инкапсуляция явно противоречит иммутабельности. Но на самом деле это чисто технический момент. Следующий код с изменяемым состоянием
class MyObject {
int _v;
public: void setField(int v) { _v = v; }
};
легко преобразуется в иммутабельный
class MyObject {
int _v;
public: MyObject setField(int v)&& { this->_v = v; return *this; }
}
да, такой код не очень идиоматичен. Но чисто технически он иммутабельность убирает. В языках типа С# и Java конечно такое тяжело (нет move семантики), но начиная с С++ и Rust так извращаться уже можно. В данном случае ограничения языков не должны вводить в заблуждение относительно ограниченности ООП. В ООП стиле можно писать даже иммутабельно