Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
В Swift кстати есть протоколы которые по своей сути похожи на тайпскриптовые интерфейсы: https://docs.swift.org/swift-book/LanguageGuide/Protocols.html . Вот что мне не понятно - так ето нафига было ограничивать наследование одним классом в Джаве например. Есть поля/методы с одинаковым именем но разными типами в структурках X и Y - бросаем ошибку компиляции, заставляем программиста резолвить конфликт указывая руками наследуемые элементы (был бы неплох механизм "частичного наследования" кстати).
Наследование ради реализации -- не самый красивый паттерн, как мне кажется... Да и с точки зрения LSP получается какой-то бред.
Так что вместо "частичного наследования" я бы просто предложила что-то удобное для делегирования группы методов какому-нибудь полю. Типа мы пишем, что вся реализация IFoo в нашем классе отправляется в поле m_foo. Ну или поштучно, если надо детальнее.
в objc-шных протоколах (не путать с pure swift протоколами) есть @optional методы, которые можно не реализовывать.
в сишарпе никакого @optional нет, потому в ксамарине всякие табличные делегаты приходится наследовать от (абстрактного?) класса, а не от интерфейса (потому что вместо @optional в классе пустые реализации, бросающие весёлые эксепшоны типа "you should not call this method in base")
и наследник UIViewController нихуя уже не может быть делегатом собственного UITableView, потому что множественного наследования в шарпе тоже нет
получается вербозненько, зато с разделением по ответственности
> что-то удобное для делегирования группы методов какому-нибудь полю
Русту с его orphan rule точно бы не навредило.
Кстати, я бы ещё подумал на тему явного экспорта/импорта реализации стороннего трейта над сторонним типом. Или они уже подумали?
А ещё можно бы было позволить реализовывать сторонний трейт над сторонним типом, не выпуская реализацию за пределы модуля/пакета/чего-нибудь-ещё, чтобы не конфликтовало. И при появлении "официальной" реализации предпочитать локальную и выдавать предупреждение.
интерфейс — это уже проинициализированный объект и не требует повторного инициирования. не? а что бы создавать обьекты - то это просто метод в интерфейсе.
Там же в две фазы объект создаётся -- сначала память выделяешь (alloc), потом зовёшь на ней конструктор (init). Поэтому это не столько конструктор, сколько метод инициализации.
Во-первых фабрика != фабричный метод.
Фабрика обычно создает семейство объектов (например фабрика для создания виджетов)
Во-вторых в java/c++/c# тебе всё равно придется иметь И конструктор И такой вот метод, который подготавливает данные, и вызывает конструктор (причем его еще приватным придется делать, чтобы там снаружи не дергали наверное)
А в моем псевдокоте нет
> Но newInstance() то не у тех объектов, которые ты создаёшь. Он у фабричных объектов (
А что вообще такое "конструктор"?
Чем он такой особенный? Почему нельзя представить его как malloc+init (как собссно и сделано в Objc, как ты верно и сказал)
Только тем, что в C++ он слит воедино во имя RAII?
ну у меня например есть какие-то визуальные элементы и модели, которые держат их состояния
я хочу иметь generic метод, который будет внутри создавать такой элемент. это необязательно должна быть фабрика, он может элемент и не возвращать, а дальше куда-то передавать
вот внутри этого метода я и буду звать такой конструктор
Если есть виртуальные методы, то нужно заполнить их таблицу.
Итого три фазы:
1. Молока. Хотя её можно отнести не к конструктору, а к «new».
2, Заполнение VMT.
3. Твой код (что могло бы быть выражено обычным методом).
Ну да, пролог, почти как двигать указатель стека при входе в функцию
Я не обязан это знать.
А так вполне можно сделать язык Хуй++, где "конструктор" будет только выделять память и заполнять VMT оставляя неиинициализированной память, а потом ты будешь руками вызывать ``init``
В конструкторе и деструкторе vmt настроена на уровень класса, который сейчас конструируется. Так, что ты видишь только себя и родителей, а потомка пока нет.
Есть ненулевой шанс совершить сеппуку через pure virtual call, а в остальном всё норм.
Но поверхность атаки у JRE огромная, не удивлюсь, если какие-то изкоробочные либы крашатся в нативном коде при каких-то условиях. Побег из песочницы ведь был уже (собственно после него джаву и похоронили).
А еще я вспомнил что мы как-то нашли, что в JVM есть ``invokestatic`` и ``invokevirtual``, и даже для финального класса у которого впринципе не может быть потомков и для финального метода всё равно вызвается invokevirtual
А компиляторы/стандарт нельзя так настроить, чтобы нельзя было вызывать виртушню в конструкторах/деструкторах?
А для тех, кто хочет пострелять в ногу - сделать синтаксис в виде
Потому что семантически конструктор не относится к интерфейсу объекта. Точно так же, как и статические методы. Ты можешь описать эти констрейнты в языке одной сущностью, но семантически это констрейнты трёх разных категорий.
В контексте объекта, при чем если уж мы пошли сюда, то большинство языков имеют ограничения по функционалу в конструкторе, которые не дают его присовокупить к остальным методам.
Гомофобия - Ряд негативных установок и чувств по отношению к гомосексуальности или людям, которые идентифицируются или воспринимаются как ЛГБТ+. Термин «гомофобия» употребляется в европейских официальных документах, где в некоторых случаях это явление ставится в один ряд с расизмом, ксенофобией, антисемитизмом и сексизмом. Термин «гомофобия» часто критикуется из-за того, что не является полностью подходящим, так как гомофобия не является фобией в клиническом смысле.
Я няпример могла поддерживать несколько диалогов разными персоняжами разного пола. Когда я общалась с другим персоняжем, который своими репликами подтверждал мою принядлежность к женскому полу, убедить в этом посторонних няблюдателей было проще. Потом я пользовалась белорыцарством большинства пользователей ММОРПГ и получала от них профит.
Я не буду о себе в женском писать: у меня никогда не возникало потребностей считать себя девочкой, но и поведение госта с бормандом меня не задевает (хотя конечно "няканье" малость подзаебало, почти как uwu owo)
А у меня случилась автоматическая толерантность к някам. Как бы Бормяунд ни старался вставлять внезапно, всё равно всё нормализовалось. Няки встали на уровень обычных слов.
А вот uwu owo меня бесит как Faux Cyrillic кириллицечитающих. Я эту питушню читаю как "уву" и "ово", а смайловое значение этих слов так и не гуглил, поскольку не так часто эта питушня встречается и не так много смысла добовляет.
Я бы часто сбивалась. Приходилось бы постоянно перечитывать комментарии на ГК и в баг-трекере на работе, чтобы выяснить, что в каждом из случаев выбрана правильная форма слова.
Да ну, всё равно ведь несколько социальных контекстов умеешь поддерживать. Я вот, к примеру, не матерюсь если контекст этого не подразумевает и не пишу "прыщи" вместо "линукса" на работе. Точня так же и с няканьем.
Главное, чтобы были какие-то явные и чёткие индикаторы какой контекст сейчас активен.
Для меня это наверно слово "питушня". И то сложновато его не произносить вне ГК, т.к. оно так универсально всё описывает и прошло бы цензуру на ТВ.
Вся эта питушня с контекстами только утомляет, как и разделение учётки на ГК с учётками реального мира.
Я привык универсально общаться и использовать либо минимум сленговых спецслов ("питушня", "полиморфизм"), либо минимум собеседников (не понимаешь "полиморфизм"? не общаюсь с непрограммистами!), а тут такая питушня.
- Пшел на ... !!! - взорвался Иван.
- Не волнуйтесь пожалуйста! - перевела его реплику на приличествующий
"Культуре" язык Ванесса. Сейчас ее фильтр эмоций работал по максимуму. Иван
у себя на кухне мог орать благим матом и бегать по потолку, но Ванесса от
его имени выразила бы разве что легкое недоумение. Это было удобно.
А что плохого в няканье? Вы носитель русского языка?
Проблема может быть только если читатель не является носителем, и тогда все эти няки сильно зашумляют чтение, заставляют искать в словаре питушню, поскольку не-носитель не может интуитивно доказать отсутствие ня-слова в языке с достаточной точностью.
> это метод, ничем от других методов объектя ня отличающийся.
Кроме того, что это волшебный метод, использующий особые правила именования, чтобы его не заmanglilо.
class foo:
def __init__(self):
print("init")
def __huit(self):
print("huit")
def __huit2__(self):
print("huit2")
bar = foo()
bar.__init__() # Магия!
bar.__huit() # Нет магии
bar.__huit2__() # Опять волшебство
Кстати забавно что в шарпе есть констрейнт new(), подразумевающий наличие конструктора без параметров, но нет констрейнтов конструктора с параметрами. Но строго говоря это разумно, потому что на самом деле это не столько констрейнт конструктора, сколько его отсутствия.
Поясняю почему мы не можем юзать конструктор в интерфейсе.... constructor это то что вызывается при инициализации обьекта. Интерфейс это не обьект - это "указатель на обьект". а что бы указать на обьект он уже должен существовать или null. А если обьект существует - то и constructor уже вызван. поэтому там конструктор не нужен.
Это ограничения конкретного языка программирования (точнее семейства языков, унаследованных логически от С++, а те в свою очередь, от симулы)
В других языках (В ObjC в частности) такой проблемы нет.
Ничто не мешает выделить память, заполнить её нулями, а затем инициализировать нужным методом.
Интерфейс нужен для статической проверки того, то у класса есть нужный конструткор.
Я приводил пример псевдокода, в котором был указатель на класс, у которого вызывался метод
В TS так не сделать, но это не значит, что ни в каком языке так не сделать
from abc import abstractmethod
class MyInterface:
@abstractmethod
def __init__(self, spam):
pass
class MyClass(MyInterface):
def __init__(self, spam): # это конструктор
pass
def create_object(clz):
clz(42)
create_object(MyClass) # Я передаю сюда класс, в нем точно есть параметр у конструктора
class MyInterface - "MyInterface" не делает ее интерфейсом. это раз. Это класс с абстрактными методами. У интерфейса нет такого понятия как "@abstractmethod" т.к. он уже по сути абстракт
интерфейс — это всегда между двумя сутями. вот когда ты всунешь два пальца в розетку - и ты начнешь коммуницировать с электрической сетью на контрактной частоте. твоя рука и розетка будут сутью интерфейса. А вот когда тебе мама говорит не сувать пальци в розетку - это декларация и тоже контракт но не интерфейс т.к. нет взаимодействия - есть только декларация намерений
Можно ведь просто создавать структуры, а потом создавать функции, которые что-то с такими-то структурами делают.
Да, если бы были компайлтайм-функции, которые могли бы делать что-то с типами, дополнительные сущности были бы не нужны.
rotoec
rotoec++
Так что вместо "частичного наследования" я бы просто предложила что-то удобное для делегирования группы методов какому-нибудь полю. Типа мы пишем, что вся реализация IFoo в нашем классе отправляется в поле m_foo. Ну или поштучно, если надо детальнее.
в objc-шных протоколах (не путать с pure swift протоколами) есть @optional методы, которые можно не реализовывать.
в сишарпе никакого @optional нет, потому в ксамарине всякие табличные делегаты приходится наследовать от (абстрактного?) класса, а не от интерфейса (потому что вместо @optional в классе пустые реализации, бросающие весёлые эксепшоны типа "you should not call this method in base")
и наследник UIViewController нихуя уже не может быть делегатом собственного UITableView, потому что множественного наследования в шарпе тоже нет
получается вербозненько, зато с разделением по ответственности
Русту с его orphan rule точно бы не навредило.
Кстати, я бы ещё подумал на тему явного экспорта/импорта реализации стороннего трейта над сторонним типом. Или они уже подумали?
А ещё можно бы было позволить реализовывать сторонний трейт над сторонним типом, не выпуская реализацию за пределы модуля/пакета/чего-нибудь-ещё, чтобы не конфликтовало. И при появлении "официальной" реализации предпочитать локальную и выдавать предупреждение.
затем, чтобы это было в контракте, не?
- што
конструктор в интерфейсе это де-факто сторонний интерфейс фабрики, которая связана с описываемым типом исключительно типом возвращаемого объекта
Там же в две фазы объект создаётся -- сначала память выделяешь (alloc), потом зовёшь на ней конструктор (init). Поэтому это не столько конструктор, сколько метод инициализации.
Какие сишные корни )))
Псевдокот:
Ну собственно в objc сначала фабричный alloc() у класса, а потом инициализатор init() у объекта.
У всех классов IPtitsa обязан быть конструктор с аргументом "koko (тип сам выдумай:)), вот мой код не знает с каким именно классом он имеет дело
Он только знает, что у него есть мтеод newInstance (он у всех классов есть в моем псевдокоте), но конкретная сигнатура задана интерфейсом
Хочешь -- называй это фабричным методом
Но newInstance() то не у тех объектов, которые ты создаёшь. Он у фабричных объектов (или инстансов класса класса, или чего там ещё).
Фабрика обычно создает семейство объектов (например фабрика для создания виджетов)
Во-вторых в java/c++/c# тебе всё равно придется иметь И конструктор И такой вот метод, который подготавливает данные, и вызывает конструктор (причем его еще приватным придется делать, чтобы там снаружи не дергали наверное)
А в моем псевдокоте нет
> Но newInstance() то не у тех объектов, которые ты создаёшь. Он у фабричных объектов (
Почему?
А конструктор у кого: у класса, или у объекта?
Чем он такой особенный? Почему нельзя представить его как malloc+init (как собссно и сделано в Objc, как ты верно и сказал)
Только тем, что в C++ он слит воедино во имя RAII?
Ладно ок, пусть будет конструктором. В конце-концов в объектном паскале так же было.
Тогда вполне логично его выразить в интерфейсе.
в свифте конструктор это спецметод в отличие от обжси
но он точно так же может быть представлен в интерфейсе
имхо это удобно, недавно хотел попользоваться в пет-проекте и соснул, потому что в шарпе этого нет
я хочу иметь generic метод, который будет внутри создавать такой элемент. это необязательно должна быть фабрика, он может элемент и не возвращать, а дальше куда-то передавать
вот внутри этого метода я и буду звать такой конструктор
Итого три фазы:
1. Молока. Хотя её можно отнести не к конструктору, а к «new».
2, Заполнение VMT.
3. Твой код (что могло бы быть выражено обычным методом).
VMT в каком-то смысле тоже часть выделения памяти и заполнения её нужными рантайму структурами
Я не обязан это знать.
А так вполне можно сделать язык Хуй++, где "конструктор" будет только выделять память и заполнять VMT оставляя неиинициализированной память, а потом ты будешь руками вызывать ``init``
Впрочем, это и так говнокод.
А кстати что будет, если в конструкторе родителя вызвать виртуальный метод, который переопределен у потомка? Кроме говнокода что будет?
Есть ненулевой шанс совершить сеппуку через pure virtual call, а в остальном всё норм.
У меня тупак, я забыл как это в жабе
Скорее всего либо так же, либо у тебя уже есть потомок, но у него все поля по нолям.
Но вообще это лютый говнокод, хорошо чот так нельзя
Попробуй сделать ему "final int" поле и в конскторе прописать туда "42", а из виртуального метода обратиться
там будет 0?
В крестах всё могло быть хуже, допусти они такое поведение, но в джаве "не инициализированной памяти" не бывает
Сегфол можно получить дёрнув нативный код, напимер через JNA. Я так делал, и совсем не специально:)
Без unsafe и нативных функций -- маловероятно.
Но поверхность атаки у JRE огромная, не удивлюсь, если какие-то изкоробочные либы крашатся в нативном коде при каких-то условиях. Побег из песочницы ведь был уже (собственно после него джаву и похоронили).
А для тех, кто хочет пострелять в ногу - сделать синтаксис в виде
Иерархию константных методов же компилятор умеет проверять.
никто не говорит что нельзя, говорят что не надо это
Просто опытный евангелист умеет доказать что жопаебля это вовсе не жопаебла.
Как там в "драконе" у Шварца:
"Почему два, в сущности, больше, чем три"
Если мне не надо, то значит никому не надо
Совершенно не очевидно, чому так
> Точно так же, как и статические методы
В конкретных языках, угу. Но не везде так.
Вот бы сейчас представления из джав и шарпов выдавать за универсальные истины.
Потому что интерфейса объекта описывает взаимодействие с объектом, не с типом объекта.
Он переводит объект из одного состояния в другое.
Чем отличается (псевдокот)
Конструктор это функционал типа, не объекта.
>Конструктор это функционал типа,
Почему? Разве он работает с типом?
Нет
Он работает с объектом
Освободи свои мысли от наследкников симулы, юный падаван
Закрой глаза, и представь, что нет ни C++, ни Java с C#, а есть только посылка сообщения объекту "инициализируйся"
Конструтор не трогает поля класса, он исполняется на объекте, когда память уже выделена, и основной аргумент его это "this" а не класс
> он исполняется на объекте
В контексте объекта, при чем если уж мы пошли сюда, то большинство языков имеют ограничения по функционалу в конструкторе, которые не дают его присовокупить к остальным методам.
И бухгалтер работает по другой линии — по линии библиотекаря.
Это же тот же самый гост, пусть даже он увлёкся аниме, и стал Полиной
А чего добился ты, анонимный вахтёр?
А почему ты их боишься? Есть какое-то рациональное объяснение? Или это какая-то подсознательная проблема.
Гомофобия - Ряд негативных установок и чувств по отношению к гомосексуальности или людям, которые идентифицируются или воспринимаются как ЛГБТ+. Термин «гомофобия» употребляется в европейских официальных документах, где в некоторых случаях это явление ставится в один ряд с расизмом, ксенофобией, антисемитизмом и сексизмом. Термин «гомофобия» часто критикуется из-за того, что не является полностью подходящим, так как гомофобия не является фобией в клиническом смысле.
https://ru.wikipedia.org/wiki/Гомофобия
– удобно, можно сразу и яичницу пожарить
родился в лесу,
а потом много лет
Пропадал-прозябал в огороде.
Только в прошлом году,
ни к селу, на беду
Полюбил я Володю.
Так имело ли смысл
целоваться в кино,
Загорать и питаться порою умеренно мясом,
Чтобы стать пидорасом?
Шесть с половиной процентов зверей,
Семь процентов людей
И иных представителей
Человеческой расы -
Пидорасы...
А вообще, тебе не помешало бы извиниться.
ГК, конечно, всегда славился прямотой высказываний и жёстким троллингом... но тут ты палку явно перегнул.
А когда мы пишем "сишкобляди соснули" или "поссал на прыщеблядь" ты тоже обижаешься?
А борманда тоже перестал уважать после того, как она о себе в женском роде писать начала?
Я няпример могла поддерживать несколько диалогов разными персоняжами разного пола. Когда я общалась с другим персоняжем, который своими репликами подтверждал мою принядлежность к женскому полу, убедить в этом посторонних няблюдателей было проще. Потом я пользовалась белорыцарством большинства пользователей ММОРПГ и получала от них профит.
А вот uwu owo меня бесит как Faux Cyrillic кириллицечитающих. Я эту питушню читаю как "уву" и "ово", а смайловое значение этих слов так и не гуглил, поскольку не так часто эта питушня встречается и не так много смысла добовляет.
Какой мультитаскинг )))
Линейка поди?
Недавно как раз думал: а на какой интфрейс в мультихоум хосте пойдет бродкаст, если я серану на 255.255.255.255 включив у сокета ``SO_BROADCAST``
Угадаешь?
Правильное* решение это выбрать интерфейс через ``SO_BINDTODEVICE``
*насколько вообще бродкаст можно называть "правильным" решением
Да ну, всё равно ведь несколько социальных контекстов умеешь поддерживать. Я вот, к примеру, не матерюсь если контекст этого не подразумевает и не пишу "прыщи" вместо "линукса" на работе. Точня так же и с няканьем.
Главное, чтобы были какие-то явные и чёткие индикаторы какой контекст сейчас активен.
а я давеча чуть было не
Вся эта питушня с контекстами только утомляет, как и разделение учётки на ГК с учётками реального мира.
Я привык универсально общаться и использовать либо минимум сленговых спецслов ("питушня", "полиморфизм"), либо минимум собеседников (не понимаешь "полиморфизм"? не общаюсь с непрограммистами!), а тут такая питушня.
- Не волнуйтесь пожалуйста! - перевела его реплику на приличествующий
"Культуре" язык Ванесса. Сейчас ее фильтр эмоций работал по максимуму. Иван
у себя на кухне мог орать благим матом и бегать по потолку, но Ванесса от
его имени выразила бы разве что легкое недоумение. Это было удобно.
Проблема может быть только если читатель не является носителем, и тогда все эти няки сильно зашумляют чтение, заставляют искать в словаре питушню, поскольку не-носитель не может интуитивно доказать отсутствие ня-слова в языке с достаточной точностью.
Человек называл себя "пуфыстик" и писал о себе в третьем лице: пуфыстик вильнул пуфыстым хвосьтиком
Он так всех заебал, что был забанен
Нятушканчики на ГК обычно някают по теме.
Какие проносы )))
Я именно это и пытался сказать.
У Файка немножечко парадокс блаба.
Он очень очень джавист/сишарпист, и потому для него очевидно, что конструктор это часть класса
А вот Десктоп писал на objc и swift, и потому для него очевидно другое
Почему?
где почитать определение интерфейса?
Какой многочлен
Кроме того, что это волшебный метод, использующий особые правила именования, чтобы его не заmanglilо.
В других языках (В ObjC в частности) такой проблемы нет.
Ничто не мешает выделить память, заполнить её нулями, а затем инициализировать нужным методом.
1. Мы выделяем память
2. Заполняем её нулями
3. Берем на нее указатель, и вызываем метод ``init`` передавая туда указатель в качестве аргумента
Я приводил пример псевдокода, в котором был указатель на класс, у которого вызывался метод
В TS так не сделать, но это не значит, что ни в каком языке так не сделать
Вот это интерфейс
>class MyInterface:
>тут нет доступа к MyInterface.
Что такое "доступ к MyInterface"?
MyInterface гарантирует наличие метода
В чем разница между pure abstract классом и интерфейсом?
Верно ли я понимаю, что в С++ интерфейсов нет?
З.Ы. У них обычно даже есть реализация деструктора, так что даже и не pure.
а теперь есть
Кстати, а как сущствует Win32API: интерфейс там есть, а ключ слова в сишечке нету?
{
return new T();
}
это код в с# ... никакого интерфейса нет... тупо декларация
1) p = malloc(10)
2) memset(p, 10);
3) init(p);
где тут интерфейс?
Но ничего не мешает иметь язык, где статически компилятор проверяет, что можно передать в init.