1 / 1 / 0
Регистрация: 02.04.2022
Сообщений: 1
|
|
1 | |
Множественное наследование02.04.2022, 19:05. Показов 2207. Ответов 28
Здравствуйте, объясните пожалуйста вкратце, что такое комбинирование методов в clos, что может стоять за понятием "обход соседей" и как работает call next method. Желательно объяснить как это работает в концепции множественного наследования и как в lisp разрешается проблема ромба
1
|
02.04.2022, 19:05 | |
Ответы с готовыми решениями:
28
Теоретико-множественное объединение множеств элементов Множественное число для английского слова Функция (f W), вычисляющая множественное число для английского слова Множественное число английских существительных Множественное наследование |
4486 / 2721 / 485
Регистрация: 28.04.2012
Сообщений: 8,590
|
|||||||||||
03.04.2022, 08:16 | 2 | ||||||||||
Сообщение было отмечено BetirovArtur как решение
Решение
BetirovArtur, рекомендую глянуть Art of Metaobject Protocol, ЕМНИП, там основы описаны.
Вот ещё полезная ссылка: http://www.lispworks.com/docum... 07_ffd.htm Если вкратце, то комбинация методов позволяет указать способ решения проблемы ромба. Например имеем – класс A с методом foo – класс B с методом foo – класс R, наследуемый от A и B, но не переопределяющий метод foo Тогда, если в качестве комбинации указать +, то при вызове метода foo на объекте класса R, будут вызваны методы A.foo и B.foo их их результаты будут суммированы. Кажется, в книге On Lisp был примерно такой пример:
Или, например комбинация progn — просто выполнит методы последовательно:
:precedence-order в defgeneric, но там немного не так очевидно, как может показаться, ЕМНИП.Не, попутал, этот параметр за другой порядок отвечает. В общем, прям «вкратце» объяснить всё равно не получиться, читай документацию.
2
|
Нарушитель
79 / 75 / 16
Регистрация: 12.01.2022
Сообщений: 901
|
|
03.04.2022, 14:12 | 3 |
короче просто происходит перегрузка оператора.
в расте это гораздо удобнее реализовано, как мне кажется, и без всяких классов. Добавлено через 17 минут ща глянул - не, нехрна не удобнее
1
|
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
|
03.04.2022, 14:39 | 4 |
Совсем нет, "+" в смысле комбинации методов и "+" в смысле сложения просто одинаково называются. Комбинация методов "+" - это когда для данной генеричной функции при вызове её метода складываются результаты вызовы методов, соответствующим классам предков. Не знаю, в каком ещё языке такое есть. Обычно, когда вызываешь метод, можно вызвать родительский метод, получить его значение. Но так, чтобы сами собой складывались значения всех родительских методов - я такое не знаею.
А функцию сложения перегружать нельзя, она не генеричная. Онтопик: это очень обширные вопросы. Плюсую про документацию. По поводу ромба - например, пусть вызов (foo a). У класса аргумента может быть много предков, которые образуют ориентированный граф. Циклов в нём нет, потому что циклическое наследование запрещено. Весь этот граф линейно упорядочивается топологической сортировкой, и call-next-method выбирает методы вдоль этой линейно упорядоченной цепочки. То есть ромб "уплощается".
2
|
4486 / 2721 / 485
Регистрация: 28.04.2012
Сообщений: 8,590
|
|
03.04.2022, 14:55 | 5 |
0
|
4486 / 2721 / 485
Регистрация: 28.04.2012
Сообщений: 8,590
|
||||||
03.04.2022, 16:25 | 7 | |||||
Оператор сложения (а точнее функция) тут не при чём и он никаким образом не перегружается. Он используется как комбинатор.
Добавлено через 21 минуту Нет, не так. В Rust же нет множественного наследования. https://onlinegdb.com/awmcOFMOI Код
/****************************************************************************** Online Rust Compiler. Code, Compile, Run and Debug Rust program online. Write your code in this editor and press "Run" button to execute it. *******************************************************************************/ trait HasWeight { fn weight(&self) -> u32; } struct Cat {} impl HasWeight for Cat { fn weight(&self) -> u32 { 42 } } struct Dog {} impl HasWeight for Dog { fn weight(&self) -> u32 { 9001 } } struct CatDog { cat: Cat, dog: Dog, } impl HasWeight for CatDog { fn weight(&self) -> u32 { self.cat.weight() + self.dog.weight() } } fn main() { let dog = Dog{}; let cat = Cat{}; let catdog = CatDog{ cat: Cat{}, dog: Dog{} }; println!("{}", cat.weight()); println!("{}", dog.weight()); println!("{}", catdog.weight()); }
1
|
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
|||||||||||
03.04.2022, 17:03 | 8 | ||||||||||
Раст не знаю.
Может, без множественного наследования будет понятней:
Тут, наверно, первый вопрос, который приходит в голову - зачем??? Вот пример использования комбинации append (работает как +, но объединяет списки вместо сложения чисел) для сериализации в список:
1
|
Нарушитель
79 / 75 / 16
Регистрация: 12.01.2022
Сообщений: 901
|
|
03.04.2022, 21:01 | 9 |
там его вообще нет, так как нет классов.
это почти то же самое, что и я написал, только я использовал уже готовый трейт и общую структуру не создавал. Добавлено через 1 час 2 минуты helter, ясно. просто в других языках это называется перегрузкой операторов. то же самое - объединяет вектора методом append, но при этом мы используем оператор сложения тут
0
|
4486 / 2721 / 485
Регистрация: 28.04.2012
Сообщений: 8,590
|
||||||
03.04.2022, 21:21 | 10 | |||||
Это совсем не то же самое.
Нет, это не имеет никакого отношения к перегрузке операторов. Вот тебе другой язык, C++:
Код
<source>: In function 'int square(int)': <source>:22:25: error: request for member 'weight' is ambiguous 22 | std::cout << catDog.weight() << std::endl; | ^~~~~~ <source>:13:17: note: candidates are: 'virtual int Dog::weight()' 13 | virtual int weight() { | ^~~~~~ <source>:6:17: note: 'virtual int Cat::weight()' 6 | virtual int weight() { | ^~~~~~ Compiler returned: 1 При чём тут перегрузка операторов? Как ты решишь эту проблему перегрузкой операторов? Вернёмся к моему примеру на Rust: Код
... fn printWeights(xs: Vec<&dyn HasWeight>) { for x in xs.iter() { println!("{}", x.weight()); } } fn main() { let cat = Cat{}; let dog = Dog{}; let catdog = CatDog{ cat: Cat{}, dog: Dog{} }; let mut pets: Vec<&HasWeight> = Vec::new(); pets.push(&cat); pets.push(&dog); pets.push(&catdog); printWeights(pets); } Напиши такую же функцию printWeights со своей перегрузкой операторов.
0
|
Нарушитель
79 / 75 / 16
Регистрация: 12.01.2022
Сообщений: 901
|
|
03.04.2022, 21:57 | 11 |
0
|
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
|
03.04.2022, 22:43 | 12 |
Нет. Какой тут оператор, по-вашему, перегружается? Вы можете написать на каком-нибудь языке пример, аналогичный моему с c1, c2, c3, чтобы (new C3()).foo() возвращало бы 6?
0
|
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
|
04.04.2022, 00:53 | 14 |
Это не очень близкая аналогия.
1. Композиция, а не наследование. 2. У меня - три класса, здесь - четыре структуры. 3. Главное отличие, в котором суть комбинации методов: комбинация методов автоматически обходит родительские классы, а здесь сумма прописана руками. Добавлено через 11 минут Кстати, при тех же определениях (foo (make-instance 'c2)) вернёт 3 = 2 + 1.
1
|
Нарушитель
79 / 75 / 16
Регистрация: 12.01.2022
Сообщений: 901
|
|
04.04.2022, 12:31 | 15 |
helter, ну так вопрос какой был?
а как это будет сделано - не важно) так тоже можно сделать
0
|
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
|
04.04.2022, 13:05 | 16 |
Сообщение было отмечено BetirovArtur как решение
Решение
Важно имитировать структуру. А шестёрку можно напечатать просто как
(print 6) . Смысл в чём: вот у меня цепочка наследования c1 <- c2 <- c3, для этих классов я определяю методы, возвращающие 1, 2, 3, и в применении к объекту класса c3 (а не класса c123!) генеричная функция возвращает 6, обойдя всех родителей класса и сложив значения методов. И она так же автоматически обойдёт всех родителей при любом дереве наследования.Я не говорю, что это киллер-фича лиспа, и что по-другому никак нельзя. Но среди тех (немногочисленных) языков, о которых я имею представление, так не умеет делать никакой. В "обычном языке" даже не стоит вопрос, что при диспетчеризации метода можно сделать что-либо другое помимо выбора подходящего метода и применения его. То есть комбинирования методов, при котором результат по-разному зависит от всего дерева наследования, как раз и нет.
0
|
Нарушитель
79 / 75 / 16
Регистрация: 12.01.2022
Сообщений: 901
|
|
04.04.2022, 22:34 | 17 |
не надо передёргивать. вы задали конкретный вопрос
я ответил. Странный спор: у каждого языка свои методы. Другие языки умеют то, что не умеет лисп (какой из лиспов, кстати?). Что ж теперь с того? Просто, по-моему, ООП с его классами свое отжило. Многие современные языки от него уже отказались.
0
|
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
|
04.04.2022, 23:30 | 18 |
Это неаналогичный код.
Вы утверждаете, что комбинация методов аналогична перегрузке оператора. Я пытаюсь пояснить, что это не так. Что комбинация методов не перегрузка, и более того, в языках встречается нечасто. Вероятно, и вам она раньше не встречалась, и вы поэтому не понимаете, о чём речь. Но если при всём при том вы не желаете понять разницу, а предпочитаете продолжать думать, что комбинация методов есть перегрузка оператора - ваше право.
0
|
Нарушитель
79 / 75 / 16
Регистрация: 12.01.2022
Сообщений: 901
|
|
05.04.2022, 00:02 | 19 |
а почему он должен быть аналогичным?
То что вы сначала описали достигается перегрузкой операторов. Я об этом и сказал.
0
|
4486 / 2721 / 485
Регистрация: 28.04.2012
Сообщений: 8,590
|
||||||
05.04.2022, 02:40 | 20 | |||||
Не достигается, просто ты не понял примера. Когда покажешь как сделать функцию printWeights с помощью перегрузки операторов, тогда и будешь говорить, что достигается.
Вот ещё пример:
Код
{"color": "RED", "label": "A", "tags": ["MULTIMETHODS","COMBINATIONS"], "x": 42, "y": 9001, "enabled": true}
1
|
05.04.2022, 02:40 | |
05.04.2022, 02:40 | |
Помогаю со студенческими работами здесь
20
Множественное наследование Множественное наследование множественное наследование Множественное наследование Множественное наследование Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |