BlitzMax/Lições/Orientação a objeto
Durante as edições anteriores da plataforma Blitz, sempre foi usado a programação de forma imperativa, no BlitzMax porém, foi introduzido o conceito de programação orientada a objeto. Primeiramente vamos entender como funciona este novo estilo de programação para depois colocá-la em prática.
Entendendo a POO
[editar | editar código]Para entender a programação orientada a objeto vamos primeiro ver a diferença entre os dois paradigmas da programação. A orientação a objeto é uma forma que mais se aproxima do raciocínio humano, a imperativa se aproxima mais do raciocínio da máquina, por isso que se diz que a POO é um paradigma de programação de nível maior que a programação imperativa. Para entender melhor, vamos usar dois conceitos: objeto e ação.
- Programação imperativa - Primeiro pensa na ação e depois associa aos objetos, por ex: pense na ação "andar", você pode associar vários objetos que andam como pessoas, animais, carros, etc...
- Programação orientada a objeto - Primeiro pensa no objeto e depois associa as ações, por ex: pense no objeto "pessoa”, você pode associar várias ações que uma pessoa pode fazer, andar, correr, falar, etc...
Na programação imperativa as ações são tidas como funções, e os objetos são os tipos de dados. Na programação orientada a objetos os objetos são os tipos de dados e as ações são os métodos.
Um jogo orientado a objeto
[editar | editar código]Podemos fazer um conceito do que seria um jogo orientam a objeto, nele temos os vários itens e subitens para os objetos criando hierarquias de objetos, vejamos um simples exemplo:
- Jogo
- Menu
- Áudio
- Volume
- Mono/Stereo
- Vídeo
- Resolução
- Efeitos
- Áudio
- Gameplay
- Eventos
- Interativos
- Não interativos
- Inteligência artificial
- Estados
- Ações
- Eventos
- Menu
Criando um tipo
[editar | editar código]Primeiramente para usarmos a orientação a objeto iremos programar todo o código através de tipos de dado, sempre fazendo referência uns aos outros. Vamos começar criando um Type. E colocando atributos nele.
Type TMeuTipo
Field x%
Field y%
EndType
Criando um objeto
[editar | editar código]Criamos o protótipo de um tipo de dado, agora iremos criar o dado (objeto) em si, para isso vamos utilizar o comando New.
Type TMeuTipo
Field x%
Field y%
EndType
novoObjeto:TMeuTipo = New TMeuTipo
Dando atributos a um objeto
[editar | editar código]Criamos o protótipo e inicializamos o objeto, agora vamos inicializar atributos a esse objeto, para isso usaremos o nome do objeto, logo após o ponto e depois o nome do campo.
Type TMeuTipo
Field x%
Field y%
EndType
novoObjeto:TMeuTipo = New TMeuTipo
novoObjeto.x% = 1
novoObjeto.y% = 2
Métodos
[editar | editar código]Uma das grandes vantagens da POO é a possibilidade de se usar métodos dentro dos tipos. Métodos trabalham como funções normais, mas a diferença é que na POO eles podem ser acessíveis ou não por algumas partes do programa. Para criarmos o protótipo de um método utilizamos o comando Method, para iniciá-lo fazemos da mesma forma que os Fields.
Type TMeuTipo
Field x%
Field y%
Method meuMetodo()
Print("Ola!")
EndMethod
EndType
novoObjeto:TMeuTipo = New TMeuTipo
novoObjeto.x% = 1
novoObjeto.y% = 2
novoObjeto.meuMetodo()
Os métodos também podem alterar os valores dos campos do objeto.
Type TMeuTipo
Field x% = 1
Field y% = 2
Method meuMetodo()
x% = 10
y% = 20
EndMethod
EndType
novoObjeto:TMeuTipo = New TMeuTipo
Print(novoObjeto.x%)
Print(novoObjeto.y%)
novoObjeto.meuMetodo()
Print(novoObjeto.x%)
Print(novoObjeto.y%)
Vejam que no exemplo anterior alteramos os campos do objeto após chamarmos o método de alteração.
Herança
[editar | editar código]Na POO herança é a habilidade que um tipo tem de herdar os atributos de outro tipo, aqui vamos definir o conceito de supertipo e subtipo que funcionarão como uma união de conjuntos em matemática. O supertipo (ou tipo pai) é o tipo que contem os campos primitivos, já o subtipo é aquele que tem contém tanto os campos da superclasse como os seus próprios campos.
Para começar vamos criar o supertipo (ou tipo pai), e inicializar um simples campo inteiro nele.
Type TSuperTipo
Field superCampo% = 1
EndType
Agora vamos criar o subtipo, para isso vamos criar um Type e colocar o comando Extends que indica que o subtipo irá estender o supertipo, vamos também inicializar um simples campo.
Type TSuperTipo
Field superCampo% = 1
EndType
Type TSubTipo Extends TSuperTipo
Field subCampo% = 2
EndType
Agora vamos criar uma nova variável do tipo TSubTipo.
Type TSuperTipo
Field superCampo% = 1
EndType
Type TSubTipo Extends TSuperTipo
Field subCampo% = 2
EndType
variavelSubTipo:TSubTipo = New TSubTipo
Agora primeiramente vamos mostrar no console o parâmetro do próprio subtipo.
Type TSuperTipo
Field superCampo% = 1
EndType
Type TSubTipo Extends TSuperTipo
Field subCampo% = 2
EndType
variavelSubTipo:TSubTipo = New TSubTipo
Print variavelSubTipo.subCampo%
Para acessar o campo do subtipo fazemos normalmente com o campo nato, agora vamos acessar o campo do TSuperTipo com a nossa variável sub-tipo, isso se faz da mesma forma que o campo do super-tipo pertencesse ao sub-tipo.
Type TSuperTipo
Field superCampo% = 1
EndType
Type TSubTipo Extends TSuperTipo
Field subCampo% = 2
EndType
variavelSubTipo:TSubTipo = New TSubTipo
Print variavelSubTipo.subCampo%
Print variavelSubTipo.superCampo%
Agora para efeito de teste, vamos criar uma variável do supertipo e tentar acessar o campo do subtipo.
Type TSuperTipo
Field superCampo% = 1
EndType
Type TSubTipo Extends TSuperTipo
Field subCampo% = 2
EndType
variavelSuperTipo:TSuperTipo = New TSuperTipo
Print variavelSuperTipo.subCampo%
Você provavelmente deve ter recebido uma mensagem de erro, porque não é possível acessar um subtipo através de um supertipo.
Agora vamos testar fazendo os campos do supertipo e subtipo terem o mesmo nome.
Type TSuperTipo
Field campo% = 1
EndType
Type TSubTipo Extends TSuperTipo
Field campo% = 2
EndType
variavelSubTipo:TSubTipo = New TSubTipo
Print variavelSubTipo.campo%
Na execução vimos que o conteúdo exibido foi o do subtipo, isso porque o tipo tem como prioridade seus próprios campos.