Executando verificação de segurança...
1

POO em ação: Construindo os pilares do paradigma - Parte 1

Estou fazendo um novo post no meu blog, passando tópicos fundamentais sobre POO em Java de forma bem didática, usando exemplos e animações. Este é o primeiro post da série de (planejado) 8 partes, qualquer sugestão para futuros posts é muito bem vinda. Ele acabou ficando um pouco grande, então não dá para colocar ele inteiro aqui, se ficou interessado, acesse o post completo aqui:
POO em ação: Construindo os pilares do paradigma - Parte 1

Aqui vai uma pequena espiada em alguns poucos tópicos do post.

Tópicos abordados

Nesta série, vamos usar o Java com JDK 21 para criar os exemplos práticos, escolhi o Java por ser amplamente usado em várias áreas além de muitas faculdades ainda o usam para a disciplina de POO.

Quero deixar claro que, se você está interessado em POO, então provavelmente já sabe os conceitos básicos sobre linguagem de programação, como declarações, funções, controle de fluxo e outros, se não, então provavelmente vai se sentir mais perdido que o resto, sugiro aprender, na teoria e na prática, estes conceitos antes de continuar, além disso, não vou focar em ensinar a sintaxe e peculiaridades do Java, o intuito aqui é ensinar POO.

  • ➡️ Parte 1 - Construindo os pilares do paradigma (Abstração e Encapsulamento).
  • Parte 2 - Construindo os pilares do paradigma (Polimorfismo e Herança).
  • Parte 3 - Relações entre objetos.
  • Parte 4 - Fixando os conceitos da POO com mais prática.
  • Parte 5 - Os princípios S.O.L.I.D
  • Parte 6 - Aplicando Padrões de projeto (Design Pattern).
  • Parte 7 - OO de forma inteligente com mais prática.
  • Parte 8 - OO para a vida: Os conceitos de uma perspectiva diferente.

Objetos ≠ Classe

É fundamental deixar isso claro, uma classe é um molde para um objeto, um objeto é o que chamamos de instancia de uma classe, a partir de uma classe criamos um novo objeto, geralmente fazemos isso com a palavra-chave new, mas isso depende da linguagem, isso irá gerar um objeto concreto que podemos guardar em uma variável por exemplo e usar seus atributos e métodos que definimos na classe.

Getter e Setter

Estes são métodos que criamos para manter o controle de acesso dos atributos das nossas classes, métodos Get são usados para recuperar valor de um atributo, enquanto o Set é usado para atribuir valor ao atributo. A criação deles não é obrigatória para todo atributo, você os cria de acordo com a necessidade, inclusive, você pode criar apenas um Get, sem um Set, para um atributo, para assim garantir a imutabilidade.

Abstração

Esta diz respeito ao que você modela para dentro do seu software, pegar algo do mundo real e colocar no seu programa, no nosso exemplo abstraímos um livro, criando a classe com seus atributos (propriedades) e ações (métodos). Você pode ter notado que nem toda informação que tem em um livro tem na nossa classe, isso simplesmente porque não precisamos delas, você pode ter se lembrado de ISBN, gênero, idioma, etc. Mas queria deixar o exemplo simples, então coloquei apenas o que achei necessário.

Encapsulamento

Não pense que encapsulando os membros do nosso programa vamos fazer dele mais seguro, encapsulamento é sobre acesso e controle, ele dá ao programador uma forma de moldar a forma de usar uma classe que criamos por meio de permissões. Pode não parecer grande coisa, mas isso é bastante usado na criação de pacotes ou quando estamos trabalhando em equipe, onde devemos expor para eles apenas o que queremos que eles acessem, dessa forma, podemos dificultar o uso indevido da classe.

Carregando publicação patrocinada...
5

E lá vamos nós de novo :-)


Já falei aqui sobre isso, mas como o assunto sempre volta, vale repetir:

Sei que a ideia do post é ser um guia básico, mas de qualquer forma é uma ótima oportunidade pra esclarecer novamente uma coisa muito importante:

Não existe uma definição única, canônica, universal e livre de controvérsias sobre Orientação a Objetos. A definição dada acima é uma das existentes, mas na realidade o buraco é mais embaixo.

Já respondi sobre isso também aqui, e sugiro ler e seguir todos os links indicados (e mais os links em cada em cada um deles) para se aprofundar no tema.

Mas só pra resumir:

Existem várias vertentes (ou "escolas", se preferir) de Orientação a Objetos, e a mencionada no texto é apenas uma delas - provavelmente a mais popular, e talvez por isso muita gente acredita que é a única. As definições mais conhecidas são a de Alan Kay e Bjarne Stroustrup (respectivamente, à esquerda e direita na imagem abaixo):

Alan Kay e Bjarne Stroustrup, cada um com sua definição de OO

Alan Kay é o cara que cunhou o termo "Orientação a Objetos", mas ironicamente a definição dele é diferente da que está no texto. Ele definiu, entre outras coisas, que "tudo é um objeto" (o que excluiria Java como linguagem orientada a objeto, só pra ficar em um exemplo), e que eles se comunicam via troca de mensagens.

Ou seja, nada de herança, encapsulamento ou polimorfismo (as características que sempre aparecem em qualquer texto sobre o assunto). Essas características se aproximam muito mais da definição de Bjarne Stroustrup, que basicamente pegou o mesmo termo e "ressignificou". No fim, acabou virando a definição mais conhecida.

Mesmo os "pilares" não são consenso. Tem gente que diz que "abstração" é um termo genérico demais para pertencer a um único paradigma, por exemplo.

Isso não quer dizer que o post está errado. Mas é importante mencionar que orientação a objetos é bem mais complexo que isso, e mesmo a sua definição exata é controversa. Por exemplo, não é obrigatório ter classes, tanto que dá pra fazer POO em C. Ou usando protótipos, como faz o JavaScript (apesar de ter a palavra chave class, ela é apenas um syntax sugar). Ou seja, a classe é apenas um mecanismo que facilita, mas não é pré-requisito pra algo ser orientado a objeto. E ela por si só também não garante nada, muita gente faz programas procedurais em Java sem perceber, por exemplo.

Por fim, sobre getters e setters, sugiro ler os links que estão aqui, tem discussões muito boas pra se aprofundar no tema, em especial esta (sim, o assunto é mais complexo do que parece).

2

Desculpe se parecer rude, mas no post completo tem uma seção chamada “O que é POO?” onde esclareço justamente isso, de que não existe uma definição clara sobre POO. Coloquei esta seção justamente por conta que li a sua resposta a primeira vez que postou.

Entendi algo errado?

Novamente, desculpe se parecer rude. O post é open-source e toda contribuição é bem-vinda.

1

Eu vi o post, mas como não dá pra saber se todo mundo vai clicar, resolvi responder e deixar a informação aqui também. Desculpe pelo mal entendido.


Mas eu reconheço que isso é uma batalha perdida. A esmagadora maioria dos cursos só ensina de uma forma, até porque é a que se tornou mais popular e no fim a mais usada. E por isso a maioria vai continuar achando que é a única.

Eu só insisto porque sou teimoso mesmo, ainda acredito que as pessoas deveriam se aprofundar no tema e entender que "não é só isso" :-)

1

A definição do Alan Kay implica em alguns resultados que podem passar despercebidos para alguns programadores. Um exemplo simples que serve para visualizar melhor a definição:

2 + 4 * 3 = 18 e não 14

Como tudo são objetos, a expressão acima poderia ser traduzida como:

2.plus(4).times(3)

3

Não esquece de ler os comentários do kht e meu: https://www.tabnews.com.br/Araujo/conteudo-programacao-orientado-a-objetos-javascript (também: https://www.tabnews.com.br/kht/2b3c6beb-bae5-4c2a-b7d7-3a8e90ceb0e6). Então há controvérsias sosbre esses pilares e outros. Veja também: https://pt.stackoverflow.com/q/215679/101. Eu discuto muito isso no SOpt, e ainda não tenho conclusão definitiva sobre isso, posso até discordar o que eu escrevi.

SOLID é até uma forma que consertar OOP, assim como os design patterns que ficaram famosos por fazer o mesmo. E as pessoas nem sabem o que são DP porque só aprenderam os famosos.

O new pode mudar sua definição em Java nas próximas atualiação (estão prometendo desde a versão 10), assim como em C# não é isso. Tem linguagem que ele é só um alocador de memória.

Não me parece que essa definição de abstração esteja tão correta. https://pt.stackoverflow.com/q/360556/101.

Embora tenha definições diferentes, encapsulamento costuma ser colocar tudo dentro de uma cápsula. Veja em https://pt.stackoverflow.com/q/240186/101. A definição apresentada acima costuma ser chamada de information hiding. Mas é aquela coisa, depende de escola.

Quase 100% das pessoas usam getters/setters errado, é tão prevalente que meio que "virou o certo". Eu nem sou tão contra, mas as pesoas glorificam algo que elas não querem seguir, querem fazer diferente, mas usar o nome porque assim ela passa estar na moda.

O fato do artigo estar capado aqui dá ideia bem errada. O fato de não ter esse e talvez outros comentários no original vai fazer muita gente aprender e/ou perpetuar os erros. Que é o que eu sempre falo do ciclo:

|-> aprende errado -> treina o erro -> executa o erro -> ensina o erro ->|
|----------------------<----------------------------<------------------------<-|

Vamos ver o que vem do resto, eu vou comentando conforme for precisando.

Pode ajudar:

Observou? Faz sentido para você?

Espero ter ajudado. Em geral estou à disposição na plataforma (sem abusos :D)


Farei algo que muitos pedem para aprender a programar corretamente, gratuitamente. Para saber quando, me segue nas suas plataformas preferidas. Quase não as uso, não terá infindas notificações (links aqui).

1

Muito obrigado pelos links, vou levá-los em consideração nas próximas partes.

Meu intuito não é entrar a fundo nos conceitos, no post, passo um código, explico bem detalhadamente o que foi feito e proponho o que será feito em seguida e porquê.
Eu tomei uma abordagem de explicar a prática, tentei ser bem didático e não citar conceitos tão complicados no começo.

Por exemplo, sei que o new atua muito como um alocador, mas talvez para ficar mais claro, tenha que explica sobre alocação (memória heap, stack), então simplesmente falo que o new é usado para instanciar um novo objeto.

Realmente pelo jeito que escrevi no final sobre getters/setters (o trecho que coloquei aqui foi um corte da definição que dei no final) pode parecer information hiding, mas durante a prática no post, explico porque fiz determinado atributo privado, explicando que usamos o encapsulamento mais para moldar a forma que queremos usar (ou que outros usem) a classe que criamos.

Acabei esquecendo, mas se quiser, você pode fazer sua contribuição no post, ele é open-source e pode ser acessado aqui toda contribuição é bem-vinda.