Existe um nome específico para o paradoxo "O quadrado herda do retângulo"?

18

Uma certa falha do OOP é mostrada com uma classe Square herdada de Rectangle, onde logicamente Square é uma especialização de Rectangle e, portanto, deve herdar dele, mas tudo desmorona quando você tenta alterar o comprimento ou a largura de um Square.

Existe um termo específico para descrever o que está acontecendo de errado com esse caso?

Vencedor
fonte
2
você poderia explicar o que exatamente "está errado"? Eu não entendo o que quer dizer
mosquito
1
Supondo que um retângulo tenha um método virtual que permita definir tamanho passando comprimento e largura, definir um comprimento e largura diferentes em um quadrado pode retornar um retângulo e definir um mesmo comprimento e largura em um retângulo pode retornar um quadrado. Qualquer código que precise conhecer explicitamente o quadrado pode tentar converter para um quadrado. Eu não ver como há uma falha ...
8
Isto não é um paradoxo. Este é um caso de modelagem incorreta do domínio do problema. A hierarquia de herança NÃO necessariamente está alinhada com a hierarquia de coisas no domínio do problema. É bom quando o faz, mas o truque de um bom modelo é entender onde você precisa fazer as coisas de maneira diferente do mundo real.
Michael Kohne
1
FWIW: Mais especificamente, o problema é que as interfaces de leitura e gravação não coincidem. Ou seja, você pode ler um círculo como especialização de uma elipse, mas apenas escrever uma elipse como especialização de um círculo.
Macke
1
@GrandmasterB Eu passo por "qualquer pessoa, coisa ou situação exibindo uma natureza aparentemente contraditória". A contradição é que, se o quadrado tem propriedades diferentes, temos que dizer "um quadrado não é uma espécie de retângulo", quando na verdade esperamos que o quadrado seja um subtipo de retângulo. Provavelmente, nenhum aplicativo real teria os tipos Retângulo e Quadrado, é apenas uma abstração para ilustrar um certo tipo de problema que pode aparecer em paradigmas baseados em classe.
253 Victor

Respostas:

27

A Wikipedia apenas se refere a ele como o problema da elipse circular

O problema da elipse circular no desenvolvimento de software (às vezes conhecido como problema do retângulo quadrado ) ilustra várias armadilhas que podem surgir ao usar o polimorfismo de subtipo na modelagem de objetos. Os problemas são mais comumente encontrados ao usar a programação orientada a objetos.

Este é o L no acrônimo SOLID, conhecido como princípio de substituição de Liskov . Esse problema surge como uma violação desse princípio.

O problema diz respeito a qual relação de subtipagem ou herança deve existir entre classes que representam círculos e elipses (ou, da mesma forma, quadrados e retângulos). Mais geralmente, o problema ilustra as dificuldades que podem ocorrer quando uma classe base contém métodos que modificam um objeto de uma maneira que pode invalidar um invariante (mais forte) encontrado em uma classe derivada, causando a violação do princípio de substituição de Liskov ...

Mark Canlas
fonte
1
E, lendo, a Wikipedia menciona a explicação mais acadêmica como "[violação do] princípio de substituição de Liskov". Obrigado :)
Victor
1
Bem, é apenas uma violação, dependendo de como você olha para ela. Pessoalmente, todos os círculos são elipses; não há violação. Começa a haver uma violação se os métodos de elipse se tornarem restritivos. Então, nesse cenário específico, um círculo não pode ser um subtipo desse contrato específico de elipse.
Mark Canlas
6
@ MarkCanlas O problema é indiscutivelmente uma violação do princípio da substituição de Liskov. Pode não ser uma violação de outros princípios, mas ninguém afirmou isso. Quando o problema não ocorre porque os contratos não incluem invariáveis ​​que seriam quebrados (embora eu não consiga imaginar um modelo útil onde isso seja verdade), pode não haver uma violação do LSP, mas isso não significa que o contrato O problema , quando ocorre, não se deve a uma violação do LSP.
7
@ Mark Canlas: não, círculo constante é uma elipse constante , círculo mutável não é uma elipse mutável. Em constantness geometria é assumido, você não pode mudar uma elipse, você pode tomar outra elipse
maxim1000
1
A restrição / regra de história do princípio de substituição de Liskov diz que, quando um subtipo adiciona novos métodos, esses métodos não têm permissão para manipular o estado do objeto de maneira a criar um histórico (isto é, uma série de estados) que não é permitido no supertipo. Por exemplo, você não pode transformar um subtipo de um mutável imutável, porque quando manipulado apenas pelos métodos do supertipo, o estado é sempre o mesmo, enquanto que quando manipulado pelos métodos mutadores do subtipo, o estado muda. Essa é uma história que não é permitida pelo supertipo.
Jörg W Mittag
8

Eu consideraria uma violação do Princípio da Substituição de Liskov - a Squaresubclasse viola especificamente a invariante de que comprimento e largura são independentes.

Paul Phillips
fonte
8

Em um nível mais fundamental que o Princípio da Substituição de Liskov, esse é um erro de categoria ou erro de categoria

No contexto do comportamento de modelagem, um quadrado simplesmente não é um tipo de retângulo.

Quando você percebe isso, o problema evapora, pois a suposição inicial (um quadrado é um tipo de retângulo) é removida do jogo.

O problema com esta resposta é que, desde a escola, é estudado quem faz geometria que um quadrado é um tipo de retângulo. Mas é muito importante entender que isso só é verdade dentro de um contexto muito específico (a classificação de formas geométricas com base nas propriedades de seus ângulos internos). Em termos de comportamento, um quadrado não é um retângulo. Visualizar um conjunto de classificação no contexto errado é um erro de categoria.

Cormac Mulhall
fonte