Laura Lemay
A programação orientada ao objeto (OOP) é uma das ideias de programação mais grandes dos últimos anos, e poderia preocupar-se que deva passar anos aprendendo todos sobre metodologias de programação orientadas ao objeto e como podem fazer a sua vida mais fácil do que O Velho Modo de programar. Tudo isso alcança a organização dos seus programas de modos que repercutem como as coisas se juntam no mundo real.
Hoje adquirirá um resumo de conceitos de programação orientados ao objeto em Java e como se relacionam a como estrutura os seus próprios programas:
Se já for familiar com a programação orientada ao objeto, a maior parte da lição de hoje será velho chapéu para você. Pode querer escumá-lo e ir a um filme hoje em vez disso. Amanhã, entrará em detalhes mais específicos.
Considere, se vai, Legos. Legos, para aqueles que não passam muito tempo com crianças, são pequenos blocos de edifício plásticos em várias cores e tamanhos. Têm pequenos bits redondos em um lado que se ajustam em pequenos buracos redondos em outro Legos para que se ajustem em conjunto confortavelmente para criar formas maiores. Com partes de Lego diferentes (rodas de Lego, motores de Lego, dobradiças de Lego, roldanas de Lego), pode juntar castelos, automóveis, robôs gigantescos que engolem cidades, ou quase algo mais que pode imaginar. Cada parte Lego é um pequeno objeto que se ajusta em conjunto com outros pequenos objetos de modos predestinados de criar outros objetos maiores. É rudemente como a programação orientada ao objeto trabalha: reunião de mais pequenos elementos para construir maiores.
Aqui está outro exemplo. Pode andar em uma loja de informática e, com um pequeno contexto e muitas vezes alguma ajuda, reunir um sistema de computador de PC inteiro de vários componentes: uma placa mãe, um pedaço de CPU, uma placa de vídeo, um disco rígido, um teclado, e assim por diante. De maneira ideal, quando termina de reunir todas várias unidades reservadas, tem um sistema no qual todas as unidades colaboram para criar um sistema maior com o qual pode resolver os problemas pelos quais comprou o computador em primeiro lugar.
Interiormente, cada um daqueles componentes pode complicar-se vastamente e projetar-se por companhias diferentes com métodos diferentes do desenho. Mas não precisa de saber como o componente trabalha, o que cada pedaço no conselho faz, ou como, quando aperta Uma chave, um A se envia ao seu computador. Como o assembler do sistema total, cada componente que usa é uma unidade reservada e tudo no qual se interessa é como as unidades interagem um com outro. Esta placa de vídeo vai se ajustar nas fendas na placa mãe, e isto controlará o trabalho com esta placa de vídeo? Cada determinado componente falará as ordens direitas a outros componentes com que interage para que cada parte do computador se entenda por cada outra parte? Uma vez que sabe o que as interações estão entre os componentes e podem combinar com as interações, reunir o sistema total é fácil.
O que isto tem a ver com programação? Tudo. A programação orientada ao objeto trabalha de exatamente este mesmo modo. Usando a programação orientada ao objeto, o seu programa total compõe-se de muitos componentes reservados diferentes (objetos), cada um dos quais tem um papel específico no programa e todos dos quais podem falar um com outro de modos predestinados.
A programação orientada ao objeto modela-se em como, no mundo real, os objetos muitas vezes se compõem de muitas espécies de mais pequenos objetos. Esta capacidade de combinar objetos, contudo, é só um aspecto muito geral da programação orientada ao objeto. A programação orientada ao objeto fornece vários outros conceitos e características para fazer a criação e a utilização de objetos mais fáceis e mais flexíveis, e a mais importante destas características é classes.
Quando escreve um programa em uma língua orientada ao objeto, não define objetos reais. Define classes de objetos, onde uma classe é um padrão de múltiplos objetos com características semelhantes. As classes personificam todas as características de um determinado jogo de objetos. Por exemplo, poderia ter uma classe de Tree que descreve as características de todas as árvores (tem folhas e raízes, cresce, cria a clorofila). A classe de Tree serve de um modelo abstrato do conceito de uma árvore - para estender a mão para pegar e agarrar, ou interagir, ou reduzir uma árvore tem de ter um exemplo concreto daquela árvore. Naturalmente, uma vez que tem uma classe de árvore, pode criar muitos exemplos diferentes daquela árvore, e cada exemplo de árvore diferente pode ter características diferentes (curto, alto, fechado, folhas de baixas no outono), se comportando ainda como e sendo imediatamente reconhecível como uma árvore (ver a Figura 2.1).
A figura 2.1: A classe de Árvore e vários exemplos de Árvore.
Novo termo |
Uma classe é um padrão genérico do grupo de objetos com características semelhantes. |
Um exemplo de uma classe é outra palavra de um objeto real. Se a classe for a representação geral (genérica) de um objeto, um exemplo é a sua representação concreta. Assim, qual, precisamente, é a diferença entre um exemplo e um objeto? Nada, realmente. O objeto é o termo mais geral, mas tanto os exemplos como os objetos são a representação concreta de uma classe. De fato, os termos exemplo e objeto muitas vezes usam-se de modo trocável no jargão OOP. Um exemplo de uma árvore e um objeto de árvore é ambos a mesma coisa.
Novo termo |
Um exemplo é a representação concreta específica de uma classe. Os exemplos e os objetos são a mesma coisa. |
Que tal um exemplo mais perto ao tipo de coisas poderia querer fazer na programação de Java? Poderia criar uma classe do elemento de interface de usuário chamado um botão. A classe de Button define as características de um botão (a sua etiqueta, o seu tamanho, a sua aparência) e como se comporta. (Precisa de um clique único ou clicar duas vezes para ativá-lo? Modifica a cor quando se clica? O que faz quando se ativa?) Depois que define a classe de Button, então pode criar facilmente exemplos daquele botão - isto é, objetos de botão - que todos empreendem as características básicas do botão como definido pela classe, mas podem ter aparecimentos diferentes e comportamento baseado no que quer que aquele determinado botão faça. Criando uma classe de Button, não tem de continuar reescrevendo o código de cada botão individual que quer usar no seu programa, e pode reutilizar a classe de Button para criar tipos diferentes de botões como precisa deles neste programa e em outros programas.
Ponta |
Se estiver acostumado a programar em C, pode pensar em uma classe como tipo de criar um novo tipo de dados composto usando struct e typedef. As classes, contudo, podem prover muito mais do que somente uma coleção de dados, como descobrirá no resto da lição de hoje. |
Quando escreve um programa Java, projeta e constrói o grupo de classes. Então quando o seu programa corre, os exemplos daquelas classes criam-se e descartam-se como necessário. A sua tarefa, como um programador de Java, é criar o jogo direito de classes para realizar o que o seu programa tem de realizar.
Afortunadamente, não tem de começar do mesmo começo: O ambiente de Java vem com um conjunto padrão de classes (chamou uma biblioteca de classe) que implementam muito comportamento básico do qual precisa - não só para tarefas de programação básicas (classes para fornecer funções matemáticas básicas, tabelas, cadeias, e assim por diante), mas também para gráfica e ligação em rede de comportamento. Em muitos casos, as bibliotecas de classe de Java podem ser bastante para que tudo que tem de fazer no seu programa Java seja criam uma classe única que usa as bibliotecas de classe padrão. Para programas Java complicados, deveria criar um jogo inteiro de classes com interações definidas entre eles.
Novo termo |
Uma biblioteca de classe é uma coleção de classes destinadas para reutilizar-se repetidamente em programas diferentes. As bibliotecas de classe de Java padrão contêm várias classes para realizar tarefas de programação básicas em Java. |
Cada classe que escreve em Java tem duas características básicas: atributos e comportamento. Nesta seção aprenderá sobre cada um como aplica a uma classe simples teórica chamada Motorcycle. Para terminar esta seção, criará o código de Java para implementar uma representação de uma motocicleta.
Os atributos são as coisas individuais que diferenciam um objeto do outro e determinam a aparência, estado ou outras qualidades daquele objeto. Vamos criar uma classe teórica chamada Motorcycle. Uma classe de motocicleta poderia incluir os seguintes atributos e ter estes valores típicos:
Os atributos de um objeto também podem incluir a informação sobre o seu estado; por exemplo, pode ter características da condição de motor (de ou em) ou engrenagem atual selecionada.
Os atributos definem-se em classes por variáveis. Os tipos daquelas variáveis e os nomes definem-se na classe, e cada objeto pode ter os seus próprios valores daquelas variáveis. Como cada exemplo de uma classe pode ter valores diferentes das suas variáveis, estas variáveis muitas vezes chamam-se variáveis de exemplo.
Novo termo |
Uma variável de exemplo define os atributos do objeto. Os tipos de variáveis de exemplo e os nomes definem-se na classe, mas os seus valores se estabelecem e se modificam no objeto. |
As variáveis de exemplo podem estabelecer-se inicialmente quando um objeto se cria e fique constante durante a vida do objeto, ou podem ser capazes de modificar-se à vontade quando o programa corre. Modifique o valor da variável, e modifica atributos de um objeto.
Além de variáveis de exemplo, também há as variáveis de classe, que aplicam à própria classe e a todos os seus exemplos. Diferentemente de variáveis de exemplo, cujos valores se guardam no exemplo, os valores de variáveis de classe guardam-se na própria classe. Aprenderá sobre variáveis de classe mais tarde nesta semana e mais especificação sobre variáveis de exemplo amanhã.
O comportamento de uma classe determina como um exemplo daquela classe funciona; por exemplo, como "reagirá" se perguntado fazer algo por outra classe ou objeto ou se o seu estado interno se modificar. O comportamento é o único modo que os objetos podem fazer-se algo ou mandar fazer algo para eles. Por exemplo, para voltar à classe de Motorcycle teórica, aqui estão alguns comportamentos que a classe de Motorcycle poderia ter:
Para definir o comportamento de um objeto, cria métodos, grupo de afirmações de Java que realizam alguma tarefa. Os métodos olham e comportam-se como funções em outras línguas mas definem-se e acessíveis sozinho dentro de uma classe. Java não tem funções definidas do lado de fora de classes (como C ++ faz).
Novo termo |
Os métodos são funções definidas dentro de classes que produzem exemplos daquelas classes. |
Enquanto os métodos podem usar-se sozinho para produzir um objeto individual, os métodos também se usam entre objetos de comunicar-se um com outro. Uma classe ou um objeto podem chamar métodos em outra classe ou objetar para comunicar modificações no ambiente ou pedir que objeto de modificar o seu estado.
Tal como há exemplo e as variáveis de classe, também há o exemplo e os métodos de classe. Os métodos de exemplo (que são tanto comum que somente os chamam normalmente métodos) aplicam-se e produzem um exemplo de uma classe; os métodos de classe aplicam-se e produzem a própria classe. Aprenderá mais sobre métodos de classe mais tarde nesta semana.
Até este ponto, a lição de hoje foi bastante teórica. Nesta seção, criará um exemplo de trabalho da classe de Motorcycle para que possa ver como as variáveis de exemplo e os métodos se definem em uma classe em Java. Também criará uma aplicação de Java que cria um novo exemplo da classe de Motorcycle e mostra as suas variáveis de exemplo.
Observar |
Não vou entrar em muito detalhe sobre a sintaxe real deste exemplo aqui. Não se incomode demasiado com ele se não estiver realmente seguro o que está acontecendo; ficará claro para você mais tarde nesta semana. Tudo com o qual realmente tem de incomodar-se neste exemplo está entendendo as partes básicas desta definição de classe. |
Pronto? Vamos começar com uma definição de classe básica. Abra o editor de texto que tem usado para criar o texto fonte de Java e entrar o seguinte (lembre-se, superior - e matérias em letras minúsculas):
class Motorcycle { }
Congratulações! Criou agora uma classe. Naturalmente, não faz muito no momento atual, mas isto é uma classe de Java no seu muito o mais simples.
Em primeiro lugar, vamos criar algumas variáveis de exemplo desta classe três deles, vamos ser específicos. Somente em baixo da primeira linha, acrescente três seguintes linhas:
String make; String color; boolean engineState = false;
Aqui criou três variáveis de exemplo: Dois, make e color, pode conter objetos de String (uma cadeia é o termo genérico de uma série de carateres; String, com a capital S, é parte daquela biblioteca de classe padrão mencionou antes). O terceiro, engineState, é uma variável de boolean que se refere a se o motor é desligado ou ligado; um valor de false significa que o motor é desligado, e true significa que o motor é ligado. Observe que booleano é letra minúscula b.
Novo termo |
Um booleano é um valor de verdadeiro ou de falso. |
Nota técnica |
boolean em Java é um verdadeiro tipo de dados que pode ter os valores true ou false. Diferentemente de em C, os booleans não são números. Ouvirá sobre isto novamente amanhã para que não se esqueça. |
Agora vamos acrescentar algum comportamento (métodos) à classe. Há todas espécies de coisas que uma motocicleta pode fazer, mas guardar coisas curtas, vamos acrescentar somente um método de método-a que começa o motor. Acrescente as seguintes linhas em baixo das variáveis de exemplo na sua definição de classe:
void startEngine() { if (engineState == true) System.out.println("The engine is already on."); else { engineState = true; System.out.println("The engine is now on."); } }
O método de startEngine() testa para ver se o motor já corre (na parte engineState == true) e, se for, simplesmente imprime uma mensagem para aquele efeito. Se o motor já não estiver correndo, modifica o estado do motor a true (acendendo o motor) e logo imprime uma mensagem. Finalmente, porque o método de startEngine() não devolve um valor, a sua definição inclui o vazio de palavra no começo. (Também pode definir métodos a valores de retorno; aprenderá mais sobre definições de método no Dia 6, "Criando Classes e Aplicações em Java".)
Ponta |
Aqui e em todas as partes deste livro, sempre que me refira ao nome de um método, acrescentarei parênteses vazios ao fim do nome (por exemplo, como fiz na primeira frase do parágrafo prévio: "O método de startEngine() …" Isto é uma convenção usada na comunidade de programação em liberdade para indicar que um determinado nome é um método e não uma variável. Os parênteses são silenciosos. |
Com os seus métodos e variáveis no lugar, salve o programa a um arquivo chamado Motorcycle.java (lembre-se de que sempre deve denominar os seus arquivos originais de Java os mesmos nomes que a classe que definem). A listagem 2.1 mostra a que o seu programa deve parecer por enquanto.
A listagem 2.1. O arquivo de Motorcycle.java.
1:class Motorcycle { 2: 3: String make; 4: String color; 5: boolean engineState = false; 6: 7: void startEngine() { 8: if (engineState == true) 9: System.out.println("The engine is already on."); 10: else { 11: engineState = true; 12: System.out.println("The engine is now on."); 13: } 14: } 15:}
Ponta |
A denteação de cada parte da classe não é importante para o compilador de Java. Usar alguma forma da denteação, contudo, faz a sua definição de classe mais fácil para você e outras pessoas para ler. A denteação usada aqui, com variáveis de exemplo e métodos encomendou da definição de classe, é o estilo usado em todas as partes deste livro. As bibliotecas de classe de Java usam uma denteação semelhante. Pode escolher qualquer estilo de denteação de que você gosta. |
Antes que compile esta classe, vamos acrescentar um mais método somente em baixo do método de startEngine() (isto é, entre linhas 14 e 15). O método de showAtts() usa-se para imprimir os valores atuais de todas as variáveis de exemplo em um exemplo da sua classe de Motorcycle. Aqui está a que parece:
void showAtts() { System.out.println("This motorcycle is a " + color + " " + make); if (engineState == true) System.out.println("The engine is on."); else System.out.println("The engine is off."); }
O método de showAtts() imprime duas linhas para a tela: o make e color da motocicleta objetam e se o motor é ligado ou desligado.
Agora tem uma classe de Java com três variáveis de exemplo e dois métodos definidos. Salve aquele arquivo novamente e compile-o usando um dos seguintes métodos:
Observar |
Depois deste ponto, vou supor que saiba como compilar e dirigir programas Java. Não repetirei esta informação depois disto. |
Windows |
Do interior de uma concha de DOS, CD ao diretório que contém o seu arquivo original de Java e uso a ordem de javac de compilar ele: |
javac Motorcycle.java
Macintosh |
Arraste e deixe o arquivo de Motorcycle.java para o ícone Java Compiler. |
Salaris |
De uma linha de comando, CD ao diretório que contém o seu arquivo original de Java e uso a ordem de javac de compilar ele: |
javac Motorcycle.java
Quando dirigir este pequeno programa usando os programas java ou Java Runner, adquirirá um erro. Porque? Quando dirige uma classe de Java compilada diretamente, Java supõe que a classe seja uma aplicação e procure um método de main(). Como não definimos um método de main() dentro da classe, o intérprete de Java (java) dá-lhe um erro algo como um destes dois erros:
In class Motorcycle: void main(String argv[]) is not defined Exception in thread "main": java.lang.UnknownError
Fazer algo com a classe por exemplo de Motorcycle, criar exemplos daquela classe e jogar com eles-you're indo criar Java separado applet ou aplicação que usa esta classe ou acrescenta um método de main() a este. Para a causa de simplicidade, vamos fazer o último. A listagem 2.2 mostra o método de main() que acrescentará à classe de Motorcycle. Quererá acrescentar este método ao seu arquivo original de Motorcycle.java justo antes da tira final última (}), embaixo de métodos de showAtts() e o startEngine().
A listagem 2.2. O método de main() de Motorcycle.java.
1: public static void main (String args[]) { 2: Motorcycle m = new Motorcycle(); 3: m.make = "Yamaha RZ350"; 4: m.color = "yellow"; 5: System.out.println("Calling showAtts..."); 6: m.showAtts(); 7: System.out.println("--------"); 8: System.out.println("Starting engine..."); 9: m.startEngine(); 10: System.out.println("--------"); 11: System.out.println("Calling showAtts..."); 12: m.showAtts(); 13: System.out.println("--------"); 14: System.out.println("Starting engine..."); 15: m.startEngine(); 16:}
Com o método de main() no lugar, a classe de Motorcycle é agora uma aplicação oficial, e pode compilá-lo novamente e esta vez correrá. Aqui está como a produção deve olhar:
A primeira linha declara o método de main(). A primeira linha do método de main() sempre parece a isto; aprenderá a especificação de cada parte depois nesta semana. A linha 2, Motorcycle m = new Motorcycle();, cria um novo exemplo da classe de Motorcycle e guarda uma referência para ele no m variável. Lembre-se, não produz normalmente diretamente classes nos seus programas Java; em vez disso, cria objetos daquelas classes e logo chama métodos naqueles objetos. As linhas 3 e 4 estabelecem as variáveis de exemplo deste objeto de Motorcycle: fazer é agora um Yamaha RZ350 (uma motocicleta muito bonita de meados dos anos 1980), e a cor é yellow. As linhas 5 e 6 chamam o método de showAtts(), definido no seu objeto de Motorcycle. (De fato, só 6 fazem; 5 somente impressões uma mensagem que está a ponto chamada este método.) O novo objeto de motocicleta então imprime os valores das suas variáveis de exemplo - o make e color como estabelece nas linhas prévias - e mostra que o motor é desligado. Linha 7 impressões uma linha de divisor à tela; isto é somente para a mais bonita produção. A linha 9 chamadas o método de startEngine() na motocicleta objeta para começar o motor. O motor deve ser ligado agora. Linha 11 impressões os valores das variáveis de exemplo novamente. Esta vez, o relatório deve dizer que o motor é ligado agora. Linha 15 tentativas de começar o motor novamente, somente para o divertimento. Como o motor já é ligado, isto deve imprimir a mensagem The engine is already on. A listagem 2.3 mostra a classe de Motorcycle final, em caso de que tem tido preocupação compilando e dirigindo aquele tem (e lembre-se, este exemplo e todos os exemplos neste livro estão disponíveis no CD que acompanha o livro): Agora que tem um aperto básico de classes, objetos, métodos, variáveis, e como pôr todos eles em conjunto em um programa Java, é tempo de confundi-lo novamente. A herança, as interfaces e os pacotes são todos os mecanismos para organizar comportamentos de classe e classes. As bibliotecas de classe de Java usam todos estes conceitos, e as melhores bibliotecas de classe que escreve para os seus próprios programas também usarão estes conceitos. A herança é um dos conceitos mais cruciais na programação orientada ao objeto, e tem um efeito muito direto sobre como projeta e escreve as suas classes de Java. A herança é um mecanismo potente que significa quando escreve uma classe só tem de especificar como aquela classe é diferente de alguma outra classe; a herança lhe dará o acesso automático à informação contida naquela outra classe. Com a herança, todas as classes - aqueles escreve, aqueles de outras bibliotecas de classe que usa, e aqueles das classes de serviço padrão também - arranjam-se em uma hierarquia estrita (ver a Figura 2.2). Cada classe tem uma superclasse (a classe acima dele na hierarquia), e cada classe pode ter uma ou várias subclasses (classes em baixo daquela classe na hierarquia). Diz-se que as classes além disso abaixo na hierarquia herdem de classes além disso na hierarquia.
A figura 2.2: Uma hierarquia de classe.
As subclasses herdam todos os métodos e variáveis das suas superclasses - isto é, em qualquer determinada classe, se a superclasse definir o comportamento de que a sua classe precisa, não tem de redefini-lo ou cópia que codificam de alguma outra classe. A sua classe automaticamente adquire aquele comportamento da sua superclasse, aquela superclasse adquire o comportamento da sua superclasse, e assim por diante durante todo o tempo a hierarquia. A sua classe torna-se uma combinação de todas as características das classes acima dele na hierarquia.
Em cima de Java a hierarquia de classe é a classe Object; todas as classes herdam desta superclasse. Object é a classe mais geral na hierarquia; define o comportamento herdado por todas as classes de Java. Cada classe além disso abaixo na hierarquia acrescenta mais informação e fica mais talhada a um objetivo específico. Deste modo, pode pensar em uma hierarquia de classe como definição de conceitos muito abstratos em cima da hierarquia e aquelas ideias que ficam mais concreto o mais longe abaixo a cadeia de superclasses vai. A maior parte do tempo quando escreve novas classes de Java, quererá criar uma classe que tem toda a informação que alguma outra classe tem, mais alguma extra informação. Por exemplo, pode querer uma versão de um Button com a sua própria etiqueta construída. Para adquirir toda a informação de Button, tudo que tem de fazer é definem a sua classe para herdar de Button. A sua classe adquirirá automaticamente todo o comportamento definido em Button (e em superclasses de Button), portanto tudo com o qual tem de incomodar-se é as coisas que fazem a sua classe diferente de próprio Button. Este mecanismo para definir novas classes como as diferenças entre eles e as suas superclasses chama-se subclassificando. A subclassificação implica a criação de uma nova classe que herda de alguma outra classe na hierarquia de classe. Usando a subclassificação, só tem de definir as diferenças entre a sua classe e o seu pai; o comportamento adicional está tudo disponível para a sua classe por meio da herança.
E se a sua classe define um comportamento inteiramente novo e não é realmente uma subclasse de outra classe? A sua classe também pode herdar diretamente de Object, que ainda lhe permite ajustar-se asseadamente na hierarquia de classe de Java. De fato, se cria uma definição de classe que não indica a sua superclasse na primeira linha, Java automaticamente supõe que esteja herdando de Object. A classe de Motorcycle criou na seção prévia herdada de Object. Se estiver criando um jogo maior de classes de um programa muito complexo, faz sentido para as suas classes não só para herdar da hierarquia de classe existente, mas também compor uma hierarquia elas mesmas. Isto pode tomar algum planejamento anteriormente quando tenta compreender como organizar o seu código de Java, mas as vantagens são significantes uma vez que se faz: Por exemplo, vamos atrás a que a classe de Motorcycle e finge criou um programa Java para implementar todas as características de uma motocicleta. Faz-se, trabalha, e tudo é perfeito. Agora, a sua seguinte tarefa é criar uma classe de Java chamada Car.
Car e Motorcycle têm muitas características semelhantes - ambos são transportes dirigidos por motores. Ambos têm transmissões, faróis e velocímetros. Portanto o seu primeiro impulso pode ser de abrir o seu arquivo de classe de Motorcycle e cópia sobre muita informação já definiu na nova classe Car. Um plano muito melhor é ao fator fora a informação comum de Car e Motorcycle em uma hierarquia de classe mais geral. Isto pode ser muito trabalho somente das classes Motorcycle e Car, mas uma vez que acrescenta Bicycle, Scooter, Truck, e assim por diante, tendo comportamento comum em uma superclasse reutilizável significativamente reduz o volume de trabalho que tem de fazer em geral. Vamos projetar uma hierarquia de classe que poderia servir este objetivo. O começo em cima é a classe Object, que é a raiz de todas as classes de Java. A classe mais geral à qual uma motocicleta e um carro ambos pertencem poderia chamar-se Vehicle. Um veículo, geralmente, define-se como uma coisa que propele alguém de um lugar ao outro. Na classe de Vehicle, só define o comportamento que permite a alguém se propelir do ponto um para apontar b e nada mais. Em baixo de Vehicle? E duas classes: PersonPoweredVehicle e EnginePoweredVehicle? EnginePoweredVehicle é diferente de Vehicle porque tem um motor, e os comportamentos poderiam incluir a paragem e o começo do motor, tendo certos montantes de gasolina e óleo, e possivelmente a velocidade ou engrenagem na qual o motor corre. Os transportes acionados pelas pessoas têm uma espécie de mecanismo para traduzir o movimento das pessoas para pedais do movimento de veículo, por exemplo. A figura 2.3 mostra o que tem por enquanto.
A figura 2.3: A hierarquia de veículo básica.
Agora vamos ficar até mais específicos. Com EnginePoweredVehicle, poderia ter várias classes: Motorcycle, Car, Truck, e assim por diante. Ou pode o fator fora ainda mais comportamento e ter classes intermediárias de TwoWheeled e transportes de FourWheeled, com comportamentos diferentes para cada um (ver a Figura 2.4).
A figura 2.4: transportes de duas rodas e com quatro rodas.
Finalmente, com uma subclasse dos transportes acionados pelo motor de duas rodas, pode ter uma classe de motocicletas. Alternativamente, pode definir adicionalmente patinetes e motocicletas, ambas as quais são transportes acionados pelo motor de duas rodas mas têm qualidades diferentes de motocicletas. Onde fazem qualidades tais que fazem ou colorem entram? Onde quer que queira que eles vão - ou, mais normalmente, onde se ajustam o mais naturalmente na hierarquia de classe. Pode definir fazer e cor em Vehicle, e todas as subclasses terão aquelas variáveis também. O ponto para lembrar-se é que tem de definir uma característica ou um comportamento só uma vez na hierarquia; reutiliza-se automaticamente por cada subclasse. Como a herança trabalha? Como é que os exemplos de uma classe podem adquirir automaticamente variáveis e métodos das classes além disso na hierarquia? Por exemplo variáveis, quando cria um novo exemplo de uma classe, adquire uma "fenda" de cada variável definida na classe atual e para cada variável definida em todas as suas superclasses. Deste modo, toda a associação de classes para formar um padrão do objeto atual, e logo cada objeto preenche a informação apropriada para a sua situação. Os métodos funcionam de mesmo modo: os novos objetos têm o acesso a todos os nomes de método da sua classe e as suas superclasses, mas as definições de método se escolhem dinamicamente quando se chama um método. Isto é, se chamar um método em um determinado objeto, Java primeiro verifica a classe do objeto a definição daquele método. Se não se definir na classe do objeto, olha na superclasse daquela classe, e assim por diante a cadeia até que a definição de método se encontre (ver a Figura 2.5).
A figura 2.5: Como os métodos se localizam.
As coisas complicam-se quando uma subclasse define um método que tem a mesma assinatura (nome, número e tipo de argumentos) como um método definido em uma superclasse. Neste caso, a definição de método que se encontra primeira (começando no fundo e trabalhando para cima em direção ao topo da hierarquia) é aquela que se realiza de fato. Por isso, pode definir intencionalmente um método em uma subclasse que tem a mesma assinatura que um método em uma superclasse, que então "esconde" o método da superclasse. Isto chama-se ignorando um método. Aprenderá todos sobre métodos no Dia 7, "mais sobre Métodos".
A figura 2.6: métodos primordiais.
A forma de Java da herança, como aprendeu nas seções prévias, chama-se a herança única. A herança única significa que cada classe de Java pode ter só uma superclasse (embora qualquer superclasse dada possa ter múltiplas subclasses). Em outras linguagens de programação orientadas ao objeto, como C ++, as classes podem ter mais de uma superclasse, e herdam variáveis combinadas e métodos de todas aquelas classes. Isto chama-se múltipla herança. Múltipla herança pode fornecer o poder enorme quanto a ser capaz de criar classes que o fator quase todo o comportamento imaginável, mas também pode complicar significativamente definições de classe e o código para produzi-los. Java faz a herança mais simples se só isoladamente herdado. Há dois conceitos restantes para discutir aqui: pacotes e interfaces. Ambos são tópicos promovidos para implementar e projetar grupos de comportamento de classe e classes. Aprenderá tanto sobre interfaces como sobre pacotes no Dia 16, "Os pacotes e as Interfaces", mas pelo menos valem a pena introduzir aqui. Lembre que cada classe de Java tem só uma superclasse única, e herda variáveis e métodos daquela superclasse e todas as suas superclasses. Embora a herança única faça a relação entre classes e a funcionalidade que aquelas classes implementam fácil entender e projetar, também pode ser um tanto restritivo - especialmente, quando tem o comportamento semelhante que tem de duplicar-se através de "ramos" diferentes da hierarquia de classe. Java resolve este problema do comportamento compartilhado usando o conceito de interfaces, que reúnem nomes de método em um lugar e logo lhe permitem acrescentar aqueles métodos como um grupo a várias classes que precisam deles. Observe que as interfaces só contêm nomes de método e interfaces (argumentos, por exemplo), não definições reais. Embora uma classe de Java única possa ter só uma superclasse (devido à herança única), aquela classe também pode implementar qualquer número de interfaces. Implementando uma interface, uma classe fornece implementações de método (definições) para os nomes de método definidos pela interface. Se duas classes muito desiguais implementarem a mesma interface, podem responder ambos às mesmas chamadas de método (que definido por aquela interface), embora o que cada classe de fato faz em resposta àquelas chamadas de método possa ser muito diferente.
Não precisa de saber muito sobre interfaces agora mesmo. Aprenderá mais enquanto o livro progride, portanto se tudo isso for muito confuso, não apavore! O novo conceito de Java final para hoje é pacotes. Os pacotes em Java são um modo de agrupar classes relacionadas e interfaces em uma biblioteca única ou coleção. Os pacotes permitem a grupos modulares de classes estar só disponíveis se forem necessários e eliminarem conflitos potenciais entre nomes de classe em grupos diferentes de classes. Aprenderá todos sobre pacotes, inclusive como criá-los e usá-los, na Semana 3. Por agora, há só algumas coisas que tem de saber: Para terminar hoje, vamos criar uma classe que é uma subclasse de outra classe e ignore alguns métodos. Também adquirirá uma sensação básica para como os pacotes trabalham neste exemplo. Provavelmente o exemplo mais típico de criar uma subclasse, pelo menos quando primeiro começa a programar em Java, cria um applet. Todos os applets são as subclasses da classe Applet (que é parte do pacote de java.applet). Criando uma subclasse de Applet, automaticamente adquire todo o comportamento da caixa de ferramentas de janela e as classes de leiaute que permitem ao seu applet desenhar-se no lugar certo na página e interagir com operações de sistema, como cliques de rato e keypresses. Neste exemplo, criará um semelhante applet ao Olá Mundo applet de ontem, mas aquele que desenha a cadeia de Hello em uma fonte maior e uma cor diferente. Para começar este exemplo, vamos construir primeiro a própria definição de classe. Vamos ao seu editor de texto, e entram na seguinte definição de classe: Aqui, cria uma classe chamada HelloAgainApplet. Observe a parte que diz o-that's de extends java.applet.Applet a parte que diz que a sua classe applet é uma subclasse da classe de Applet. Observe que porque a classe de Applet se contém no pacote de java.applet, não tem acesso automático àquela classe, e tem de referir-se a ele explicitamente por nome de classe e pacote. Outra parte desta definição de classe é a palavra-chave de public. O público subentende que a sua classe está disponível para o sistema de Java em liberdade uma vez que se carrega. A maior parte do tempo tem de fazer uma classe public só se quiser que ele seja visível a todas as outras classes no seu programa Java, mas deve declarar-se que applets, especialmente, seja público. (Aprenderá mais sobre classes de public na Semana 3.) Uma definição de classe com nada nela realmente não tem a maior parte de um ponto; sem acrescentar ou ignorar alguma de variáveis das suas superclasses ou métodos, não há razão de criar uma subclasse em absoluto. Vamos acrescentar alguma informação a esta classe, dentro das duas tiras de cerrado, vamos fazê-lo diferente da sua superclasse. Em primeiro lugar, acrescente uma variável de exemplo para conter um objeto de Font: A variável de exemplo de f agora contém um novo exemplo da classe Font, parte do pacote de java.awt. Este determinado objeto de Font é uma fonte romana de Tempos, tipo negrito, 36 pontos altos. No prévio Olá Mundo applet, a fonte usada para o texto foi a fonte à revelia: romano de Tempos de 12 pontos. Usando um objeto de Font, pode modificar a fonte do texto que desenha no seu applet. Criando uma variável de exemplo para manter este objeto de fonte, põe-no à disposição de todos os métodos na sua classe. Agora vamos criar um método que o usa. Quando escreve applets, há vários métodos "padrão" definidos nas superclasses applet que ignorará comumente na sua classe applet. Estes incluem métodos para inicializar o applet, fazê-lo começar a correr, tratar operações como movimentos de rato ou cliques de rato, ou limpar quando o applet deixa de correr. Um daqueles métodos padrão é o método de paint(), que de fato expõe o seu applet onscreen. A definição à revelia de paint() não faz nada-it's um método vazio. Ignorando paint(), diz o applet somente que atrair a tela. Aqui está uma definição de paint(): Há duas coisas a saber sobre o método de paint(). Em primeiro lugar, observe que este método se declara por public, como o próprio applet foi. O método de paint() é de fato public por uma razão diferente - porque o método é primordial também é public. Se o método de uma superclasse se definir como public, o seu ignorar o método também tem de ser public, ou adquirirá um erro quando compila a classe. Em segundo lugar, observe que o método de paint() toma um argumento único: um exemplo da classe de Graphics. A classe de Graphics fornece o comportamento independente da plataforma para dar fontes, cores e comportamento para desenhar linhas básicas e formas. Aprenderá muito mais sobre a classe de Graphics na Semana 2, quando criar applets mais extenso. Dentro do seu método de paint(), fez três coisas: Para um applet isto simples, isto é tudo que tem de fazer. Aqui está a que o applet parece por enquanto: Se tenha prestado a atenção fechada, notará que algo está enganado com este exemplo até este ponto. Se não souber qual é, tente salvar este arquivo (lembre-se, salve-o ao mesmo nome que a classe: HelloAgainApplet.java) e compilação dele. Deve adquirir um ramo de erros semelhantes a este: Porque adquire estes erros? Como as classes às quais se refere nesta classe, como Graphics e Font, são parte de um pacote que não está disponível à revelia. Lembre-se de que o único pacote ao qual tem o acesso automaticamente nos seus programas Java é java.lang. Mencionou a classe de Applet na primeira linha da definição de classe referindo-se ao seu nome de pacote cheio (java.applet.Applet). Além disso em no programa, contudo, mencionou todas as espécies de outras classes como se estivessem disponíveis. O compilador pega isto e diz-lhe que não tem acesso àquelas outras classes. Há dois modos de resolver este problema: Refira-se a todas as classes externas pelo pacote cheio denominam ou importam a classe apropriada ou pacote no início do seu arquivo de classe. Que que decide fazer é pela maior parte uma matéria da escolha, embora se se encontrar que se refere a uma classe em outro pacote muitos tempos, possa querer importá-lo para reduzir no montante da datilografia. Neste exemplo, importará as classes das quais precisa. Há três deles: Graphics, Font e Color. Todos os três são parte do pacote de java.awt. Aqui estão as linhas para importar estas classes. Estas linhas vão em cima do seu programa, antes da definição de classe real:
Agora, com as classes próprias importadas para o seu programa, HelloAgainApplet.java deve compilar limpamente a um arquivo de classe. A listagem 2.4 mostra a versão final para reexaminar. Para testá-lo, crie um arquivo de HTML com a etiqueta de <APPLET> como fez ontem. Aqui está um arquivo de HTML para usar: Para este exemplo de HTML, o seu arquivo de classe de Java está no mesmo diretório que este arquivo de HTML. Salve o arquivo a HelloAgainApplet.html e acenda o seu browser permitido por Java ou Java applet espectador. A figura 2.7 mostra o resultado que deve estar adquirindo (a cadeia de "Hello Again!" é vermelha).
A figura 2.7: O HelloAgain applet.
Se isto for o seu primeiro encontro com a programação orientada ao objeto, muita informação nesta lição vai parecer realmente teórica e esmagadora. O medo não - além disso ao longo neste livro que adquire, e mais classes de Java e aplicações cria, mais fácil deve entender. Uma das barreiras mais grandes da programação orientada ao objeto é não necessariamente os conceitos; são os seus nomes. OOP tem muito jargão que o rodeia. Para resumir o material de hoje, aqui está um glossário de termos e conceitos que aprendeu hoje: A maior parte do tempo, usará variáveis de exemplo e métodos. Aprenderá mais sobre variáveis de classe e métodos depois nesta semana.
Calling showAtts...
This motorcycle is a yellow Yamaha RZ350
The engine is off.
--------
Starting engine...
The engine is now on.
--------
Calling showAtts...
This motorcycle is a yellow Yamaha RZ350
The engine is on.
--------
Starting engine...
The engine is already on.
Análise
Os conteúdos do método de main() vão todos parecer muito novos para você, então vamos por ele linha pela linha para que pelo menos tenha uma ideia básica do que faz (adquirirá detalhes sobre a especificação de tudo isso amanhã e o dia depois).
A listagem 2.3. A versão final de Motorcycle.java.
1: class Motorcycle {
2:
3: String make;
4: String color;
5: boolean engineState;
6:
7: void startEngine() {
8: if (engineState == true)
9: System.out.println("The engine is already on.");
10: else {
11: engineState = true;
12: System.out.println("The engine is now on.");
13: }
14: }
15:
16: void showAtts() {
17: System.out.println("This motorcycle is a "
18: + color + " " + make);
19: if (engineState == true)
20: System.out.println("The engine is on.");
21: else System.out.println("The engine is off.");
22: }
23:
24: public static void main (String args[]) {
25: Motorcycle m = new Motorcycle();
26: m.make = "Yamaha RZ350";
27: m.color = "yellow";
28: System.out.println("Calling showAtts...");
29: m.showAtts();
30: System.out.println("------");
31: System.out.println("Starting engine...");
32: m.startEngine();
33: System.out.println("------");
34: System.out.println("Calling showAtts...");
35: m.showAtts();
36: System.out.println("------");
37: System.out.println("Starting engine...");
38: m.startEngine();
39: }
40:}
Herança, interfaces e pacotes
Herança
Novo termo
A herança é um conceito na programação orientada ao objeto onde todas as classes se arranjam em uma hierarquia estrita. Cada classe na hierarquia tem superclasses (classes acima dele na hierarquia) e qualquer número de subclasses (classes em baixo dele na hierarquia). As subclasses herdam atributos e comportamento das suas superclasses.
Novo termo
A subclassificação é o processo de criar uma nova classe que herda de alguma outra classe já existente.
Criar uma hierarquia de classe
Como herança trabalha
Novo termo
A anulação de um método cria um método em uma subclasse que tem a mesma assinatura (nome, número e tipo de argumentos) como um método em uma superclasse. Aquele novo método então esconde o método da superclasse (ver a Figura 2.6).
Herança única e múltipla
Interfaces e pacotes
Novo termo
Uma interface é uma coleção de nomes de método, sem definições, que podem acrescentar-se a classes para fornecer o comportamento adicional não incluído com aqueles métodos que a classe definiu ela mesma ou herdou das suas superclasses.
Criação de uma subclasse
public class HelloAgainApplet extends java.applet.Applet {
}
Font f = new Font("TimesRoman", Font.BOLD, 36);
public void paint(Graphics g) {
g.setFont(f);
g.setColor(Color.red);
g.drawString("Hello again!", 5, 40);
}
public class HelloAgainApplet extends java.applet.Applet {
Font f = new Font("TimesRoman",Font.BOLD,36);
public void paint(Graphics g) {
g.setFont(f);
g.setColor(Color.red);
g.drawString("Hello again!", 5, 40);
}
}
HelloAgainApplet.java:7: Class Graphics not found in type declaration.
import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
Ponta
Também pode importar um pacote inteiro de classes de public usando um asterisco (*) no lugar de um nome de classe específico. Por exemplo, para importar todas as classes no pacote de awt, pode usar esta linha:
import java.awt.*;
A listagem 2.4. A versão final de HelloAgainApplet.java.
1:import java.awt.Graphics;
2:import java.awt.Font;
3:import java.awt.Color;
4:
5:public class HelloAgainApplet extends java.applet.Applet {
6:
7: Font f = new Font("TimesRoman",Font.BOLD,36);
8:
9: public void paint(Graphics g) {
10: g.setFont(f);
11: g.setColor(Color.red);
12: g.drawString("Hello again!", 5, 40);
13: }
14:}
<HTML>
<HEAD>
<TITLE>Another Applet</TITLE>
</HEAD>
<BODY>
<P>My second Java applet says:
<BR><APPLET CODE="HelloAgainApplet.class" WIDTH=200 HEIGHT=50>
</APPLET>
</BODY>
</HTML>
Sumário
classe: Um padrão de um objeto, que contém variáveis e métodos que representam comportamento e atributos. As classes podem herdar variáveis e métodos de outras classes.
método de classe: Um método definiu em uma classe, que produz a própria classe e pode chamar-se via a classe ou algum dos seus exemplos.
variável de classe: Uma variável que "se possui" pela classe e todos os seus exemplos no conjunto e se guarda na classe.
exemplo: a mesma coisa que um objeto; cada objeto é um exemplo de alguma classe.
método de exemplo: Um método definiu em uma classe, que produz um exemplo daquela classe. Os métodos de exemplo chamam-se normalmente somente métodos.
variável de exemplo: Uma variável que se possui por um exemplo individual e cujo valor se guarda no exemplo.
interface: Uma coleção de especificações de comportamento abstratas que as classes individuais então podem implementar.
objeto: Um exemplo concreto de alguma classe. Múltiplos objetos que são os exemplos da mesma classe têm o acesso aos mesmos métodos, mas muitas vezes têm valores diferentes das suas variáveis de exemplo.
pacote: Uma coleção de classes e interfaces. As classes de pacotes outros do que java.lang devem importar-se explicitamente ou mencionar-se pelo nome de pacote cheio.
subclasse: Uma classe mais baixo na hierarquia de herança do que o seu pai, superclasse. Quando cria uma nova classe, muitas vezes chamava a subclassificação.
superclasse: Uma classe além disso na hierarquia de herança do que a sua criança, subclasse.
Perguntas e Respostas
Os métodos são efetivamente funções que se definem dentro de classes. Se parecerem a funções e ato como funções, porque não são chamaram funções?
Algumas linguagens de programação orientadas ao objeto realmente chamam-nos funções (C ++ chama-os funções de membro). Outras línguas orientadas ao objeto diferenciam-se entre funções dentro e fora de um corpo de uma classe ou objeto, onde ter termos separados é importante para a compreensão como cada um trabalha. Como a diferença é relevante em outras línguas e porque o termo método está agora em tal uso comum na tecnologia orientada ao objeto, Java usa a palavra também. Entendo variáveis de exemplo e métodos, mas não a ideia de variáveis de classe e métodos.
A maioria tudo que faz em um programa Java será com objetos. Alguns comportamentos e os atributos, contudo, fazem mais sentido se se guardarem na própria classe em vez de no objeto. Por exemplo, para criar um novo exemplo de uma classe, precisa de um método que se define e disponível na própria classe. (De outra maneira, como pode criar um objeto? Precisa de um objeto de chamar o método, mas não tem um objeto ainda.) As variáveis de classe, de outro lado, muitas vezes usam-se quando tem um atributo cujo valor quer compartilhar com todos os exemplos de uma classe.