Modelo Java Magazine

Propaganda
Grupo de Usuários Java
http://www.guj.com.br
Conceitos de Programação Orientada a Objetos
Tatyana Bitencourt
Com as técnicas de orientação a objeto, é possível obter resultados considerados impossíveis
pensando de maneira estruturada. Como Java não deixa ao programador a opção de escrever ou não
orientado a objetos (como em C++), os conceitos de oop devem estar bem fundamentados.
Abstração
A capacidade de determinar o problema de maneira geral, dando importância apenas aos seus
aspectos relevantes e ignorando os detalhes é chamada de abstração.
Existem dois tipos de abstração: Abstração de dados e Abstração de Procedimentos.
-
Abstração de dados
Abstração de dados é a definição de um tipo de dado por seu comportamento e estado, utilizandose métodos. A manipulação desse dado é realizada apenas através de seus métodos.
Um exemplo é classificar uma lista a partir das operações aplicadas a ela, como inserção e
remoção. Qualquer objeto do tipo lista só pode sofrer modificações através dessas operações.
-
Abstração de procedimentos
Consiste em considerar um procedimento com uma operação bem definida como algo único,
mesmo que utilize outros procedimentos internos. Usamos abstração de procedimentos quando uma
função divide-se em outras sub-funções, que por sua vez decompõem-se em outras funções.
Classe
Tipo definido pelo usuário. Contém a especificação da classe, identificando seus atributos (dados) e
seus métodos (comportamento da classe). A definição de uma classe não é responsável pela criação de
nenhuma instância, portanto não ocupa uma parte da memória.
Considere a classe a seguir:
public class Person
{
private String name;
public Person(String a)
{
name = a; //copia a para name
}
public String getName()
{
return name;
}
public String toString()
{
return "Nome: " + name;
}
}
Grupo de Usuários Java – http://www.guj.com.br – Página 1
Grupo de Usuários Java
http://www.guj.com.br
A instrução inicial
public class Person
declara uma classe chamada Person, que possui como um atributo
private String name;
e três métodos públicos:
public Person(String a);
public String getName();
public String toString();
Objeto
Em uma linguagem procedural, a instância de uma estrutura é chamada de variável. Já uma instância
de uma classe é chamada de objeto. A classe informa a cada objeto suas características (dados) e seu
comportamento (métodos). Suas características são informadas pela declaração de variáveis de tipo
primitivo (int, float, etc...) ou classes anteriormente definidas. Seus métodos são definidos por funções,
possibilitando a “conversa” entre dois objetos.
- Criando objetos
Após a definição da classe Person, a instrução
Person x = new Person("Maria"),
y = new Person(“Andre”);
cria dois objetos da classe definida anteriormente Person, passando a ocupar realmente um espaço na
memória.
- Funções-Membro
Quando um objeto chama um método de sua classe (função-membro), costuma-se dizer que uma
mensagem foi enviada. Assim, a instrução
x.toString();
envia uma mensagem a x, pedindo que retorne seu conteúdo como String.
Encapsulamento
Encapsulamento consiste em esconder detalhes (dados) e oferecer uma interface comum aos objetos
(métodos). Toda vez que uma alteração deve ser feita em alguma variável de instância, deve ser feita
através de um método da classe. Caso alguma modificação ocorra em alguma variável de instância,
sabe-se exatamente quais métodos interagiram com a variável, prevenindo alterações acidentais.
É permitido ao usuário ver apenas os dados necessários, todo o resto é mantido escondido, através de
especificadores de acesso (public, private, protected). A utilização de encapsulamento também
favorece a reusabilidade e manutenção do código.
Dessa maneira, a instrução
System.out.println(“Nome: ”,name);
chamada por qualquer outro objeto causará um erro, pois o atributo name não está visível (através do
modificador private). Para realizar a impressão da variável name é necessário então chamar um método
de x:
Grupo de Usuários Java – http://www.guj.com.br – Página 2
Grupo de Usuários Java
http://www.guj.com.br
System.out.println(x.toString());
Herança
Herança é a criação de novas classes, chamadas classes derivadas, a partir de classes já existentes,
as classes-base. Alguns dos benefícios da utilização de herança é a reutilização do código da classe
base, além da possibilidade de implementação de classes abstratas genéricas.
Ao implementar um applet, utiliza-se a seguinte instrução:
public class HelloApplet extends JApplet
{
......
}
A palavra chave extends indica que HelloApplet é uma classe derivada de JApplet. Isso siginifica que a
classe HelloApplet herda por exemplo, os métodos init() e start() de JApplet. Num applet, pode-se definir
novos atributos e métodos, bem como sobrescrever os métodos herdados de JApplet, como o init().
Uma classe derivada (ou subclasse) pode realizar todas as funções que a classe-base (ou superclasse)
realizaria. A subclasse herda todos os métodos public da superclasse, mas não possui acesso a nenhum
membro private de sua classe-base. Se isso fosse possível, não haveria motivo algum em realizar o
encapsulamento de dados. Além disso, uma subclasse pode acrescentar mais alguns métodos ou
atributos àqueles herdados da superclasse, possuindo características particulares em relação à classebase.
Especificador de acesso protected
Além de public e private, Java permite um terceiro tipo de modificadores de acesso:
protected.
Métodos e atributos declarados como protected possuem um nível intermediário de
proteção. Um membro protected é como um membro private, exceto pelo fato de
que ele pode ser acessado pelas classes derivadas de uma superclasse. Cada vez que
deseja-se utilizar algum método da superclasse, utiliza-se a palavra-chave super
seguida pelo operador ponto (. ).
Considere a classe Student:
public class Student extends Person
{
private String grade; // serie cursada
private int classes; // aulas que frequenta
...
public Student(String n, String g)
{
super(n); //chamada ao construtor da superclasse
grade = g;
classes = 0;
}
public String toString()
{
return super.toString() + “\nGrade: “ + grade;
}
} //fim da classe Student
Grupo de Usuários Java – http://www.guj.com.br – Página 3
Grupo de Usuários Java
http://www.guj.com.br
A classe acima ilustra a criação de uma subclasse Student que herda os atributos e métodos de
Person. Uma subclasse não herda os construtores de sua superclasse, mas pode invoca-los através do
comando super. A chamada a essa função deve ser a primeira instrução no construtor da subclasse, caso
contrário ocorrerá erro. Caso a chamada ao construtor base não tivesse sido feita explicitamente em
Student(String n, String g), uma chamada ao construtor default (sem argumentos) da classe base seria
realizada.
Em Java não é permitido o uso de herança múltipla como em C++, o que pode ser contornado com o uso
de interfaces.
Por que Java não suporta herança múltipla
Algumas das características da linguagem Java é ser familiar, simples, segura,
robusta, etc.
Os projetistas da linguagem fizeram-na parecida com C++ (atingindo o conceito de
ser familiar) e decidiram não implementar algumas características que tornavam a
linguagem C++ um tanto complexa, como herança múltipla e sobrecarga de
operadores. Eles simplesmente verificaram que o trabalho não valia a pena.
Para contornar esse fato, foi inspirado na linguagem Objective C que surgiu o
conceito de interfaces. Um objeto pode herdar diversos métodos, com a condição de
que implemente-os.
Fonte: Java World (http://www.javaworld.com/javaqa/2002-07/02-qa-0719multinheritance.html)
Classes abstratas
Uma classe abstrata é utilizada quando deseja-se fornecer uma interface comum a diversos membros
de uma hierarquia de classes. Os métodos declarados na classe abstrata serão implementados em suas
subclasses, através de polimorfismo.
Considere as seguintes modificações na classe Person:
public abstract class Person
{
private String name;
public Person(String a)
{
name = a; //copia a para name
}
public String getName()
{
return name;
}
public String toString()
{
return "Nome: " + name;
}
public abstract String getType();
}
Grupo de Usuários Java – http://www.guj.com.br – Página 4
Grupo de Usuários Java
http://www.guj.com.br
O método getType() retorna o tipo de pessoa (estudante, professor, funcionario, etc). A inclusão do
método
public abstract String getType();
indica que a classe Person é uma classe abstrata, o que justifica a inclusão da palavra-chave abstract na
definição da classe. Nenhum objeto da classe Person poderá ser instanciado agora.
Agora a classe Student deve se adequar às mudanças realizadas. Ao extender Person, a subclasse
possui também um método abstrato, e caso não o sobrescreva será também uma classe abstrata. A
classe Student ficaria mais ou menos assim:
public class Student extends Person
{
private String grade; // serie cursada
private int classes; // aulas que frequenta
...
public Student(String n, String g)
{
super(n); //chamada ao construtor da superclasse
grade = g;
classes = 0;
}
public String toString()
{
return super.toString() + “\nGrade: “ + grade;
}
public String getType()
{
return “Student”;
}
} //fim da classe Student
Implementando o método getType(), a classe Student é agora uma classe concreta.
Diferenças entre classe abstrata e interface
As semelhanças entre classe abstrata e interface são muitas. Uma interface é utilizada
quando não existe a necessidade das classes derivadas herdarem métodos já
implementados. Outra diferença é que interfaces não permitem a declaração de
atributos, como as classes abstratas.
Polimorfismo
Polimorfismo caracteriza a criação de funções com um mesmo nome, mas códigos diferentes,
facilitando a extensão de sistemas.
Um tipo de polimorfismo é a redefinição de métodos para uma classe derivada. Para que isso
aconteça, o método deve possuir o mesmo nome, tipo de retorno e argumentos do método sobrescrito.
O acréscimo de um segundo construtor à classe Student, como mostra o exemplo, é um exemplo de
sobrecarga de métodos.
public class Student extends Person
Grupo de Usuários Java – http://www.guj.com.br – Página 5
Grupo de Usuários Java
http://www.guj.com.br
{
private String grade; // serie cursada
private int classes; // aulas que frequenta
...
public Student(String n, String g)
{
super(n); //chamada ao construtor da superclasse
grade = g;
classes = 0;
}
public Student(String n, String g, int c)
{
super(n); //chamada ao construtor da superclasse
grade = g;
classes = f;
}
.
.
.
} //fim da classe Student
Quando ocorre a instanciação dos objetos:
Student s1 =
s2 =
new
new
Student(“Maria”, “5”),
Student (“João”,”8”,5);
O objeto s1 utiliza o primeiro construtor, pois os tipos de argumento são os mesmo. Já o objeto s2
utiliza o segundo construtor, por ter além dos dois argumentos do tipo String, um outro do tipo int.
Em Java não é possível realizar a sobrecarga de operadores como em C++.
Conclusão
O fato de Java ser orientado a objetos contribui muito para sua utilização no desenvolvimento de
sistemas, cada vez mais complexos. Sendo uma linguagem orientada a objetos, Java pode usufruir do
melhor das antigas linguagens também orientadas a objetos, como Smaltalk, Objective C, C++. Além
disso, a utilização de técnicas como herança e polimorfismo facilitam ainda mais a extensão do software,
uma característica extremamente importante em tempos em que a política de não reinventar a roda é
cada vez mais forte.
Tatyana Bitencourt ([email protected]) é programadora e estudante de Ciência da Computação (UFMS).
Grupo de Usuários Java – http://www.guj.com.br – Página 6
Download