Aula 3
Uma classe é um modelo usado para definir vários
objetos com características semelhantes. Um programa é constituído de uma classe ou de
um conjunto de classes. Os elementos básicos de uma classe são chamados
membros da classe e podem ser divididos em duas
categorias:
- As variáveis, que especificam o estado da
classe ou de um objeto instância desta classe.
- Os métodos, que especificam os mecanismos pelos
quais a classe ou um objeto instância desta classe podem operar.
O esqueleto de uma classe apresenta-se da seguinte maneira:
class NomeDaClasse
{
TipoDaVariahvel1 variahvel1;
TipoDaVariahvel2 variahvel2;
...
TipoDeRetorno1 mehtodo1()
{
...
}
TipoDeRetorno2 mehtodo2()
{
...
}
...
}
Um ojeto é uma
instância de uma classe. Um objeto precisa ser
declarado e criado.
- Declaração: a seguinte instrução declara que
a variável
nomeDoObjeto
refere-se a um objeto instância da classe
NomeDaClasse
:
NomeDaClasse nomeDoObjeto;
- Criação: a seguinte instrução cria (em
memória) um novo objeto instância da classe
NomeDaClasse
, que
será referenciado pela
variável nomeDoObjeto
previamente declarada :
nomeDoObjeto = new NomeDaClasse();
As duas instruções acima podem ser combinadas numa só:
NomeDaClasse nomeDoObjeto = new NomeDaClasse();
Variáveis de instância e variáveis de classe
Uma variável de instância é uma variável cujo valor
é específico ao objeto e não à classe. Uma variável de instância em geral possui
uma valor diferente em cada objeto membro da classe.
Uma variável de classe é uma variável cujo valor
é comum a todos os objetos membros da classe. Mudar o valor de uma variável de classe
em um objeto membro automaticamente muda o valor para todos os objetos membros.
Uma variável é considerada como de instância por "default". Para declarar uma variável
de classe, acrescenta-se a palavra-chave static
.
Exemplos:
static int nuhmeroDeInstahnciasDestaClasse;
static int LEFT = 1;
Variáveis públicas, amigáveis, protegidas e privadas
Algumas palavras-chaves são diponíveis para ampliar ou restringir o acesso a uma
variável. Estas palavras-chaves são acrescentadas à declaração da variável.
Uma variável para a qual não foi especificada nenhuma destas palavras-chaves
é dita amigável e pode ser acessada por todas as
classes que pertencem ao mesmo pacote.
Uma variável que pode ser acessada
por qualquer outra classe é dita pública,
e é declarada usando-se a palavra-chave
public
.
Uma variável que pode ser acessada somente
por métodos da própria classe é dita privada,
e é declarada usando-se a palavra-chave
private
.
Uma variável que, além de poder ser acessada por todas as classes do mesmo pacote,
também pode ser acessada pelas subclasses da classe na qual ela é declarada, é
dita protegida e é declarada usando-se a
palavra-chave protected
. [O conceito de subclasse
será desenvolvido na próxima aula.]
Exemplo:
package algumPacote; // a classe definida neste arquivo
pertence a algumPacote
public class NomeDaClasse
{
public int w; // acessível por qualquer classe
protected int x; // acessível pelas subclasses
de NomeDaClasse
int y; // acessível pelas classes deste pacote
private int z; // acessível somente pelos métodos
de NomeDaClasse
...
}
Como um objeto acessa as variáveis de outro objeto
Supondo que as restrições de acesso discutidas acima o permitam, uma classe pode
utilizar ou modificar uma variável variahvel
pertencente a um
objeto objeto
através do
"operador ponto":
var1 = objeto.variahvel;
objeto.variahvel = var2;
Se a variável for um objeto, pode-se concatenar operadores pontos para alcançar variáveis
deste objeto:
var1 = objeto.variahvel.outraVariahvel;
Se a variável for uma variável de classe, pode-se usar a classe, em vez de uma instância
particular, para acessar a variável:
var1 = NomeDaClasse.variahvel;
Embora esta seja a maneira a mais direta de permitir que um objeto tenha acesso às variáveis
de outro objeto, não é a mais segura, pois permite que um objeto modifique uma variável do
outro sem restrição. Uma maneira mais segura consiste em declarar a variável como privada,
mas incluir na classe métodos especiais controlando o acesso à variável:
public class NomeDaClasse
{
private TipoDaVariahvel variahvel;
...
public TipoDaVariahvel getVariahvel()
{
return variahvel;
}
public void setVariahvel( TipoDaVariahvel valor)
{
...
variahvel = valor;
}
}
Assim, pode-se colocar no método setVariahvel
código para conferir que o valor
passado como argumento é adequado. Omitindo o método setVariahvel
, impedimos
qua a variável seja modificada por qualquer outro objeto, embora ela possa ser lida chamando
o método getVariahvel
.
O operador ponto também serve para chamar os métodos de outro objeto, de maneira que
a classe que deseja manipular as variáveis do outro objeto conterá agora
comandos do tipo:
var1 = objeto.getVariahvel();
objeto.setVariahvel( var2 );
Esta técnica de programação é chamada encapsulação
de variáveis.
Variáveis globais e variáveis locais
As variáveis discutidas acima são declaradas fora de qualquer método (usualmente no cabeçalho
da classe) e são acessíveis por qualquer método da classe. Tais variáveis são chamadas
globais. Muitas vezes, variáveis auxiliares são declaradas
dentro de um determinado método, ou até dentro de um bloco menor. Tais variáveis são chamadas
locais. Elas existem somente durante a execução daquele
método ou bloco. A parte de código que "enxerga" uma determinada variável é chamada o
escopo da variável. Assim, o escopo de uma variável global
é a classe inteira, e o escopo de uma variável local é o método, ou bloco contido dentro
do método, ao qual ela pertence.
Exemplo:
class NomeDaClasse
{
TipoDaVariahvel variahvel1; // variável global
...
TipoDeRetorno nomeDoMehtodo()
{
TipoDaVariahvel variahvel2; // variável local, definida
neste método
for( int i = 0; i < 10; i++ )
{
... // a variável i é local, definida só dentro deste
bloco
}
}
}
Embora não pareça uma boa ideia, é possível dar a uma variável local um nome que já
foi atribuído a uma variável global. Neste caso, a variável local "encobre" a variável
global, mas o acesso à variável global é possível usando a palavra-chave
this
(que fornece uma referência ao próprio objeto)
e o operador ponto:
class NomeDaClasse
{
TipoDaVariahvel variahvel; // variável global
...
TipoDeRetorno nomeDoMehtodo()
{
TipoDaVariahvel variahvel; // variável local, definida
neste método
variahvel2 = variahvel; // recebe o valor da variável local
variahvel3 = this.variahvel;
// recebe o valor da variável global
}
}
Alguns programadores fazem uso desta construção em métodos set
:
public class NomeDaClasse
{
private TipoDaVariahvel variahvel;
public void setVariahvel( TipoDaVariahvel variahvel )
{
this.variahvel = variahvel;
}
}
Variáveis constantes
Esta expressão um tanto paradoxal refere-se a variáveis cujo valor não pode mudar durante
a execução do programa. Tais variáveis são caracterizadas pela palavra-chave
final
, e por convenção recebem usualmente nomes escritos
inteiramente em maiúsculas. Por exemplo, na classe Math
do pacote
lang
, encontramos
public static final double PI;
que contem o valor da famosa constante matemática.
Valor de retorno e argumentos
Em geral, um método recebe argumentos cujos valores lhe são passados pelo objeto
que o chamou, efetua um conjunto de operações e retorna algum resultado. A declaração
do método especifica o nome do método, o tipo de retorno, o nome e o tipo de cada
argumento. Os argumentos são variáveis locais do método em questão:
TipDeRetorno nomeDoMehtodo( TipoDoArg1 arg1, TipoDoArg2 arg2, ...)
{
... // corpo do método
}
Se o método não utiliza nenhum argumento, parénteses vazias devem ser incluídas na declaração.
Se o método não retorna nenhum valor, isto deve ser declarado usando-se a palavra-chave
void
:
TipDeRetorno nomeDoMehtodo( )
{
... // corpo do método
}
void nomeDoMehtodo( TipoDoArg1 arg1,
TipoDoArg2 arg2, ... )
{
... // corpo do método
}
Métodos estáticos
Por "default", um método efetua uma determinada operação sobre um determinado
objeto, i.e. uma instância da classe na qual o método está declarado. Existem
métodos que realizam operações genéricas, não relativas a uma instância particular.
Tais métodos são chamados estáticos
e são declarados acrescentando-se a palavra-chave static
à declaração do método. Por exemplo, os métodos da classe Math
do pacote lang
, que realizam operações matemáticas sobre números, são
estáticos:
public static int min( int a, int b )
{
... // retorna o menor dos 2 inteiros a e b
}
Métodos públicos, amigáveis, protegidos e privados
Algumas palavras-chaves são diponíveis para ampliar ou restringir o acesso a um
método. Estas palavras-chaves são acrescentadas à declaração do método.
Um método para o qual não foi especificada nenhuma destas palavras-chaves
é dito amigável e pode ser chamado por todas as
classes que pertencem ao mesmo pacote.
Um método que pode ser acessado
por qualquer outra classe é dito público,
e é declarado usando-se a palavra-chave
public
.
Um método que pode ser acessado somente
por métodos da própria classe é dito privado,
e é declarado usando-se a palavra-chave
private
.
Um método que, além de poder ser acessado por todas as classes do mesmo pacote,
também pode ser acessado pelas subclasses da classe na qual ele é declarado, é
dito protegido e é declarado usando-se a
palavra-chave protected
.
Exemplo:
package algumPacote; // a classe definida neste arquivo
pertence a algumPacote
public class NomeDaClasse
{
public int mehtodo1( )
{
... // acessível por qualquer classe
}
protected int mehtodo2( )
{
... // acessível pelas subclasses de NomeDaClasse
}
int mehtodo3( )
{
... // acessível pelas classes deste pacote
}
private int mehtodo4( )
{
... // acessível somente pelos métodos de NomeDaClasse
}
}
Como um objeto chama um método de outro objeto
Supondo que as restrições de acesso discutidas acima o permitam, uma classe pode
chamar (executar) um método mehtodo
pertencente a um
objeto objeto
através do "operador ponto":
objeto.mehtodo1( ); // o método não requer argumento e não retorna nada
objeto.mehtodo2( var1, var2 ); // os argumentos var1 e var2 são passados ao método
Resultado resultado = objeto.mehtodo3( ); // retorna um valor do tipo Resultado
Se a variável de retorno for um objeto, pode-se concatenar operadores pontos para
chamar métodos deste objeto:
objeto.mehtodo3().mehtodo4();
Se o método for estático, usa-se a classe, em vez de uma instância
particular, para chamar o método:
int x = Math.min( a, b );
Como criar um objeto - Método construtor
Para criar uma objeto, usa-se a palavra chave new
,
seguida de uma chamada ao método construtor, cujo
nome é idêntico ao da classe:
NomeDaClasse nomeDoObjeto = new NomeDaClasse( );
O método construtor não precisa ser incluído explicitamente na classe, mas pode ser
incluído para realizar tarefas no ato da criação. A sintaxe é:
class NomeDaClasse
{
NomeDaClasse( )
{
... // comandos executados na criação do objeto
}
}
ou, para uma classe pública:
public class NomeDaClasse
{
public NomeDaClasse( )
{
... // comandos executados na criação do objeto
}
}
O método construtor pode receber argumentos:
public class NomeDaClasse
{
public NomeDaClasse( Tipo1 arg1, Tipo2 arg2 )
{
... // comandos executados na criação do objeto
}
}
Valores para estes argumentos devem então ser passados ao construtor no comando de
criação:
NomeDaClasse nomeDoObjeto = new
NomeDaClasse( valorArg1, valorArg2 );