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
Download

V - padoca