Quando os antigos deuses da programação estavam inventando a programação orientada a objetos com classes, eles decidiram, quando se tratava de composição e herança, ter dois relacionamentos para um objeto: "é um" e "tem um".
Isso resolveu parcialmente o problema das subclasses serem diferentes das classes pai, mas as tornou utilizáveis sem quebrar o código. Como uma instância de subclasse "é um" objeto de superclasse e pode ser substituída diretamente por ele, mesmo que a subclasse tenha mais funções-membro ou membros de dados, a "possui-a" garante que ele executará todas as funções do pai e terá todas as suas membros. Então, você poderia dizer que um Point3D "é um" Point e um Point2D "é um" Point se ambos herdarem do Point. Além disso, um Point3D pode ser uma subclasse de Point2D.
Entretanto, a igualdade entre as classes é específica do domínio do problema, e o exemplo acima é ambíguo quanto ao que o programador precisa para o programa funcionar corretamente. Geralmente, as regras do domínio matemático são seguidas e os valores dos dados geram igualdade se você limitar o escopo da comparação apenas neste caso a duas dimensões, mas não se você comparar todos os membros dos dados.
Então, você obtém uma tabela de igualdade de igualdade:
Both objects have same values, limited to subset of shared members
Child classes can be equal to parent classes if parent and childs
data members are the same.
Both objects entire data members are the same.
Objects must have all same values and be similar classes.
Objects must have all same values and be the same class type.
Equality is determined by specific logical conditions in the domain.
Only Objects that both point to same instance are equal.
Geralmente, você escolhe as regras mais rígidas que ainda pode executar todas as funções necessárias no domínio do problema. Os testes de igualdade internos para números são projetados para serem o mais restritivos possível para fins de matemática, mas o programador tem muitas maneiras de contornar isso, se esse não for o objetivo, incluindo arredondamento para cima / baixo, truncamento, gt, lt, etc. . Objetos com registro de data e hora são frequentemente comparados pelo tempo de geração e, portanto, cada instância deve ser única para que as comparações sejam muito específicas.
O fator de design nesse caso é determinar maneiras eficientes de comparar objetos. Às vezes, é necessário fazer uma comparação recursiva de todos os membros dos dados dos objetos, e isso pode ficar muito caro se você tiver muitos e muitos objetos com muitos membros dos dados. As alternativas são comparar apenas valores de dados relevantes ou fazer com que o objeto gere um valor de hash de seus membros de dados envolvidos para uma comparação rápida com outros objetos semelhantes, mantenha as coleções classificadas e removidas para tornar as comparações mais rápidas e menos intensivas na CPU, e talvez permitir objetos que são idênticos nos dados a serem descartados e um ponteiro duplicado para um único objeto é colocado em seu lugar.