azevedolab.net 2015 Dr. Walter F. de Azevedo Jr. Programação Orientada a Objetos em Processing 1
Programação Orientada a Objeto O uso de programação orientada a objeto (POO) não irá introduzir necessariamente nenhuma nova função ou comando da linguagem de programação Processing. Usaremos os condicionais, funções e variáveis já vistos. A novidade está na abordagem. Vejamos um exemplo fora da programação. Você é uma pessoa, que acordou hoje, tomou café da manhã e pegou um ônibus para chegar até aqui. Sendo uma pessoa você também tem características, a cor do seu cabelo, sua altura, seu gênero, a cor dos seu olhos, peso etc. Dados humanos: Altura Cor dos cabelos Gênero Peso Cor dos olhos Funções humanas: Dormir Acordar Comer Pegar algum transporte 2
Programação Orientada a Objeto Na POO chamamos os dados humanos de variáveis. A funções humanas são funções, ou usando o jargão da orientação a objeto, são métodos. Bem, e você? Você é o objeto. Todos nós aqui na sala somos objetos. Levando a abordagem de sistema um pouco adiante, temos que os objetos, como nós, pertencem ao conjunto dos seres humanos. Ser humano é uma classe. Dados humanos: Altura Cor dos cabelos Gênero Peso Cor dos olhos Funções humanas: Dormir Acordar Comer Pegar algum transporte 3
Programação Orientada a Objeto Vamos simplificar, consideremos um biscoito. A forma de biscoito não é um biscoito propriamente dito, mas é usado para criar biscoitos. A forma de biscoito é uma classe, os biscoitos são objetos. Dados humanos: Altura Cor dos cabelos Gênero Peso Cor dos olhos Funções humanas: Dormir Acordar Comer Pegar algum transporte 4
Programação Orientada a Objeto Vimos anteriormente que as variáveis globais eram definidas no início do programa, podendo ser iniciadas na função setup(), ou mesmo na função draw(), e chamadas em outras funções. Na POO podemos definir as variáveis e as funções dentro do objeto. Vamos considerar o nosso exemplo do disco voador. O disco tem variáveis para cor, localização e velocidade. Além disso temos funções (métodos) para movimento e para ser mostrado. Vamos usar um pseudocódigo para expressar os conceitos da POO. Data (Global Variables): FlyingSaucer Object Setup: Draw: Initialize your flying-saucer object Fill background Display flying-saucer object Move flying-saucer object 5
Programa: flyingsaucer08.pde Abaixo temos o código sem usarmos POO. float x; // x location of flying saucer cockpit float y; // y location of flying saucer cockpit float r; // intensity for red float g; // intensity for green float b; // intensity for blue float speed; // flying saucer speed void setup() { size(200, 480); x = 100; y = 100; speed = 1; void draw() { background(255); display(20, 20); movey(); void display(float cockpitx, float cockpity) { float saucerx = cockpitx + 100.0; float saucery = cockpity; nostroke(); ellipsemode(center); r = random(1, 256); g = random(1, 256); b = random(1, 256); fill(color(r,g,b)); // Cockpit ellipse(x, y, cockpitx, cockpity); fill(175); // Saucer ellipse(x, y+10, saucerx, saucery); void movey() { y = y + speed; if (y > 480) { else if (y<0) { 6
Programa: flyingsaucer09.pde Agora temos o código usando POO à direita. float x; float y; float r; float g; float b; float speed; // x location of flying saucer cockpit // y location of flying saucer cockpit // intensity for red // intensity for green // intensity for blue // flying saucer speed void setup() { size(200, 480); x = 100; y = 100; speed = 1; void draw() { background(255); display(20, 20); movey(); void display(float cockpitx, float cockpity) { float saucerx = cockpitx + 100.0; float saucery = cockpity; nostroke(); ellipsemode(center); r = random(1, 256); g = random(1, 256); b = random(1, 256); fill(color(r,g,b)); // Cockpit ellipse(x, y, cockpitx, cockpity); fill(175); // Saucer ellipse(x, y+10, saucerx, saucery); void movey() { y = y + speed; if (y > 480) { else if (y<0) { class FlyingSaucer { float x; // x location of flying saucer cockpit float y; // y location of flying saucer cockpit float r; // intensity for red float g; // intensity for green float b; // intensity for blue float speed; // flying saucer speed FlyingSaucer() { x = 100; y = 100; speed = 1; Nome da classe Construtor void display(float cockpitx, float cockpity) { float saucerx = cockpitx + 100.0; float saucery = cockpity; nostroke(); ellipsemode(center); r = random(1, 256); g = random(1, 256); b = random(1, 256); fill(color(r,g,b)); // Cockpit ellipse(x, y, cockpitx, cockpity); fill(175); // Saucer ellipse(x, y+10, saucerx, saucery); void movey() { y = y + speed; if (y > 480) { else if (y<0) { Funcionalidade (Métodos) Dados 7
Programa: flyingsaucer09.pde class FlyingSaucer { float x; // x location of flying saucer cockpit float y; // y location of flying saucer cockpit float r; // intensity for red float g; // intensity for green float b; // intensity for blue float speed; // flying saucer speed FlyingSaucer() { x = 100; y = 100; speed = 1; Nome da classe Construtor void display(float cockpitx, float cockpity) { float saucerx = cockpitx + 100.0; float saucery = cockpity; nostroke(); ellipsemode(center); r = random(1, 256); g = random(1, 256); b = random(1, 256); fill(color(r,g,b)); // Cockpit ellipse(x, y, cockpitx, cockpity); fill(175); // Saucer ellipse(x, y+10, saucerx, saucery); void movey() { y = y + speed; if (y > 480) { else if (y<0) { Funcionalidade (Métodos) Dados Normalmente as classes apresentam o nome da classe, dados (variáveis), construtor e métodos. O nome da classe inicia com letra maiúscula, para diferenciar de variáveis e funções. Uma vez definido o nome da classe, abrimos as chaves. Tudo que estiver entre as chaves será considerado com pertencente à classe definida após a palavra class. Os dados são as variáveis da classe, são chamadas como variáveis de instanciação (instance variables), visto que cada instância de um objeto contém este conjunto de variáveis. O construtor funciona como a função setup(), só é chamado uma vez. É onde damos as instruções de como iniciar um objeto. A funcionalidade traz o(s) método(s) da classe. 8
Programa: flyingsaucer09.pde class FlyingSaucer { float x; // x location of flying saucer cockpit float y; // y location of flying saucer cockpit float r; // intensity for red float g; // intensity for green float b; // intensity for blue float speed; // flying saucer speed FlyingSaucer() { x = 100; y = 100; speed = 1; Nome da classe Construtor Dados Se tentarmos rodar a classe definida ao lado, nada irá acontecer. É análogo à função, se definirmos uma função e não a chamamos, nada acontece. Assim, temos que criar objetos da classe. A classe reside fora das funções setup() e draw(). void display(float cockpitx, float cockpity) { float saucerx = cockpitx + 100.0; float saucery = cockpity; nostroke(); ellipsemode(center); r = random(1, 256); g = random(1, 256); b = random(1, 256); fill(color(r,g,b)); // Cockpit ellipse(x, y, cockpitx, cockpity); fill(175); // Saucer ellipse(x, y+10, saucerx, saucery); void movey() { y = y + speed; if (y > 480) { else if (y<0) { Funcionalidade (Métodos) 9
Programa: flyingsaucer09.pde FlyingSaucer mysaucer; void setup(){ size(200,480); mysaucer = new FlyingSaucer(); void draw(){ background(255); mysaucer.movey(); mysaucer.display(20,20); class FlyingSaucer { float x; // x location of flying saucer cockpit float y; // y location of flying saucer cockpit float r; // intensity for red float g; // intensity for green float b; // intensity for blue float speed; // flying saucer speed FlyingSaucer() { x = 100; y = 100; speed = 1; Construtor void display(float cockpitx, float cockpity) { float saucerx = cockpitx + 100.0; float saucery = cockpity; nostroke(); ellipsemode(center); r = random(1, 256); g = random(1, 256); b = random(1, 256); fill(color(r,g,b)); // Cockpit ellipse(x, y, cockpitx, cockpity); fill(175); // Saucer ellipse(x, y+10, saucerx, saucery); void movey() { y = y + speed; if (y > 480) { else if (y<0) { Dados Funcionalidade (Métodos) Agora temos o programa completo, na primeira linha declaramos o objeto. É similar à declaração de variáveis globais, que fazemos na parte inicial do código, só que agora declaramos um objeto. Dentro da função setup() inicializamos o objeto, similar ao que fazemos com variáveis globais. Usamos a sintaxe: nomeobjeto = new nomeclasse(); O operador new constrói um novo objeto. Depois chamamos os métodos do objeto criado, em Processing é usado a notação dot para chamada de métodos. O novo código chama-se flyingsaucer09.pde 10
Argumento do Construtor Vamos considerar agora que queremos dois discos no nosso programa. Para podermos usar POO, temos que manter a mesma classe (FlyingSaucer) e criar dois objetos desta classe, ou seja, mantemos a forma de biscoito, e criarmos dois biscoitos distintos. Mas temos aqui um problema, se usarmos o código anterior (flying_saucer09.pde), e criarmos dois objetos, teremos dois objetos idênticos. Assim, temos que introduzir uma modificação no código, de forma que possamos passar valores para as variáveis das coordenadas x,y e da velocidade (speed). Fazemos isto criando-se um construtor com argumentos. O novo construtor fica como mostrado abaixo. Veja que temos argumentos agora, chamados argumentos do construtor. Esta é a única modificação que temos que fazer na classe FlyingSaucer. FlyingSaucer(float xin,float yin,float speedin) { x = xin; y = yin; speed = speedin; 11
Argumento do Construtor Agora criamos dois objetos da mesma classe, com nomes distintos, objetos mysaucer1 e mysaucer2. Na função setup() iniciamos os dois novos objetos. Veja que usamos parâmetros distintos, que serão passados para o construtor, o que leva a posições distintas, bem como velocidades, para os dois discos. Por último, os métodos para movimentar e desenhar são aplicados aos dois objetos, como indicado na função draw(). O restante do código (programa flying_saucer10.pde) não é mostrado, pois trata-se da definição da classe FlyingSaucer com a modificação no construtor indicado no slide anterior. FlyingSaucer mysaucer1; FlyingSaucer mysaucer2; void setup(){ size(200,480); mysaucer1 = new FlyingSaucer(60,50,1.2); mysaucer2 = new FlyingSaucer(100,100,1.0); void draw(){ background(255); mysaucer1.movey(); mysaucer2.movey(); mysaucer1.display(20,20); mysaucer2.display(20,20); 12
Exercício de Programação: flying_saucer11.pde Exercício de programação: Modifique o código do programa flying_saucer10.pde, de forma que tenhamos quatro discos voadores, todos com posições iniciais e velocidades distintas. 13
Exercício de Programação: flying_saucer12.pde Exercício de programação: Modifique o código do programa flying_saucer04.pde, para que siga o paradigma de programação orientada a objeto. 14
Exercício de Programação: flying_saucer13.pde Exercício de programação: Modifique o código do programa flying_saucer05.pde, para que siga o paradigma de programação orientada a objeto. 15
Exercício de Programação: flying_saucer14.pde Exercício de programação: Modifique o código do programa flying_saucer06.pde, para que siga o paradigma de programação orientada a objeto. 16
Exercício de Programação: flying_saucer15.pde Exercício de programação: Modifique o código do programa flying_saucer07.pde, para que siga o paradigma de programação orientada a objeto. 17
Exercício de Programação: flying_saucer16.pde Exercício de programação: Modifique o código do programa flying_saucer15.pde, de forma que tenhamos dois discos voadores no jogo. 18
Referências -MODEL, Mitchell L. Bioinformatics Programming Using Python. Sebastopol: O Reilly Media, Inc., 2011. 1584 p. -REAS, Casey & FRY, Bem. Geeting Started with Processing. Sebastopol: O Reilly Media, Inc., 2010. 194 p. -SHIFFMAN, Daniel. Learning Processing. A Beginner s Guide to Programming Images, Animation, and Interaction. Burlington: Morgan Kaufmann, 2008. 453 p. -SHIFFMAN, Daniel. The Nature of Code: Simulating Natural Systems with Processing. Mountain View: The Nature of Code, 2012. 498 p. Última atualização: 13 de setembro de 2015. 19