Отвечу обоим. Сказано найти число, которое потерялось. Число, в памяти. Оно еще есть в какой-то ячейке — нужно найти ячейку с этим числом. А что не так с такой интерпретацией?
Скажем так, если бы формулировка была — вычислить, тогда вопросов бы вообще не возникло. Там написано — найти удаленное число. Для меня это двояко.
Ох…
Эти неверные постановки задачи. Первая задача — найдите число. Но не уточнили — нам нужна ссылка на удаленное число в первом списке\массиве или просто значение этого числа. Во втором случае конечно достаточно разницы сумм, но вот я к примеру подумал, что прежде всего по смыслу задачи нужно найти позицию индекс удаленного числа в первом списке, и в этом случае сортировка и линейная сверка один из оптимальных и быстрейших решений.
Лучше вы скажите, почему вы не согласны?
Это вопрос того же уровня, как нужен ли контроль за монополией, или нужны ли патенты\авторское право.
Как человек, любящий свободу, я считаю что искуственное ограничение монополий, право на забвение, патенты и авторское право — вмешательство в свободу слова и действий. Казалось бы, не нравится монополия — откройте конкурента по соседству, не нравится что кто-то копирует ваши изобретения — не изобретайте, но оставьте людям свободу копировать, распространять, владеть и распоряжаться.
Как дальновидный человек, я все же понимаю, что без искуственного контроля может быть хуже, а не лучше. Монополии действительно надо контролировать, авторское право и патенты в чем-то полезны. Также и право на забвение — в конце концов, пока человек или его потомки живы, любая связанная с ними информация относится к их частной жизни, и соответственно логично на государственном уровне давать им право контролировать зоны распространения такой информации.
Все просто, Google придется решать, в какой стране оставаться, а в какой нет.
Он и сейчас может совершенно спокойно решать — принять условия Канады, или закрыть свое юридическое лицо в Канаде. Думаю, второму варианту канадцы будут рады не очень.
Смотрите, если у объекта Окно будет функция открытьДверь, а у Двери функция открытьЖалюзиОкна, т.е. бессвязная мешанина данных и функций, и нет такого, что группе функций сопоставляется один объект, я не распознаю ООП.
А вот объединение функций в группы — и есть инкапсуляция. В любом коде с объектом и методами будет инкапсуляция.
Предпочитать композицию хорошо, но что делать, если уже есть компонент VelocityComponent, и нам нужен (правда правда, мы в игре совершенствуем физику, и нам нигде не нужен VelocityComponent, зато нужен будет SuperVelocityComponent. И вот здесь, в терминах композиции я буду вынужден с нуля описывать SuperVelocityComponent, или как-то хитрить, и делать объект, у которого VelocityComponent это поле, и он просто проксирует через свои методы все все методы этого компонента, но суть будет все равно в том, что для правильной архитектуры нам будет нужно наследование для такой операции. Вы можете искуственно ограничить себя и сказать — без наследования все равно ООП но мне правда кажется что нет. То есть вот она, программа — код написан, и он работает, но именно из за отсутствия возможности расширять код дальше через наследование — убивает для меня объектную природу этого кода. Она становится компонентной, если позволите.
Полиморфизм. Интерфейсы. Можно ли назвать таблицу с функциями полиморфизмом? Нет, ведь таблицы бывают разные, но та таблица с функциями, которая в зависимости от типа отдает разные функции — реализация полиморфизма с одним аргументом.
Очевидно, они не ООП.
Но вообще-то, поддержка инкапсуляции на уровне компилятора совершенно не обязательна. Достаточно code style нотации — к примеру ставить __ перед приватными членами и методами.
Конечно.
Она перестанет быть ОО, если в паблик попадут скрытые методы и данные, т. к. в процессе написания кода разработчик справедливо будет использовать публичные функции и данные, которые для этого не предназначены, и полезут UB.
Не нравится, честно честно.
Нравится разбираться и искать истину. Дух сообщения не в инкапсуляции же был, а в том, что она — действительно ключевой момент ООП, а shared state — вообще не момент из ООП, и никак к нему не относится.
Они ломают голову над нюансами. Так всегда происходит, когда определение чего-то допускает расширения. Вот вам пример — web 2.0. В свое время у каждого в голове было чуть ли не свое видение web 2.0, однако именно ключевые концепции были известны.
Формально точного определения ООП не существует, и да простите меня за новую цитату с ненадежной вики, но непосредственно ключевые, необходимые и достаточные моменты для ООП известны и точны:
«Ключевые черты ООП хорошо известны:
Первая — инкапсуляция — это определение классов — пользовательских типов данных, объединяющих своё содержимое в единый тип и реализующих некоторые операции или методы над ним. Классы обычно являются основой модульности, инкапсуляции и абстракции данных в языках ООП.
Вторая ключевая черта, — наследование — способ определения нового типа, когда новый тип наследует элементы (свойства и методы) существующего, модифицируя или расширяя их. Это способствует выражению специализации и генерализации.
Третья черта, известная как полиморфизм, позволяет единообразно ссылаться на объекты различных классов (обычно внутри некоторой иерархии). Это делает классы ещё удобнее и облегчает расширение и поддержку программ, основанных на них.
Инкапсуляция, наследование и полиморфизм — фундаментальные свойства, которыми должен обладать язык, претендующий называться объектно-ориентированным (языки, не имеющие наследования и полиморфизма, но имеющие только классы, обычно называются основанными на классах).»
И я с этими ключевыми моментами абсолютно согласен. И категорически не согласен, что изменяемые данные — это свойство или необходимый ключевой момент для ООП.
И снова та же ошибка.
«Но ООП — это по определению именно изменяемое состояние.»
Нет же. ООП не требует изменяемого состояния. Методы объекты могут возвращать что им угодно.
"(считается анти-паттерном проповедниками ООП, они даже придумали унизительное название «анемичная модель данных»)."
Я не знаю этих людей, и почему они называют себя проповедниками ООП, но поверьте, к ООП эта идея не имеет никакого отношения.
«ООП по определению — это именно изменяемое состояние, это симуляция реальных объектов путем обмена сообщениями»
Вот именно с этим заблуждением и боролся мой первый комментарий.
из вики
«Объе́ктно-ориенти́рованное программи́рование (ООП) — методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определенного класса[1], а классы образуют иерархию наследования[2][3].»
В определении все хорошо — от программы требуют писать все в объектах, их методах, взаимосвязь типов обязуют делать через наследование.
Есть и другое определение, что ООП — это наследование, инкапсуляция и полиморфизм.
Ни в одном из определений вы никогда не встретите требования иметь изменяемые данные.
Простите, но у вас есть ошибка.
«ООП — изменяемые переменные»
Вовсе нет. ООП не требует изменяемых переменных, только инкапсуляцию, наследование и полиморфизм.
Простите, если неверно подал мысль, я не говорил что ФП = ООП, я говорил что ООП и ФП это паттерны разных категорий, и они могут существовать вместе, а значит не противопоставляются.
Я искренне хочу помочь людям правильно понимать ООП и то, как он правильно сочитается с ФП.
Многое ниже будет очевидно.
Верно, неправильно применяя ООП, можно добиться невероятных приключений в разработке и поддержке кода.
На самом деле, ООП — это наследование, полиморфизм и инкапсуляция.
Если по простому — ООП это паттерн, в котором у функций есть первый аргумент, олицетворяющий this, (self, не важно), некий объект, являющийся логическим центром обработки. Эта функция не обязана менять состояние объекта, она может быть и const и pure.
Если в вашем ФП коде есть методы аля updateUser и removeUser, которые принимают первым аргументом один и тот же тип объекта — это ООП.
Вот так просто, есть объекты и их методы. Все остальное — не ОО функции.
Конечно, мало просто иметь функции с одинаковым первым аргументом, это еще не полноценное ООП.
1) Наследование. Единственное требование для наследования — возможность статически переопределять метод объекта, порождая новый тип так, чтобы в новом типе работали все предыдущие методы объекта.
Это значит, что ваш updateUser и removeUser не ОО, потому что нельзя как-то создать новый тип User2, чтобы с ним updateUser вел себя иначе. Функции должны вызываться от типа. Как видите, это не связано с shared state, это лишь паттер — кладите функции внутрь типа, чтобы при наследовании типов одно и то же имя функции вело себя по разному.
2) Полиморфизм. Это про то, что одно и то же имя функции будет вызывать разные функции для объектов, чей тип заранее _неизвестен_. Это опять же не связано с shared state, это ровно про то, что — у вас есть интерфейс, и разные типы могут реализовывать его по разному.
3) Инкапсуляция. Это вообще и про ФП и про ОО. Есть ряд данных и функций, которые мы хотим скрыть от публичного интерфейса. Повесить на них ярлык — эти вещи не для внешнего использования, эти функции можно использовать только внутри определенных функций. Классический пример — функции, начинающиеся с _ или __
__updateUser — скрытая функция, предназначенная для системы работы с пользователями, но никакая другая система не вправе вызывать эту функцию.
updateUser — публичная функция, предназначенная для вызова из любой системы.
Так или иначе, в любом — ФП, процедурном стиле — мы используем ООП, не замечая этого. ООП не про объекты — ООП про абстракцию в виде объектов, их методов и того как эти методы должны работать, переопределяться и быть доступны\недоступны в этом контексте.
ООП не альтернатива функциональному подходу, это большой паттерн, который прекрасно сочетается с функциональным стилем. Shared mutable state появляется тогда, и только тогда, когда разработчик сам его создает.
Скажем так, если бы формулировка была — вычислить, тогда вопросов бы вообще не возникло. Там написано — найти удаленное число. Для меня это двояко.
Эти неверные постановки задачи. Первая задача — найдите число. Но не уточнили — нам нужна ссылка на удаленное число в первом списке\массиве или просто значение этого числа. Во втором случае конечно достаточно разницы сумм, но вот я к примеру подумал, что прежде всего по смыслу задачи нужно найти позицию индекс удаленного числа в первом списке, и в этом случае сортировка и линейная сверка один из оптимальных и быстрейших решений.
Это вопрос того же уровня, как нужен ли контроль за монополией, или нужны ли патенты\авторское право.
Как человек, любящий свободу, я считаю что искуственное ограничение монополий, право на забвение, патенты и авторское право — вмешательство в свободу слова и действий. Казалось бы, не нравится монополия — откройте конкурента по соседству, не нравится что кто-то копирует ваши изобретения — не изобретайте, но оставьте людям свободу копировать, распространять, владеть и распоряжаться.
Как дальновидный человек, я все же понимаю, что без искуственного контроля может быть хуже, а не лучше. Монополии действительно надо контролировать, авторское право и патенты в чем-то полезны. Также и право на забвение — в конце концов, пока человек или его потомки живы, любая связанная с ними информация относится к их частной жизни, и соответственно логично на государственном уровне давать им право контролировать зоны распространения такой информации.
Он и сейчас может совершенно спокойно решать — принять условия Канады, или закрыть свое юридическое лицо в Канаде. Думаю, второму варианту канадцы будут рады не очень.
А вот объединение функций в группы — и есть инкапсуляция. В любом коде с объектом и методами будет инкапсуляция.
Предпочитать композицию хорошо, но что делать, если уже есть компонент VelocityComponent, и нам нужен (правда правда, мы в игре совершенствуем физику, и нам нигде не нужен VelocityComponent, зато нужен будет SuperVelocityComponent. И вот здесь, в терминах композиции я буду вынужден с нуля описывать SuperVelocityComponent, или как-то хитрить, и делать объект, у которого VelocityComponent это поле, и он просто проксирует через свои методы все все методы этого компонента, но суть будет все равно в том, что для правильной архитектуры нам будет нужно наследование для такой операции. Вы можете искуственно ограничить себя и сказать — без наследования все равно ООП но мне правда кажется что нет. То есть вот она, программа — код написан, и он работает, но именно из за отсутствия возможности расширять код дальше через наследование — убивает для меня объектную природу этого кода. Она становится компонентной, если позволите.
Полиморфизм. Интерфейсы. Можно ли назвать таблицу с функциями полиморфизмом? Нет, ведь таблицы бывают разные, но та таблица с функциями, которая в зависимости от типа отдает разные функции — реализация полиморфизма с одним аргументом.
Но вообще-то, поддержка инкапсуляции на уровне компилятора совершенно не обязательна. Достаточно code style нотации — к примеру ставить __ перед приватными членами и методами.
Она перестанет быть ОО, если в паблик попадут скрытые методы и данные, т. к. в процессе написания кода разработчик справедливо будет использовать публичные функции и данные, которые для этого не предназначены, и полезут UB.
Нравится разбираться и искать истину. Дух сообщения не в инкапсуляции же был, а в том, что она — действительно ключевой момент ООП, а shared state — вообще не момент из ООП, и никак к нему не относится.
Формально точного определения ООП не существует, и да простите меня за новую цитату с ненадежной вики, но непосредственно ключевые, необходимые и достаточные моменты для ООП известны и точны:
«Ключевые черты ООП хорошо известны:
Первая — инкапсуляция — это определение классов — пользовательских типов данных, объединяющих своё содержимое в единый тип и реализующих некоторые операции или методы над ним. Классы обычно являются основой модульности, инкапсуляции и абстракции данных в языках ООП.
Вторая ключевая черта, — наследование — способ определения нового типа, когда новый тип наследует элементы (свойства и методы) существующего, модифицируя или расширяя их. Это способствует выражению специализации и генерализации.
Третья черта, известная как полиморфизм, позволяет единообразно ссылаться на объекты различных классов (обычно внутри некоторой иерархии). Это делает классы ещё удобнее и облегчает расширение и поддержку программ, основанных на них.
Инкапсуляция, наследование и полиморфизм — фундаментальные свойства, которыми должен обладать язык, претендующий называться объектно-ориентированным (языки, не имеющие наследования и полиморфизма, но имеющие только классы, обычно называются основанными на классах).»
И я с этими ключевыми моментами абсолютно согласен. И категорически не согласен, что изменяемые данные — это свойство или необходимый ключевой момент для ООП.
«Но ООП — это по определению именно изменяемое состояние.»
Нет же. ООП не требует изменяемого состояния. Методы объекты могут возвращать что им угодно.
"(считается анти-паттерном проповедниками ООП, они даже придумали унизительное название «анемичная модель данных»)."
Я не знаю этих людей, и почему они называют себя проповедниками ООП, но поверьте, к ООП эта идея не имеет никакого отношения.
«ООП по определению — это именно изменяемое состояние, это симуляция реальных объектов путем обмена сообщениями»
Вот именно с этим заблуждением и боролся мой первый комментарий.
из вики
«Объе́ктно-ориенти́рованное программи́рование (ООП) — методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определенного класса[1], а классы образуют иерархию наследования[2][3].»
В определении все хорошо — от программы требуют писать все в объектах, их методах, взаимосвязь типов обязуют делать через наследование.
Есть и другое определение, что ООП — это наследование, инкапсуляция и полиморфизм.
Ни в одном из определений вы никогда не встретите требования иметь изменяемые данные.
«ООП — изменяемые переменные»
Вовсе нет. ООП не требует изменяемых переменных, только инкапсуляцию, наследование и полиморфизм.
Простите, если неверно подал мысль, я не говорил что ФП = ООП, я говорил что ООП и ФП это паттерны разных категорий, и они могут существовать вместе, а значит не противопоставляются.
Многое ниже будет очевидно.
Верно, неправильно применяя ООП, можно добиться невероятных приключений в разработке и поддержке кода.
На самом деле, ООП — это наследование, полиморфизм и инкапсуляция.
Если по простому — ООП это паттерн, в котором у функций есть первый аргумент, олицетворяющий this, (self, не важно), некий объект, являющийся логическим центром обработки. Эта функция не обязана менять состояние объекта, она может быть и const и pure.
Если в вашем ФП коде есть методы аля updateUser и removeUser, которые принимают первым аргументом один и тот же тип объекта — это ООП.
Вот так просто, есть объекты и их методы. Все остальное — не ОО функции.
Конечно, мало просто иметь функции с одинаковым первым аргументом, это еще не полноценное ООП.
1) Наследование. Единственное требование для наследования — возможность статически переопределять метод объекта, порождая новый тип так, чтобы в новом типе работали все предыдущие методы объекта.
Это значит, что ваш updateUser и removeUser не ОО, потому что нельзя как-то создать новый тип User2, чтобы с ним updateUser вел себя иначе. Функции должны вызываться от типа. Как видите, это не связано с shared state, это лишь паттер — кладите функции внутрь типа, чтобы при наследовании типов одно и то же имя функции вело себя по разному.
2) Полиморфизм. Это про то, что одно и то же имя функции будет вызывать разные функции для объектов, чей тип заранее _неизвестен_. Это опять же не связано с shared state, это ровно про то, что — у вас есть интерфейс, и разные типы могут реализовывать его по разному.
3) Инкапсуляция. Это вообще и про ФП и про ОО. Есть ряд данных и функций, которые мы хотим скрыть от публичного интерфейса. Повесить на них ярлык — эти вещи не для внешнего использования, эти функции можно использовать только внутри определенных функций. Классический пример — функции, начинающиеся с _ или __
__updateUser — скрытая функция, предназначенная для системы работы с пользователями, но никакая другая система не вправе вызывать эту функцию.
updateUser — публичная функция, предназначенная для вызова из любой системы.
Так или иначе, в любом — ФП, процедурном стиле — мы используем ООП, не замечая этого. ООП не про объекты — ООП про абстракцию в виде объектов, их методов и того как эти методы должны работать, переопределяться и быть доступны\недоступны в этом контексте.