Cuando los antiguos dioses de la programación inventaban la programación orientada a objetos con clases, decidieron cuando se trataba de composición y herencia tener dos relaciones para un objeto: "es un" y "tiene un".
Esto resolvió parcialmente el problema de que las subclases fueran diferentes a las clases primarias, pero las hizo utilizables sin romper el código. Debido a que una instancia de subclase "es un" objeto de superclase y puede sustituirse directamente por él, a pesar de que la subclase tiene más funciones miembro o miembros de datos, el "tiene un" garantiza que realizará todas las funciones del padre y tendrá todos sus miembros. Entonces, se podría decir que un Point3D "es un" Punto, y un Point2D "es un" Punto si ambos heredan de Point. Además, un Point3D podría ser una subclase de Point2D.
Sin embargo, la igualdad entre clases es un problema específico del dominio, y el ejemplo anterior es ambiguo en cuanto a lo que el programador necesita para que el programa funcione correctamente. En general, se siguen las reglas del dominio matemático y los valores de los datos generarían igualdad si limita el alcance de la comparación a solo en este caso dos dimensiones, pero no si compara todos los miembros de datos.
Entonces obtienes una tabla de reducciones de igualdad:
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.
Por lo general, elige las reglas más estrictas que pueda que aún realicen todas las funciones necesarias en su dominio problemático. Las pruebas de igualdad incorporadas para los números están diseñadas para ser tan restrictivas como pueden ser para fines matemáticos, pero el programador tiene muchas formas de evitarlo si ese no es el objetivo, incluido el redondeo arriba / abajo, truncamiento, gt, lt, etc. . Los objetos con marcas de tiempo a menudo se comparan por su tiempo de generación, por lo que cada instancia debe ser única para que las comparaciones sean muy específicas.
El factor de diseño en este caso es determinar formas eficientes de comparar objetos. A veces, una comparación recursiva de todos los miembros de datos de objetos es lo que debe hacer, y eso puede ser muy costoso si tiene muchos objetos con muchos miembros de datos. Las alternativas son solo comparar valores de datos relevantes, o hacer que el objeto genere un valor hash de sus miembros de datos interesados para una comparación rápida con otros objetos similares, mantener las colecciones ordenadas y podadas para hacer comparaciones más rápidas y menos intensivas en CPU, y quizás permitir objetos que son idénticos en los datos que se seleccionarán y se colocará un puntero duplicado a un solo objeto en su lugar.