Classe pode ser definida como uma categoria de objetos. No nosso dia a dia, usamos as classes para facilitar o entendimento dos objetos que nos cercam. Esse é o modo como nosso cérebro funciona. Estamos sempre colocando os objetos dentro de categorias. Fazemos isso para reconhecer os objetos e determinar suas características e comportamento. Toda vez que olhamos para qualquer objeto, automaticamente nosso cérebro o classifica, ou seja, o coloca dentro de alguma classe de objetos que já conhecemos. Nós só podemos entender e reconhecer um objeto qualquer depois que ele foi devidamente classificado. Quando não conseguimos classificar um objeto, não podemos saber o que ele é e nem entendê-lo. Este processo de classificação é automático e inconsciente, normalmente não o percebemos a não ser quando ele falha. Note que classe é um conceito, um modelo, um conjunto de definições. Não tem existência física no universo. Já os objetos existem fisicamente no universo.

Por exemplo, ao vermos um carro estacionado na rua, reconhecemos esse objeto porque automaticamente classificamos esse objeto como pertencente à uma categoria de objetos que já conhecemos, a categoria (classe) Carro. Uma vez que ele foi classificado, podemos inferir suas características e seu comportamento, mesmo que elas não sejam aparentes no momento e mesmo que seja a primeira vez que olhamos para aquele carro em particular. Ou seja, mesmo nunca tendo visto esse carro antes, sabemos por exemplo que o carro é capaz de acelerar, de frear, de virar para a esquerda ou para a direita, que é capaz de acender os faróis e muitas outras ações que ele é capaz de realizar, mesmo não vendo essas ações sendo executadas naquele momento. Sabemos disso porque sabemos que todos os objetos que pertencem à categoria Carro são capazes destas ações, portanto se aquele objeto que vimos é um carro, então ele também é capaz destas ações.

Da mesma forma que a classe nos informa as ações que um objeto é capaz de realizar (seu comportamento), também determina o conjunto de atributos dos objetos. Ainda usando o exemplo do carro, sabemos que o carro que vimos estacionado tem um modelo, ano de fabricação, número de chassis, número de Renavam, proprietário, placa e muitos outros atributos, que embora não sejam aparentes, sabemos que eles existem, porque todos os carros têm estes atributos. Embora cada carro possa ter um valor diferente para cada atributo, todos têm o mesmo conjunto de atributos.

Em resumo, objetos têm atributos (características, dados) e comportamento (ações que são capazes de realizar). Objetos da mesma classe têm o mesmo conjunto de atributos e o mesmo comportamento.

Instância

A palavra instância tem muito significados na língua portuguesa. Pode significar “insistência” ou “pedido insistente”, também é usada para designar o nível de autoridade em uma instituição jurídica. Na programação orientada a objeto, instância tem o sentido de “manifestação”, a classe, que é algo abstrato, se manifesta concretamente através dos objetos a partir dela. A classe é tida como um molde, um modelo a partir do qual os objetos são criados. Portanto o termo “instanciar uma classe” significa criar um objeto daquela classe. Como na programação orientada a objeto todos os objetos pertencem a alguma classe, então todos os objetos são instâncias das suas respectivas classes.

Generalização/Especialização

Classes podem ser divididas em subclasses de modo a formar uma hierarquia onde no topo estão as classes mais gerais e na base as classes mais especializadas.
Como citado antes, um carro qualquer pertence à classe Carros, entretanto essa não é a única classe a que pertence. Podemos imaginar uma classe mais geral que inclua não só os carros, mas também outros veículos, como motocicletas, caminhões, trens, etc. Note que um carro continua pertencendo à classe Carros, mas além disso também pode pertencer à classe Veículos. Podemos pensar na classe Carros como uma subclasse da classe Veículos. Neste caso, Veículos é uma classe mais geral e Carros uma classe mais especializada. Veja o exemplo na figura abaixo:
classes.jpg
Exemplo de hierarquia de classes

Processo de generalização – Consiste em detectar características e comportamentos comuns entre duas classes para criar outra classe que contenha apenas o que é comum às duas classes. Esta nova classe será ancestral das outras.

Processo de Especialização – Consiste em detectar características e comportamentos diferentes entre objetos da mesma classe e criar novas classes descendentes mais especializadas.

Encapsulamento

O termo encapsulamento vem do verbo encapsular, que significa literalmente colocar dentro de uma cápsula, um recipiente. Na POO, este termo se refere ao fato que é possível esconder os detalhes da implementação dos objetos dos usuários destes. Neste caso, o objeto passa a funcionar como uma caixa preta, onde os mecanismos internos ficam escondidos e o acesso é apenas aos métodos que ativam estes mecanismos.

Como exemplo, vamos considerar um telefone celular. Todos nós sabemos como fazer ligações em um celular. Sabemos que basta digitar o número e apertar o botão Send, entretanto poucos conhecem os mecanismos envolvidos em uma ligação telefônica. Não sabemos como funcionam os circuitos internos de um celular e nem como ele faz a conexão para estabelecer a ligação. Mas isso não nos impede de fazer ligações, porque conhecemos o método oferecido pelo celular, ou seja, o teclado numérico e o botão Send. Celulares diferentes usam circuitos e mecanismos diferentes internamente, mas todos oferecem o mesmo método, ou seja, todos têm um teclado numérico e um botão Send. Portanto somos capazes de fazer ligações em qualquer celular, não importando como são construídos internamente.

Neste exemplo, o celular pode ser considerado uma caixa preta, porque não temos acesso aos mecanismos internos dele, nosso acesso é limitado à sua interface, ou seja, o conjunto de métodos que ele oferece para ativar seus mecanismos internos.

Voltando à POO, como um objeto guarda na mesma estrutura os dados (atributos) e as funções que os processam (ações – métodos) pode-se pensar em atributos e métodos privados, ou seja, dados e funções que só podem ser manipulados pelas funções que estão dentro da estrutura. Desta maneira é possível formar uma camada protetora nos dados e evitar atribuições desastradas que comprometeriam o funcionamento do programa. Os defensores mais ortodoxos da POO dizem que todos os dados de um objeto deveriam ser privados e o número de funções públicas deve ser o menor possível. O Java implementa este conceito e oferece atributos e métodos públicos (public), privados (private) e protegidos (protected).

Herança

Como citado, uma classe geral tem atributos e métodos que são comuns a todas as suas subclasses mais especializadas. Ao especializar uma classe, a nova classe herda automaticamente todos os recursos públicos (métodos e atributos) da classe original. Essa capacidade é chamada de Herança.

A herança permite que o código já escrito para uma classe seja facilmente reaproveitado quando é necessário criar uma nova classe mais especializada.

Uma subclasse sempre herda todos os recursos da classe original. Neste caso a subclasse é chamada de classe descendente e a classe original de classe ancestral. No exemplo da figura 1, a classe Veículos é ancestral de todas as outras classes. A classe Terrestres tem como descendentes as classes Carros, Trens e todas as classes descendentes delas, ou seja: Esportivos, Passeio e Utilitários. Já a classe Esportivos tem como ancestrais as classes Carros, Terrestres e Veículos, portanto herda todos os recursos presentes nestas três classes.

Observação: No java, a classe ancestral é chamada de super-classe, ou simplesmente super.

Polimorfismo

Refere-se à capacidade de objetos de classes diferentes responderem de formas diferentes a um mesmo método, conforme sua classe, a fim de obter o mesmo resultado ou resultado equivalente. Por exemplo, vamos considerar a hierarquia da figura acima. Sabemos que todos os veículos devem ser capazes de frear e de acelerar. Na verdade, estas ações fazem parte da própria definição do conceito de veículo. Um objeto que não seja capaz de acelerar e frear, não é um veículo. Então todo e qualquer objeto classificado como veículo tem que ser capaz de realizar essas ações e portanto deve oferecer métodos para desencadeá-las. Entretanto, sabemos que frear um trem é um processo completamente diferente de frear um navio ou um avião, os mecanismos envolvidos para executar esta ação são completamente diferentes, mas o resultado da ação será sempre o mesmo: o veículo diminui sua velocidade ou para completamente.

Uma consequência deste conceito é a existência de classes abstratas. Uma classe abstrata contém métodos que estão declarados, mas não estão implementados. A implementação é feita em alguma classe descendente, conforme as características específicas daquela classe. Então a classe ancestral define uma linguagem comum (conjunto de métodos) para todas as classes descendentes e estas por sua vez implementam estes métodos de acordo com seus recursos e características. Classes abstratas não podem ser instanciadas. Isso significa que não é possível criar objetos destas classes, elas podem apenas ser ancestrais de outras classes.