A diferença está entre o que é algo e como se comporta.
Muitas línguas tentam confundir as duas, mas são coisas bem distintas.
Se como é o que e como é ...
Se tudo herda object
, alguns benefícios ocorrem como: qualquer variável de objeto pode ter qualquer valor. Mas esse também é o problema, tudo deve se comportar ( como ) como um object
e parecer com ( o que ) um object
.
Mas:
- E se o seu objeto não tiver uma definição significativa de igualdade?
- E se ele não tiver um hash significativo?
- E se o seu objeto não puder ser clonado, mas os objetos puderem?
Ou o object
tipo se torna essencialmente inútil - devido ao objeto não fornecer elementos comuns em todas as instâncias possíveis. Ou existirão objetos que tenham uma definição quebrada / com chifres / absurdo de alguma propriedade universal presumida encontrada na object
qual prove um comportamento quase universal, exceto por uma série de truques.
Se o que não está relacionado a como
Como alternativa, você pode manter os itens O que e Como separados. Então, vários tipos diferentes (sem nada em comum, tudo o que ) podem se comportar da mesma maneira que o colaborador vê como . Nesse sentido, a idéia de um Iterator
não é um quê específico , mas um como . Especificamente Como você interage com uma coisa quando ainda não sabe com o que está interagindo.
Java (e similares) permitem abordagens para isso usando interfaces. Uma interface a esse respeito descreve os meios de comunicação e, implicitamente, um protocolo de comunicação e ação que é seguido. Qualquer O que se declara de um determinado Como , declara que apóia a comunicação e a ação relevantes descritas no protocolo. Isso permite que qualquer colaborador confie no Como e não fique atolado, especificando exatamente quais O que pode ser usado.
C ++ (e similares) permitem abordagens para isso digitando duck. Um modelo não se importa se o tipo colaborador declara que segue um comportamento, apenas dentro de um determinado contexto de compilação, com o qual o objeto pode ser interagido de uma maneira específica. Isso permite que ponteiros C ++ e objetos substituindo operadores específicos sejam usados pelo mesmo código. Porque eles atendem à lista de verificação para serem considerados equivalentes.
- suporta * a, a->, ++ ae ++ -> iterador de entrada / encaminhamento
- suporta * a, a->, ++ a, a ++, --a e a-- -> iterador bidirecional
O tipo subjacente nem precisa estar iterando um contêiner, pode ser qualquer o que . Além disso, permite que alguns colaboradores sejam ainda mais genéricos, imagine que uma função precise apenas a++
, um iterador pode satisfazer isso, assim como um ponteiro, um número inteiro, assim como qualquer objeto implementado operator++
.
Sob e sobre a especificação
O problema com as duas abordagens está abaixo e acima da especificação.
O uso de uma interface exige que o objeto declare que suporta um determinado comportamento, o que também significa que o criador deve imbuí-lo desde o início. Isso faz com que alguns O que não façam o corte, pois não o declararam. Isso também significa que sempre O que tem um ancestral comum, a interface que representa o Como . Isso volta ao problema inicial de object
. Isso faz com que os colaboradores superexcliquem seus requisitos, enquanto simultaneamente fazem com que alguns objetos sejam inutilizáveis devido à falta de declaração ou ocultem truques, pois o comportamento esperado é mal definido.
O uso de um modelo exige que o colaborador trabalhe com um quê completamente desconhecido e, por meio de suas interações, ele define um como . Até certo ponto, isso dificulta a escrita dos colaboradores, pois ele deve analisar o quê para suas primitivas de comunicação (funções / campos / etc), evitando erros de compilação, ou pelo menos apontar como um determinado que não corresponde aos seus requisitos para o Como . Isso permite que o colaborador para exigir o mínimo absoluto de qualquer dado que , permitindo a mais ampla gama do que é para ser usado. Infelizmente, isso tem a desvantagem de permitir usos sem sentido de objetos que fornecem as primitivas de comunicação para um dadoComo , mas não siga o protocolo implícito, permitindo que todos os tipos de coisas ruins ocorram.
Iteradores
Neste caso, um Iterator
é uma Como ela é uma abreviação para uma descrição de interação. Qualquer coisa que corresponda a essa descrição é, por definição, umIterator
. Saber como nos permite escrever algoritmos gerais e ter uma pequena lista de ' Como é fornecido um ' O ' específico ' que precisa ser fornecido para que o algoritmo funcione. Essa lista é a função / propriedades / etc, sua implementação leva em consideração o específico O que está sendo tratado pelo algoritmo.