Для установки нажмите кнопочку Установить расширение. И это всё.

Исходный код расширения WIKI 2 регулярно проверяется специалистами Mozilla Foundation, Google и Apple. Вы также можете это сделать в любой момент.

4,5
Келли Слэйтон
Мои поздравления с отличным проектом... что за великолепная идея!
Александр Григорьевский
Я использую WIKI 2 каждый день
и почти забыл как выглядит оригинальная Википедия.
Статистика
На русском, статей
Улучшено за 24 ч.
Добавлено за 24 ч.
Альтернативы
Недавние
Show all languages
Что мы делаем. Каждая страница проходит через несколько сотен совершенствующих техник. Совершенно та же Википедия. Только лучше.
.
Лео
Ньютон
Яркие
Мягкие

Из Википедии — свободной энциклопедии

C3-линеаризация суперкласса (англ. C3 superclass linearization) — алгоритм, используемый преимущественно для получения устойчивой линеаризации иерархии множественного наследования в объектно-ориентированном программировании. Данная линеаризация используется для определения порядка, в котором должны наследоваться методы, что часто в англоязычной литературе обозначается как «MRO» (сокращение от «Method Resolution Order», то есть «порядок разрешения метода»). C3 в названии указывает на три главные особенности итоговой линеаризации: устойчивый и расширяющийся (по старшинству) граф[англ.]*, сохранение локального порядка старшинства, а также монотонность. Данная теория впервые была представлена в 1996 году в рамках конференции OOPSLA, в документе, озаглавленном «Монотонная линеаризация суперкласса для языка Dylan»[1]. Впоследствии данный алгоритм был выбран как алгоритм по умолчанию для разрешения методов в языке программирования Python 2.3 (и последующих версиях), Perl 6 и виртуальной машине Parrot. Он также доступен в виде альтернативы (не являясь MRO по умолчанию) в ядре Perl 5, начиная с версии 5.10.0. Расширенная реализация для более ранних версий Perl 5 носит название Class::C3 и существует в CPAN.

Пример

Для

Граф зависимостей данного примера.
class O
class A extends O
class B extends O
class C extends O
class D extends O
class E extends O
class K1 extends A, B, C
class K2 extends D, B, E
class K3 extends D, A
class Z extends K1, K2, K3

Линеаризация Z считается как

L(O)  := [O]                                                // линеаризация O тривиально представляет собой единичный список [O], потому что O не имеет родителей 
L(A)  := [A] + merge(L(O), [O])                             // линеаризация A - это A плюс объединение линеаризаций его родителей с списком родителей...        
= [A] + merge([O], [O])        = [A, O]                                             // ...что просто добавляет A в линеаризацию его единственного родителя 
L(B)  := [B, O]                                             // линеаризации B, C, D и E вычисляются аналогично линеаризации A 
L(C)  := [C, O] 
L(D)  := [D, O] 
L(E)  := [E, O] 

L(K1) := [K1] + merge(L(C), L(B), L(A), [C, A, B])          // сначала найдем линеаризации родителей K1: L(C), L(B) и L(A), и объединим их с списком родителей [C, A, B]        
= [K1] + merge([C, O], [B, O], [A, O], [C, A, B])    // класс C - хороший кандидат для первого шага слияния, потому что он появляется только в начале первого и последнего списка        
= [K1, C] + merge([O], [B, O], [A, O], [A, B])       // класс O - не является хорошим кандидатом для следующего шага слияния, потому что он также появляется в хвостах списка 2 и 3, класс B тоже не подходит; но класс A - хороший кандидат        
= [K1, C, A] + merge([O], [B, O], [O], [B])          // класс B - хороший кандидат; класс O все еще появляется в хвосте списка 2        
= [K1, C, A, B] + merge([O], [O], [O])               // наконец, класс O - допустимый кандидат, что также завершает все оставшиеся списки        
= [K1, C, A, B, O] 

L(K3) := [K3] + merge(L(A), L(D), [A, D])        
= [K3] + merge([A, O], [D, O], [A, D])               // выбираем A        
= [K3, A] + merge([O], [D, O], [D])                  // отбрасываем O, выбираем D        
= [K3, A, D] + merge([O], [O])                       // выбираем O        
= [K3, A, D, O] 

L(K2) := [K2] + merge(L(B), L(D), L(E), [B, D, E])        
= [K2] + merge([B, O], [D, O], [E, O], [B, D, E])    // выбираем B        
= [K2, B] + merge([O], [D, O], [E, O], [D, E])       // отбрасываем O, выбираем D        
= [K2, B, D] + merge([O], [O], [E, O], [E])          // отбрасываем O, выбираем E        
= [K2, B, D, E] + merge([O], [O], [O])               // выбираем O        
= [K2, B, D, E, O] 

L(Z)  := [Z] + merge(L(K1), L(K3), L(K2), [K1, K3, K2])        
= [Z] + merge([K1, C, A, B, O], [K3, A, D, O], [K2, B, D, E, O], [K1, K3, K2])    // выбираем K1        
= [Z, K1] + merge([C, A, B, O], [K3, A, D, O], [K2, B, D, E, O], [K3, K2])        // выбираем C        
= [Z, K1, C] + merge([A, B, O], [K3, A, D, O], [K2, B, D, E, O], [K3, K2])        // отбрасываем A, выбираем K3        
= [Z, K1, C, K3] + merge([A, B, O], [A, D, O], [K2, B, D, E, O], [K2])            // выбираем A        
= [Z, K1, C, K3, A] + merge([B, O], [D, O], [K2, B, D, E, O], [K2])               // отбрасываем B, отбрасываем D, выбираем K2        
= [Z, K1, C, K3, A, K2] + merge([B, O], [D, O], [B, D, E, O])                     // выбираем B        
= [Z, K1, C, K3, A, K2, B] + merge([O], [D, O], [D, E, O])                        // отбрасываем O, выбираем D        
= [Z, K1, C, K3, A, K2, B, D] + merge([O], [O], [E, O])                           // отбрасываем O, выбираем E        
= [Z, K1, C, K3, A, K2, B, D, E] + merge([O], [O], [O])                           // выбираем O        
= [Z, K1, C, K3, A, K2, B, D, E, O]                                               // готово

Обозначения:

L(Class) - линеаризация класса Class
[A,B,C]  - список из трех элементов, где голова это A, а хвост [B,C]
merge    - слияние списков

Функция merge осуществляет слияние списков таким образом, чтобы каждый элемент встречался в результате ровно один раз, этим она похожа на слияние множеств, но тут важен порядок следования элементов в списке. Функция merge работает следующим образом - она перебирает списки-аргументы по порядку упоминания (слева направо), выбирая первый элемент, который может быть первым в нескольких списках, но нигде не упоминается вторым и далее, и перемещает его в список-результат, исключая из списков-аргументов, повторяя эту процедуру несколько раз, пока все элементы не переместятся из списков-аргументов в список-результат. Если на каком-то этапе возникает ситуация, что нельзя выбрать элемент-кандидат, удовлетворяющий указанному условию, т.е. если во всех списках-аргументах первые элементы встречаются в других списках-аргументах не первыми, итоговый список не создаётся.

Пример Python3:

Создадим отображение классов в виде их имен

class Type(type):
    def __repr__(cls):
        # Will make it so that repr(O) is "O" instead of "<__main__.O>",
        # and the same for any subclasses of O.
        return cls.__name__

class O(object, metaclass=Type): pass

Определим базовые классы

class A(O): pass

class B(O): pass

class C(O): pass

class D(O): pass

class E(O): pass

Построим дерево наследования

class K1(C, A, B): pass

class K3(A, D): pass

class K2(B, D, E): pass

class Z(K1, K3, K2): pass

Проверяем mro

>>> Z.mro()
[Z, K1, C, K3, A, K2, B, D, E, O, <class 'object'>]

Пример в Raku:

class A {}
class B {}
class C {}
class D {}
class E {}
class K1 is C is A is B {}
class K3 is A is D {}
class K2 is B is D is E {}
class Z is K1 is K3 is K2 {}
say Z.^mro; # OUTPUT: ((Z) (K1) (C) (K3) (A) (K2) (B) (D) (E) (Any) (Mu))

Примечания

  1. "A Monotonic Superclass Linearization for Dylan". OOPSLA '96 Conference Proceedings. ACM Press. 1996-06-28. pp. 69—82. doi:10.1145/236337.236343. ISBN 0-89791-788-X. Архивировано из оригинала 17 августа 2000. Дата обращения: 14 декабря 2009. Источник. Дата обращения: 14 декабря 2009. Архивировано 17 августа 2000 года.

Ссылки

Эта страница в последний раз была отредактирована 24 декабря 2023 в 07:35.
Как только страница обновилась в Википедии она обновляется в Вики 2.
Обычно почти сразу, изредка в течении часа.
Основа этой страницы находится в Википедии. Текст доступен по лицензии CC BY-SA 3.0 Unported License. Нетекстовые медиаданные доступны под собственными лицензиями. Wikipedia® — зарегистрированный товарный знак организации Wikimedia Foundation, Inc. WIKI 2 является независимой компанией и не аффилирована с Фондом Викимедиа (Wikimedia Foundation).