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

Minecraft: A Janela para a POO

Conteúdo


Nota do Autor

Irei direto ao ponto: neste artigo, explorarei os conceitos-chave da Programação Orientada a Objetos (POO) utilizando o Minecraft (para os mais íntimos, o Mine) como exemplo. Sem rodeios, acredito que o Mine constitui uma excelente forma de tornar esses princípios de programação mais concretos e de fácil compreensão.

E quem dentre nós não jogou Minecraft ou não criou um canal durante a era de ouro dessa franquia (que, vale ressaltar, nunca se findou)? Portanto, empregarei esse universo para ilustrar o funcionamento de conceitos como classes, objetos, atributos e métodos, sem me ater aos detalhes sintáticos de linguagens específicas.


Começando pelo começo

Para começar, primeiro precisamos entender o conceito de POO, ou Programação Orientada a Objetos. Ela é uma técnica de programação – ou seja, uma forma de pensar em criar algoritmos.

A forma base de se pensar em POO é abstrair, e criar classes para servirem de modelo para a criação dos objetos que serão usados nos programas – perceba que POO tenta se voltar mais para a realidade, pois tenta pegar objetos do mundo real e transformá-los em código.

Ela segue alguns Pilares e conceitos base, que veremos a frente. De todo modo, POO é uma das formas mais utilizadas em toda a computação, sendo uma das formas de resolver problemas computacionais mais bem aceitas e empregadas.


Conceitos base

Classes

Classe é a forma, modelo que será seguido contento: ações e características
Quando se usa POO, tudo ou quase é uma classe e por tabela é um objeto.

Image description

Image description

Com isso em mente e o conceito do que seria programação orientada a objetos, temos que pensar que para representarmos algo do mundo real, precisamos primeiro fazer o modelo da “coisa” ou “ser”, para isso criamos as classes, que por vez elas terão as suas respectivas característicasatributos e suas ações → métodos.

Vamos a um exemplo no Minecraft:

Image description

Tudo no Minecraft é um objeto, ou seja, o seu personagem, os mobs, os blocos, o mundo

Então eles foram feitos a partir de classes que por sua vez são modelos desses objetos → o que terão e como irão se comportar

Dessa forma podemos, não só reutilizar código, como modularizar em classes o que o programa vai fazer de modo que vai gerar mais facilidade na hora de criar e manter o sistema.

Transformando em código:

Para criar uma classe, usamos a palavra reservada class:

Image description

As classes por padrão começam sempre com as primeiras letras em maiúscula → uso do PascalCase. Elas possuem:

  • atributos → o que aquele modelo terá
  • métodos → deve sempre começar com o método construtor que vai iniciar a classe, eles são as ações do modelo

Objeto

Image description

Image description

É o uso da classe
Um Objeto é a instancia de um classe.

Pense que o objeto é o uso do modelo e ele que usamos para interagir com o sistema, contendo todos os atributos e métodos da classe.

Vamos a um exemplo no Minecraft:

Image description

Como vemos no exemplo, a classe Jogador possui três instâncias -> Jogador1, Jogador2, Jogador3.

  • Essas instâncias possuem as características e ações definidas na classe Jogador.

Transformando em código:

Image description

  • Para criar objetos, precisamos instanciar as classes e, para isso, usamos a palavra-chave:
new NomeDaClasse()
  • Devemos usar parênteses para a chamada do método construtor.

Lembrando que não podemos adicionar ou remover atributos ou métodos pelo objeto, somente a classe pode fazer isso.


Atributos

Image description

Os atributos são as características da classe (ou objeto).

Podemos pensar que os atributos são essenciais, uma vez que são eles que a classe vai utilizar e definir o que os objetos terão.

Vamos a um exemplo no Minecraft:

  • A o observarmos, vemos que os atributos são a base para uma classe, já que são eles que serão usados quando for realizar alguma ação ou até mesmo serem utilizados por outro objeto.

Image description

Transformando em código:

  • Podemos definir um atributo desse modo:
modificador tipo nomeDoAtributo

Image description

  • E para usá-los usamos a palavra reservada → this servindo para referenciar que vamos usar os atributos e métodos “dessa” ou “essa” classe;

Image description

  • Agora, vamos usa-lo, deste modo: objeto.atributo

💡 obviamente cada linguagem tem sua sintaxe, mas de modo base a forma como usamos e criamos se repete em outras linguagens

Image description


Métodos

Image description

Tudo aquilo que as classes fazem.

Os métodos são responsáveis pelas ações de uma classe (ou seja, do objeto), sendo que possuímos dois tipos:

  • construtorinicializa a classe, (obrigatório) e o primeiro a ser executado assim que a classe é invocada (quando usamos o new)
  • métodos não construtores → todo e qualquer outro método que não é o construtor

Vamos a um exemplo no Minecraft:

No exemplo vemos que um objeto Jogador ele precisa de algumas ações básicas como:

Image description

🤔 Quer dizer então que existe uma etapa antes de você jogar que é criar o jogador isto é chamar o método construtor para que inicialize o objeto com algumas informações como nome, skin, etc.

Transformando em código:

  • Para criar o método construtor:
modificador NomeDaClasse(tipo parametro) {}

Image description

  • Para criar métodos não construtores:
modificador nomeDoMetodo() {}

Image description

  • Agora vamos usá-los:

Image description

🤯 Está é apenas foi a primeira parte: senta, pega uma água, respira e voltemos aos conceitos.
❗ Todos os conceitos são importantes, lembre-se de entender eles bem, para isso, pratique
Blender


Pilares

De forma que a Programação Orientada a Objetos se baseia em alguns pilares.

Abstração

Image description

Jogar os detalhes para debaixo do tapete

Deixar apenas o essencial de que o objeto precisa.
Por exemplo, vamos abstrair um jogador do Minecraft, ou seja, pensar nas características e ações mais importantes:

Image description

Ao Transformar em código serial algo assim:

  • No caso, vamos abstrair a questão da linguagem, já que o importante são os conceitos
  • Assim criamos uma classe – modelo, que possui apenas o que é importante para um jogador

Image description

💡 Por convenção, usamos o nome da classe no singular e usando o pascal case


Encapsulamento

Image description

cada um no seu quadrado

  • Deixar as características do objeto (atributos) e o que ele faz (métodos) acessível apenas a ele mesmo e seu acesso é controlado
  • Usaremos o exemplo abaixo para representar encapsulamento:

Image description

❗ Caso não exista este pilar, ou seja, os atributos não estão encapsulados – no seu “quadrado” ou melhor no seu objeto, logo, qualquer um pode acessar diretamente

Transformando em código:

Image description

  • Assim podemos observar que não possuir um encapsulamento correto pode ocorrer em falhas no sistema

  • Logo, para resolver isso devemos encapsular o que a classe Jogador possui para que somente seja acessado seus atributos e métodos, dentro da própria classe:

    • Quando criarmos outros objetos tanto da classe Jogador ou mesmo tentar acessar algum atributo do Jogador, não será possível.
    • Isso graças aos modificadores de acesso que são palavras-chaves, escritas nos atributos e métodos para definir como eles serão encapsulados, logo, encapsulamos usando modificadores.
  • Antes estava public, agora está private, os modificadores mudaram e o encapsulamento também e agora não é possível acessar os atributos dentro dos objetos da classe Jogador diretamente:

Image description

  • Se tentarmos acessar diretamente os atributos irá retornar erro, já que ele está como private

Image description

  • Assim só posso modificar e ler o valor dele usando getters e setters que são métodos definidos na classe e eles tem como modificador público (public)
    • getters -> uso para pegar o valor
    • setters -> uso para modificar o valor

Modificadores

  • Modificador: public

Image description

  • Modificador: private

Image description

  • Modificador: protected

Image description

  • Modificador: static

Image description


Herança

Image description

copia, mas não faz igual

Nesse pilar pense assim: há uma classe pai, aquela que vai ser usada para ser a base das classes filhas, ou seja, você vai copiar uma classe -

  • Na verdade o que será copiado são os métodos e atributos e colar em outra classe.

De forma que ao exemplificar pensando ainda no Minecraft, ficaria assim:

Image description

  • Temos uma classe (modelo) → servindo para conter as características e ações básicas de Jogador e Mob

  • Sendo que tanto Jogador e Mob terão o que a classe pai tem, mas serão vistos como outras classes, ou seja, é uma copia do que o modelo tem

Porém, não é igual, as filhas podem sobrescrever o que uma ação faz para ficar personalizada, só que isso é Polimorfismo

Transformando em código:

Image description

Image description


Poliformismo

Image description

Eu sou o Douglas, Você não é o Douglas

Com esse pilar devemos se basear na Herança, já que o poliformismo é ter um mesmo metodo, o que o objeto faz, que possui o mesmo nome da classe pai e ma filha, só que com uma forma diferente de fazer as coisas.

Voltando ao nosso Minecraft:

Como temos, Jogador e Mob que possuem formas diferentes de fazer a mesma coisa, ou seja:

  • Os dois atacam, correm, etc, porém o Mob tem certos tipos de ataque diferente do Jogador

Image description

Logo para fazer isso além de usar a Herança, temos que sobrescrever o que jaz escrito em Personagem, para cada classe filha que tenha que possuir uma ação possuindo o mesmo nome, mas varia em comportamento

Transformando em código:

Image description

Image description


Este é o fim...

Image description

Chegamos ao fim do artigo, espero que tenha sido útil, caso tenha algum erro ou outro comentário, será muito bem vindo, pois vai enriquecer mais nós mesmos!


Image description

Carregando publicação patrocinada...
3

Cara, sempre para admirar aulas, gosto de ver como um mesmo tema é tratado de forma atrativa, que facilita o entendimento. Gostei muito do que vc colocou e como colocou, fez muita diferença, os gifs foram de explodir cabeças! A questão é transmitir e facilitar o aprendizado! Programação nunca será fácil, mas POO é um daqueles mitológicos temas, então acredito que conseguiu descomplicar!

1
3

Caramba, esse conteúdo tá absurdo! Eu estou me aprofundando em JavaScript e estava quebrando a cabeça tentando entender o tal do POO e esse post vai ajudar pra caramba!. Com certeza, relerei esse post algumas vezes.

2

Ótimo exemplo com o Mine, apesar de que, pessoalmente eu veje os conceitos mais claros em RPG raiz, onde temos aquela tabele enorme de status, profissão, habilidades primarias, segundárias e etc, me envolvi bastante.

Um ponto negativo é o execesso de GIF desnecessário. Isto também é uma opinião minha que imagino que alguns irá compartilhar, mas quando estamos querendo passar algo, o ideal seria focar mais no necessário e reduzir as distrações. Eu mesmo fiquei uns segundos tentando lembrar onde tinha visto determinados GIFs na internet

2
1

discordo do seu ponto, acho que os gifs nos conectam mais ao post, achei super divertido inclusive, mas entendo que eles não agregam ao conteúdo em si

2

Comecei a programar justamente na intenção de criar plugins para o jogo, então já explorei algumas tecnologias como o Bukkit e sempre pensava a mesma coisa: "Isso é o mais puro suco do POO", as classes abstratas, interfaces, sobrecarga e sobreescrita de métodos, polimorfismo, entre várias outras coisas, era tudo que vi na teoria sendo aplicado na prática. Bem, parabéns pelo ótimo post! Agora mesmo estava revendo conceitos de POO e me veio a cabeça que explicar com Minecraft seria de fácil entendimento e você fez isso de uma forma incrível.

1

Que legal cara, ainda tenho vontade de fazer plugins e mods para o Mine, mas acabo esquecendo rsrsrs e realmente concordo contigo:

"Isso é o mais puro suco do POO"

2

Parabéns pela postagem! Os gifs tornaram a leitura muito mais divertida, e a maneira como você escreveu o conteúdo prendeu completamente minha atenção até o final. Que venham mais conteúdos como este!

1

Vou dizer, a quantidade de GIFs e memes desse post me deixou tonto, mas fora isso tem alguns erros conceituais, eu não vou me alongar muito com fontes porque toda vez que se fala de POO com fontes alguém negativa:

A forma base de se pensar em POO é abstrair, e criar classes para servirem de modelo para a criação dos objetos que serão usados nos programas – perceba que POO tenta se voltar mais para a realidade, pois tenta pegar objetos do mundo real e transformá-los em código.

Mais ou menos, a forma base real é: abstrair, modelar, encapsular e extender, em outras fontes você acha termos diferentes mas com o mesmo efeito, ou seja que tipo os objetos vão ter, ao contrário da CRENÇA popular, POO não tem classes (sim, você e 90% aprenderam errado)

Classe, Estrutura, Protótipo

São diferentes formas de dizer como determinado objeto deve ser:

  • Protótipos são objetos que você pode usar diretamente e também pode fazer com que outros objetos busquem referências nele
  • Classe e Estrutura, são referencias para onde objetos buscam coisas faltando neles (vai ficar mais claro em extensão)

A diferença entre Classe e Estrutura é que em Estruturas o encapsulamento é feito dentro da declaração, e em estruturas, fora dela. Em resumo Classe e Estrutura ditam como um objeto deve se parecer funcionando como uma planta de construção, enquanto Protótipos são um modelo em si

Objeto

Um Objeto é uma entidade que agrupa propriedades e ações, pode ou não ser uma instancia de uma classe

Extensão (não da mais pra prosseguir sem)

Numa herança você tem uma linha de sucessão de referência, considerando o objeto "allSpark" que é do tipo Cubo, que por sua vez é do tipo Hexaedro (caso não saiba, nem todo hexaedro é um cubo), funciona assim:

allSpark->lados();

O que acontece aqui, allSpark é uma extensão de cubo (sim, instanciar uma classe é extender ela, já vou para Lua onde isso é mais explícito) então ele vai "perguntar": allSpark tem o método lados()? Se sim, chame ele e passe ele mesmo como primeiro argumento (geralmente implícito), não tem? Cubo tem? Se sim, chame ele, passando allSpark como primeiro argumento, ainda não tem? Hexaedro tem? Se sim, chame ele, passando allSpark como primeiro argumento, se não dê um erro, em Lua para visualizar melhor:

-- Declaramos a "Classe" Hexaedro e o método lados()
Hexaedro = {}
function Hexaedro:lados()
  print("Chamando de Hexaedro",self) -- O nome muda mas é o mesmo this de Java
  return 6
end
-- Declaramos a "Classe" Hexaedro e o método forma()
Cubo = {}
function Cubo:forma()
  print("Chamando de Cubo",self) -- O nome muda mas é o mesmo this de Java
  return "Quadrado"
end
-- Instanciamos o allSpark
local allSpark = setmetatable({},{__index=Cubo}
print(allSpark) -- Pra gente ver o ID na memória
allSpark:lados()
allSpark:forma()
-- Vamos pegar os métodos
print(rawget(allSpark,"lados")) -- nil, (Não existe em allSpark)
print(rawget(allSpark,"forma")) -- nil, (Não existe em allSpark)

Tudo isso pra mostrar que isso aqui não acontece "Na verdade o que será copiado são os métodos e atributos e colar em outra classe.", o que acontece é uma "cadeia de pesquisa" ou "Lookup chain" mesmo em Java, isso inclusive leva a ideia de que POO é lento, mas a verdade é que POO só fica lento com a "inheritance hell", mas aí já é assunto pra outro tópico

2

Rapaz, tu foi longe, entrou até em conceitos e/ou mecanismos de linguagens de programação.
Vá com calma, o cara está explicando com um game da infância de muitos, obviamente com o objetivo didático.

0

Obrigado pelo comentario.

Sobre os gifs, realmente é algo pessoal.

Mais ou menos, a forma base real é: abstrair, modelar, encapsular e extender, em outras fontes você acha termos diferentes mas com o mesmo efeito, ou seja que tipo os objetos vão ter, ao contrário da CRENÇA popular, POO não tem classes (sim, você e 90% aprenderam errado)

No mundo real de desenvolvimento as classes existem.

Tudo isso pra mostrar que isso aqui não acontece "Na verdade o que será copiado são os métodos e atributos e colar em outra classe.", o que acontece é uma "cadeia de pesquisa" ou "Lookup chain" mesmo em Java, isso inclusive leva a ideia de que POO é lento, mas a verdade é que POO só fica lento com a "inheritance hell", mas aí já é assunto pra outro tópico

Na verdade de modo prático é exatamente isso que acontece, as classes estariam "copiando" umas as outras, apenas abstrai essa parte e logo não me aprofundei em assinatura e nem referencia

1

No mundo real de desenvolvimento as classes existem.

Não, classe é uma keyword Syntax Sugar que algumas linguagens POO tem e apenas isso, no mundo real POO não tem classes, quanto mais rápido você desapegar dessa ideia errada, mais rápido você se torna um programador livre das amarras de uma linguagens e aumenta o seu valor como profissional

Na verdade de modo prático é exatamente isso que acontece, as classes estariam "copiando" umas as outras

Não, de modo nenhum é isso que ocorre, entender a diferença entre uma cadeia de pesquisa e essa "copia" te permite entender quando você deve herdar/extender e quando deve criar uma "Classe" independente, essa ideia de "Na verdade de modo prático é exatamente isso que acontece, as classes estariam 'copiando' umas as outras, apenas abstrai essa" é a origem de softwares que consomem de 10 a 20x mais memória,são extremamente lentos e que trazem a má fama do POO

1

Entendi seu ponto, sei o que é sintax sugar e não sabia sobre da cadeia de pesquisa.
Creio que será enriquecedor se você compartilhase conosco materiais em texto ou video que pudesse ser bom para entender esses conceitos que por exemplo você usou para adquirir esse conhecimento

1
0