[RESOLVIDO][Iniciante] Dúvidas sobre conceitos de abstração

programação
#1

A minha dúvida é a seguinte eu tenho duas classes abstrata, é possível que uma classe abstrata herde da outra?

Exemplo prático:
Em um sistema de Petshop eu tenho pessoas que serão usuários que poderão ser tanto de nível administrador quanto usuários padrões(Aqueles usuários que só irão utilizar os serviços do Petshop). Da frase acima eu posso tirar duas classes uma é a classe Pessoa e a outra classe Usuário e por ter escopo genérico, elas podem ser abstratas, só que Usuário pode ser uma Pessoa também e vice-versa. Então aqui entra a minha dúvida - Em um cenário corporativo o que eu devo fazer, criar apenas umas dessas classes abstratas? Ou fazer as duas classes abstratas e fazendo com que a Classe Usuário herde a Classe Pessoa? Explique sua resposta.

0 Likes

#2

Olá @Saulo.

A minha dúvida é a seguinte eu tenho duas classes abstrata, é possível que uma classe abstrata herde da outra?

Sim é possível, contudo essa implementação varia muito entre as linguagens de programação, o conceito geral (resumido) é:

  • Uma classe abstrata é um modelo para outras classes.
  • Classes abstratas não podem ser instanciadas diretamente, elas sempre devem ser herdadas por outras classes.
  • Se uma classe abstrata herdar de outra classe abstrata, não é necessária a implementação dos métodos abstratos.

2 textos legais sobre o assunto são:

Para fornecer um exemplo seria interessante você especificar a linguagem de programação, visto que este tipo de implementação varia bastante de linguagem para linguagem.

Para Python pode ser interessante dar uma olhada neste texto: Herança e Polimorfismo. Site da Caelum, as vezes ele não abre, tente dar F5.

Outros conteudo interessantes para Python são:

Não vou arriscar fazer um exemplo com base no que você descreveu porque:

  • Não sei a linguagem que você pretente utilizar.
  • Não sei se você já tem algo criado. Caso você já tenha algo criado eu acabaria lhe confundido mais do que ajudando.
2 Likes

#3

@natorsc, Obrigado! Não tenho nada implementado é uma dúvida que surgiu após a leitura do livro Clean Code. Como eu posso fazer para implementar de uma forma mais profissional sem criar sujeira ou classes que não são necessárias. E no problema citado o que eu poderia fazer para criar um código mais sucinto e claro, ou seja eu deveria criar as duas classes e fazer usuário herdar de pessoa ou somente usar uma das classes abstratas. Qual a melhor maneira, na sua opinião? E obrigado pela sugestão de leitura, vou dar uma olhada.

1 Like

#4

Não conhecia este livro! Já adicionei na lista de livros técnicos.

Eu criaria uma classe abstrata apenas, isso porque considero mais simples e fácil de ler o código. Exemplo genérico:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Exemplo"""

import math


class FormaGeometrica:
    """Classe que será o modelo para as demais."""

    def __init__(self, parametros, cor):
        """Construtor.

        Atributos que serão passados quando a classe filha for
        instanciada.

        :param parametros: Medida/medidas da forma geometrica.
        :param cor: (str) Cor da forma geométrica.
        """
        self.parametros = parametros
        self.cor = cor

    def exibir_cor(self):
        """Método será implementado somente nas classes filhas"""

    def exibir_area(self):
        """Método será implementado somente nas classes filhas"""


class Quadrado(FormaGeometrica):
    """Classe quadrado herda de FormaGeometrica.

    Neste caso  os métodos de classe são reescritos e não é necessário
    criar os atributos, pois eles vem da classe pai.
    """

    def exibir_area(self):
        """Reescrevendo o método da classe pai (overrides)."""
        print(math.pow(self.parametros, 2))

    def exibir_cor(self):
        """Reescrevendo o método da classe pai (overrides)."""
        print('A cor do quadrado:', self.cor)


class Retangulo(FormaGeometrica):
    def exibir_area(self):
        print(self.parametros[0] * self.parametros[1])

    def exibir_cor(self):
        print('A cor do retangulo:', self.cor)


class Circulo(FormaGeometrica):
    def exibir_area(self):
        print(f'{math.pow(self.parametros, 2) * math.pi:.2f}')

    def exibir_cor(self):
        print('A cor do circulo:', self.cor)


if __name__ == '__main__':
    # Instância do objeto.
    quadrado = Quadrado(2, 'Azul')
    quadrado.exibir_cor()
    quadrado.exibir_area()

    retangulo = Retangulo([2, 4], 'Verde')
    retangulo.exibir_cor()
    retangulo.exibir_area()

    circulo = Circulo(5, 'Roxo')
    circulo.exibir_cor()
    circulo.exibir_area()

Já com duas classes abstratas pode ser confuso entender de que classe um método pode estar vindo (pelo menos pra mim kakakakak):

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Exemplo"""

from abc import ABC, abstractmethod


class MinhaClasseA(ABC):
    """Classe A herda do módulo ABC (Abstract Base Classes)."""

    def __init__(self, value):
        """Construtor.

        :param value: (int) um valor qualquer.
        """
        self.value = value

    @abstractmethod
    def metodo_class_a(self):
        pass


class MinhaClasseB(MinhaClasseA):
    """Classe B herda de A."""

    @abstractmethod
    def metodo_class_b(self):
        pass


class MinhaClasseC(MinhaClasseB):
    """Classe C herda de B que por conseguencia herda de A.

    Por isso podemos reescrever os métodos de A e B.
    """

    def metodo_class_a(self):
        print(self.value + 1)

    def metodo_class_b(self):
        print(self.value + 2)


if __name__ == '__main__':
    instacia = MinhaClasseC(value=1)
    instacia.metodo_class_a()
    instacia.metodo_class_b()

Mais é uma questão bem interessante. Ela acaba abordado conceitos complexos da orientação a objeto que a gente costuma só aceitar que existem kakakakak.

2 Likes