Aula 5
Métodos, Parâmetros, Argumentos e
Contratos
Na aula passada …
Ciclos:
while (condição) {passo; progresso;}
for (init; condição; progresso) {passo;}
do {passo; progresso;} while (condição);
Matrizes:
int[] matriz_de_inteiros = new int[100];
matriz_de_inteiros[99] = 10;
int x = matriz_de_inteiros[99];
String:
2
String frase = “Uma frase”;
String frase = new String(“Uma frase”);
char primeiro = frase.charAt(0);
char último = frase.charAt(frase.length() – 1));
Introdução à Programação
2007/2008
Modularização em Java
Métodos (ou Rotinas)*
Funções
Conjunto de instruções, com interface bem definida, que efectua
um dado cálculo
• Devolvem explicitamente um resultado ao exterior
Procedimentos
Conjunto de instruções, com interface bem definida, que faz
qualquer coisa
• Não devolvem explicitamente um resultado ao exterior
Nota * : designam-se muitas vezes por Sub-programas ou Rotinas; correspondem a operações (conjuntos
de instruções) que um programa (ou Classe) executa, quando dele se pretende uma dado comportamento
3
Introdução à Programação
2007/2008
Sintaxe (declaração)
Classe? static?
Falaremos disto mais tarde
Funções de classe
public static tipo nome(parâmetros) {
instruções;
Declaração / cabeçalho
return variável;
Corpo
}
Tipo e nome de cada parâmetro (separados por
virgulas), ex: (int x, char a, String s, double[][] m)
Variáveis que só existem dentro do método (var. locais)
4
Introdução à Programação
2007/2008
Sintaxe (declaração)
Procedimentos de classe
public static void nome(parâmetros) {
instruções;
}
Declaração / cabeçalho
Corpo
Tipo e nome de cada parâmetro (separados por
virgulas), ex: (int x, char a, String s, double[][] m)
Variáveis que só existem dentro do método (var. locais)
5
Introdução à Programação
2007/2008
Sintaxe (utilização)
parâmetros
do método
Estando declarada a função de classe
public static tipo nome(tipo1 par1, …) {…}
Usa-se do seguinte modo :
tipo var_retorno = nome(arg1, arg2, …)
( a sua chamada integra-se numa instrução para o valor de retorno poder ser utilizado )
Estando declarado o procedimento de classe
public static void nome(tipo1 par1,…) {…}
Usa-se do seguinte modo: nome(arg1, arg2, …)
( basta saber o nome do procedimento, para que serve e que eventuais dados necessita )
6
Introdução à Programação
2007/2008
Passagem de argumentos
Parâmetros (do método) são sinónimos dos
argumentos respectivos (com que é chamado o método)
Em Java não há indicação explícita de
passagem por referência!
Argumentos são sempre passados por valor
(ainda que o valor seja uma referência)
7
Tipos primitivos: parâmetro é uma cópia do valor do
argumento
Outros tipos: parâmetro é uma cópia da referência (i.e.
aponta para os mesmos dados que o argumento)
Introdução à Programação
2007/2008
Tamanho dos métodos
Ideal
8
até 10 linhas
Em casos extremos
(sintético, estruturado,
simples e claro)
Normal
1 a 5 linhas
até 60 linhas
Nunca mais de 60 linhas!
Introdução à Programação
2007/2008
Construindo uma função
Uma função que procura, numa lista (matriz)
de palavras (String), uma palavra começada
por uma determinada letra e devolve a primeira
encontrada nessas condições, ou null se não
encontrar:
O que será devolvido?
Como se chama a função?
Quais os dados (parâmetros) que precisa?
Qual o algoritmo?
9
Introdução à Programação
2007/2008
Construindo uma função
Uma função que procura numa matriz uma palavra começada
por uma letra
O que é devolvido?
uma palavra
Qual o nome da função?
procuraPalavra (sem espaços!)
Quais os dados que precisa?
uma matriz de palavras e uma letra (são dois parâmetros)
Em Java:
public static String procuraPalavra(String[]
lista_de_palavras, char letra)
10
Introdução à Programação
2007/2008
Construindo uma função
Uma função que procura numa matriz uma palavra começada
por uma letra
public static String procuraPalavra(String[]
lista_de_palavras, char letra) {
// começa a procurar no início da lista
// enquanto não chegar ao fim e não encontrar palavra começada
pela letra pedida, fazer:
// … continua a procurar no resto da lista (progresso)
// se encontrou palavra então devolve-a
// senão devolve null
}
11
Introdução à Programação
2007/2008
Construindo uma função
public static String procuraPalavra(String[]
lista_de_palavras, char letra) {
int i = 0;
// começa no início da lista; enquanto não chegar ao fim da lista
// e não encontrar palavra começada pela letra pedida, fazer:
while (i != lista_de_palavras.length
}
++i;
&& letra != lista_de_palavras[i].charAt(0)) {
// continua a procurar no resto da lista
if (i != lista_de_palavras.length)
return lista_de_palavras[i];
// se encontrou palavra então …
// … devolve-a
return null;
// senão devolve null
}
Porque não está aqui o else ?
12
Introdução à Programação
2007/2008
Exemplo de um procedimento
Um procedimento que pergunta uma letra ao
utilizador e escreve no ecrã uma palavra (existente
numa matriz) começada por essa letra ou indica ao
utilizador que não encontrou
O que é devolvido?
Como se chama o procedimento?
Quais os dados que precisa?
Qual o algoritmo?
13
Introdução à Programação
2007/2008
Exemplo de um procedimento
Um procedimento que pergunta uma letra ao utilizador e
escreve no ecrã uma palavra começada por essa letra
O que é devolvido?
NADA! (escrever no ecrã NÃO É o mesmo que devolver)
Como se chama o procedimento?
escrevePalavra (ou escrevePalavraComeçadaPor)
Quais os dados que precisa?
Uma lista de palavras (solicitada ao utilizador dentro do procedimento)
Em Java:
public static void escrevePalavra(String[]
lista_de_palavras)
14
Introdução à Programação
2007/2008
Exemplo de um procedimento
Procedimento que pergunta uma letra ao utilizador e escreve no
ecrã uma palavra começada por essa letra
public static void escrevePalavra(String[] lista_de_palavras)
{
// pede ao utilizador para inserir uma letra
// Lê a letra
// procura palavra começada por: letra em lista_de_palavras
// se encontrou
// … mostra palavra ao utilizador
// senão
// … mostra ao utilizador mensagem a indicar que não encontrou
}
15
Introdução à Programação
2007/2008
Exemplo de um procedimento
Procedimento que pergunta uma letra ao utilizador e escreve no ecrã uma
palavra começada por essa letra
public static void escrevePalavra(String[] lista_de_palavras) {
System.out.println(“Introduza uma letra e <enter>: ”);
Scanner teclado = new Scanner (System.in);
String s = teclado.next();
// Lê a letra
char letra = s.charAt(0);
// procura palavra começada por: letra
String palavra = procuraPalavra (lista_de_palavras, letra);
if (palavra != null) { // se encontrou … mostra palavra ao utilizador
System.out.println(“Palavra encontrada: ” + palavra);
} else { // senão … mostra ao utilizador … que não encontrou
System.out.println(“Palavra não encontrada”);
}
Este else é necessário?
}
16
Introdução à Programação
2007/2008
Utilização do procedimento
public class CodificadorDeLetra {
// declaração da função e procedimento
public static void main(String[] argumentos) {
String[] palavras = {“Alfa”, “Bravo”,
“Charlie”, “Dado”, “Era”,
\\ …,
“Wolkswagen”,”Zebra”};
escrevePalavra(palavras);
}
}
17
Introdução à Programação
2007/2008
Fluxo de controlo
Início do programa
1. Chamada de main() (sempre)
2. Chamada de escrevePalavra()
3. Chamada de procuraPalavra()
Programa CodificadorDeLetra
escrevePalavra()
5
•
3
4
4. Devolução de procuraPalavra()
•
procuraPalavra()
1
2
main()
escrevePalavra() ainda
em execução!
devolve a palavra
encontrada e volta a executar
escrevePalavra() no ponto
onde foi suspenso
5. Retorno de escrevePalavra()
•
Não devolve nada,
é um procedimento
Fim do programa
(Duvida? faça o traçado/debug e verifique)
18
Introdução à Programação
2007/2008
Outro exemplo: Somador de
fracções
public class SomadorDeFracções {
/** ... */
public static int mdc (final int m, final int n) {
...
}
/** ... */
public static void escreveFracção (final int n,
final int d) {
...
}
public static void main(String[] argumentos) {
...
}
}
19
Introdução à Programação
2007/2008
Papeis do programador
Programador assume papeis distintos:
Produtor
• Desenvolve mecanismo do módulo
• Preocupa-se com:
• o que faz
• como se vai usar
• como funciona
Consumidor
• Integra cada módulo num sistema mais complexo
• Preocupa-se com:
• o que faz
• como se usa (que argumentos precisa)
20
Introdução à Programação
2007/2008
Contrato (programação por…)
Entre produtor e consumidor
Produtor: Indica como se usa
Produtor: Garante resultados …
…se consumidor respeitar condições de
utilização
21
Introdução à Programação
2007/2008
Contrato (programação por…)
Dito de outro modo:
Permite indicar quais as funcionalidades que são oferecidas
ao “exterior”
Indica que tipo de informação precisa para executar a
função
Indica qual deverá ser o comportamento esperado
Comportamento descrito com a máxima exactidão possível
22
Introdução à Programação
2007/2008
Contrato (programação por…)
Cada método deve indicar o seu contrato
Cada contrato contém (pelo menos)
Descrição sumária do funcionamento
Restrições aos argumentos a fornecer
• Pré-condições
Resultado preciso da execução
• Condição Objectivo
• Para funções, se possível: nome=<expressão c/ param.>
• Se for procedimento, mais informalmente dizer o que faz
23
Introdução à Programação
2007/2008
Máximo divisor comum (VIII)
/** Devolve o máximo divisor comum dos inteiros positivos passados como argumento.
@pre 0 < m e 0 < n.
@post o valor r devolvido é o mdc de m e n. */
public static int mdc(final int m, final int n) {
int r;
Documentação: o que faz?
quais os valores possíveis
para os argumentos?
if(m < n)
r = m;
else
Cabeçalho:
como se usa
r = n;
while(m % r != 0 || n % r != 0)
--r;
Corpo: como funciona ?
return r;
(só o produtor é que se
preocupa com esta parte)
}
24
Introdução à Programação
2007/2008
Máximo divisor comum (IX)
/** Devolve o máximo divisor comum dos inteiros positivos passados como
argumentos.
@pre 0 < m e 0 < n.
@post o valor r devolvido é o mdc de m e n. */
public static int mdc(final int m, final int n) {
assert 0 < m;
assert 0 < n;
Instruções de
asserção
(afirmação)
…
assert 0 < r;
assert m % r == 0;
assert n % r == 0;
return r;
}
25
Introdução à Programação
2007/2008
Máximo divisor comum
(com tratamento de Excepções)
/** Devolve o máximo divisor comum dos inteiros positivos passados como
argumentos.
@pre 0 < m e 0 < n
Atenção às
pré-condicões!
@post return r (é o mdc de m e n) */
public static int mdc (final int m, final int n) {
if (m <= 0 || n <= 0)
throw new IllegalArgumentException
("Pelo menos um dos argumentos é errado!");
…
verificar a validade
dos argumentos
antes de usar!
return r;
}
26
Introdução à Programação
2007/2008
Outro exemplo: Busca estranha...
(com tratamento de Excepções)
/** Devolve o caractere que tem o índice x numa dada String (o inteiro x e a String s
passados como argumentos)
Atenção às
pré-condicões!
@pre s != null e 0 <= x < s.length()
@post return caractere com índice x em s */
// ...
public static char charAtVerificado (String s, int x){
if (s == null || x < 0 || x >= s.length())
throw new IllegalArgumentException("Wrong Argument");
return s.charAt(x);
}
}
verificar a validade
dos argumentos
antes de usar!
27
Introdução à Programação
2007/2008
Especificação de contrato
No cabeçalho de rotinas
Etiquetas @pre, @post, etc.
Forçar a existência de pré e pós-condições – e recorrer a
asserções – dá origem a programas optimizados, e minimiza
os erros de programação.
No código Java
Instruções assert
Uma asserção é uma instrução que permite testar
determinados pontos-chave do programa.
As asserções permitem confirmar se o funcionamento do
programa corresponde ao que dele esperamos/pretendemos.
28
Introdução à Programação
2007/2008
Especificação de contrato
Pré-condições e condições objectivo
29
Possível especificá-las:
Ao nível de métodos
Ao nível de instruções mais elementares
Introdução à Programação
2007/2008
Exemplo: absolutoDe()
/** Devolve o valor absoluto do parâmetro.
O que faz
@pre ?.
@post ?. */
public static int absolutoDe (final int valor) {
...
}
Como funciona
Como se usa
30
Introdução à Programação
2007/2008
absolutoDe(): pré-condição
/** Devolve o valor absoluto do argumento.
@pre V. // Todos os valores do parâmetro são válidos
@post ?. */
public static int absolutoDe(final int valor) {
...
}
31
Introdução à Programação
2007/2008
absolutoDe():
condição-objectivo
/** Devolve o valor absoluto do argumento.
@pre V.
@post 0 ≤ absolutoDe. */
public static int absolutoDe (final int valor) {
...
}
É suficiente?
Não há relação entre o valor devolvido e valor!
32
Introdução à Programação
2007/2008
absolutoDe():
condição-objectivo
/** Devolve o valor absoluto do argumento.
@pre V.
@post 0 ≤ absolutoDe. */
public static int absolutoDe (final int valor) {
return 5;
}
Errado! Mas, ...
A condição objectivo (C.O.) verifica-se!
Há muitas C.O. que são válidas, mas umas são
melhores que outras (as mais restritivas)
33
Introdução à Programação
2007/2008
absolutoDe(): Cond.-Objectivo
/** Devolve o valor absoluto do argumento.
@pre V.
@post 0 ≤ absolutoDe e
(absolutoDe = valor ou
absolutoDe = -valor). */
public static int absolutoDe (final int valor) {
...
}
34
Introdução à Programação
2007/2008
absolutoDe()
/** Devolve o valor absoluto do argumento.
@pre V.
@post 0 ≤ absolutoDe e
(absolutoDe = valor ou
absolutoDe = -valor). */
public static int absolutoDe (final int valor) {
int absoluto;
...
return absoluto;
}
35
Introdução à Programação
2007/2008
absolutoDe()
/** Devolve o valor absoluto do argumento.
@pre V.
@post 0 ≤ absolutoDe e
(absolutoDe = valor ou absolutoDe = -valor). */
public static int absolutoDe(final int valor) {
// V
int absoluto;
Asserções: afirmações
acerca do estado do
programa
...
// 0 ≤ absoluto e
// (absoluto = valor ou absoluto = -valor)
return absoluto;
}
36
Introdução à Programação
2007/2008
absolutoDe()
/** Devolve o valor absoluto do argumento.
@pre V.
@post 0 ≤ absolutoDe e
(absolutoDe = valor ou absolutoDe = -valor). */
public static int absolutoDe(final int valor) {
assert true;
Instruções de
Asserções:
afirmações
asserção:
acerca do estado
verificação
explícita
dode
programa
asserções.
// V
int absoluto;
Para usar no Eclipse é necessário
a flag de execução – ea.
(Run/Run/(X)=Arguments/VM
arguments): -ea
...
// 0 ≤ absoluto e
// (absoluto = valor ou absoluto = -valor)
assert 0 <= absoluto;
assert absoluto == valor || absoluto == -valor;
return absoluto;
}
37
Introdução à Programação
2007/2008
absolutoDe()
/** Devolve o valor absoluto do argumento.
@pre V.
@post 0 ≤ absolutoDe e
(absolutoDe = valor ou absolutoDe = -valor). */
public static int absolutoDe(final int valor) {
Instruções de
Asserções:
afirmações
asserção:
acerca do estado
verificação
explícita
dode
programa
asserções.
int absoluto;
...
// 0 ≤ absoluto e
// (absoluto = valor ou absoluto = -valor)
Para usar no Eclipse é necessário
a flag de execução – ea.
(Run/Run/(X)=Arguments/VM
arguments): -ea
assert 0 <= absoluto;
assert absoluto == valor || absoluto == -valor;
return absoluto;
}
38
Introdução à Programação
2007/2008
absolutoDe()
Instruções que resolvem o problema:
absoluto = valor;
absoluto = -valor;
39
Introdução à Programação
2007/2008
absolutoDe(): PC1
// PC1: 0 ≤ -valor e
// (-valor = valor ou -valor = -valor), ou seja,
// PC1: valor ≤ 0 e (-valor = valor ou V), ou seja,
// PC1: valor ≤ 0 e V, ou seja,
// PC1: valor ≤ 0
if (valor <= 0)
absoluto = -valor;
// 0 ≤ absoluto e
// (absoluto = valor ou absoluto = -valor)
40
Introdução à Programação
2007/2008
absolutoDe(): PC2
// PC2: 0 ≤ valor e
//
(valor = valor ou valor = -valor), ou seja,
// PC2: 0 ≤ valor e (V ou valor = -valor), ou seja,
// PC2: 0 ≤ valor e V, ou seja,
// PC2: 0 ≤ valor
if (valor >= 0)
absoluto = valor;
// 0 ≤ absoluto e
// (absoluto = valor ou absoluto = -valor)
41
Introdução à Programação
2007/2008
absolutoDe()
/** Devolve o valor absoluto do argumento.
@pre V.
@post 0 ≤ absolutoDe e (absolutoDe = valor ou absolutoDe = -valor). */
public static int absolutoDe(final int valor) {
assert true;
// V
int absoluto;
if (valor < 0)
absoluto = -valor;
else
absoluto = valor;
// 0 ≤ absoluto e (absoluto = valor ou absoluto = -valor)
assert 0 <= absoluto;
assert absoluto == valor || absoluto == -valor;
return absoluto;
}
42
Introdução à Programação
2007/2008
A reter...
Métodos (ou Rotinas)
Servem para agrupar instruções associadas. Executam um cálculo ou procedimento bem
definido
Têm parâmetros
Funções devolvem um valor
Procedimentos não devolvem nenhum valor, apenas realizam acções
Passagem de argumentos
•
Tipos primitivos: são cópias, o argumento original não pode ser alterado
•
Outros: são referências: o argumento original pode ser alterado
Programação por contrato
•
Se o utilizador cumprir as pré-condições (restrições ao valor dos argumentos) o programador da função/instrução garante as pós-condições (restrições ao resultado da rotina)
•
Pré-condições devem ser sempre verificadas
(usando assert ou outros métodos … de que falaremos em breve)
43
Introdução à Programação
2007/2008
A ler...
Capítulo 6:
Y. Daniel Liang, "Introduction to Java
Programming", 5ª Edição, Prentice-Hall, 2005.
ISBN: 0-13-185721 - 5
44
Introdução à Programação
2007/2008
Aula 5: Sumário
Modularização, abstracção e encapsulamento.
Métodos como unidades atómicas de modularização.
Sintaxe da definição de métodos: cabeçalho vs. corpo.
Comprimento típico de métodos.
Interface e implementação.
Parâmetros e argumentos.
Instrução return. Retorno e devolução.
Procedimentos: não há devolução (tipo de devolução void).
Invocação de métodos.
Parâmetros como instâncias locais.
Passagem de argumentos.
Contratos e Asserções.
45
Introdução à Programação
2007/2008