aula 5 métodos, parâmetros, argumentos e contratos
TRANSCRIPT
Aula 5
Métodos, Parâmetros, Argumentos e Contratos
2007/2008Introdução à Programação2
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: String frase = “Uma frase”; String frase = new String(“Uma frase”); char primeiro = frase.charAt(0); char último = frase.charAt(frase.length() – 1));
2007/2008Introdução à Programação3
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
2007/2008Introdução à Programação4
Sintaxe (declaração)
Funções de classe
public static tipo nome(parâmetros) {
instruções;
return variável;
}
Classe? static?
Falaremos disto mais tarde
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)
2007/2008Introdução à Programação5
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)
2007/2008Introdução à Programação6
Sintaxe (utilização)
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 )
parâmetros do método
2007/2008Introdução à Programação7
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) 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)
2007/2008Introdução à Programação8
Tamanho dos métodos
Ideal
1 a 5 linhas
Normal
até 10 linhas
Em casos extremos
até 60 linhas
Nunca mais de 60 linhas!
(sintético, estruturado,simples e claro)
2007/2008Introdução à Programação9
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?
2007/2008Introdução à Programação10
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)
2007/2008Introdução à Programação11
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
}
2007/2008Introdução à Programação12
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
&& letra != lista_de_palavras[i].charAt(0)) { ++i; // continua a procurar no resto da lista}
if (i != lista_de_palavras.length) // se encontrou palavra então …
return lista_de_palavras[i]; // … devolve-a
return null; // senão devolve null
}
Porque não está aqui o else ?
2007/2008Introdução à Programação13
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?
2007/2008Introdução à Programação14
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)
2007/2008Introdução à Programação15
Exemplo de um procedimento
Procedimento que pergunta uma letra ao utilizador e escreve no ecrã uma palavra começada por essa letrapublic 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
}
2007/2008Introdução à Programação16
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?
2007/2008Introdução à Programação17
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);
}
}
2007/2008Introdução à Programação18
Fluxo de controlo
Programa CodificadorDeLetra
escrevePalavra()
procuraPalavra()
main()1 2
3 45
Início do programa1. Chamada de main() (sempre)2. Chamada de escrevePalavra()3. Chamada de procuraPalavra()
• escrevePalavra() aindaem execução!
4. Devolução de procuraPalavra()• devolve a palavra
encontrada e volta a executarescrevePalavra() no pontoonde foi suspenso
5. Retorno de escrevePalavra()• Não devolve nada,
é um procedimentoFim do programa
(Duvida? faça o traçado/debug e verifique)
2007/2008Introdução à Programação19
Outro exemplo: Somador de fracçõespublic 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) {
...
}
}
2007/2008Introdução à Programação20
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)
2007/2008Introdução à Programação21
Contrato (programação por…)
Entre produtor e consumidor
Produtor: Indica como se usa
Produtor: Garante resultados …
…se consumidor respeitar condições de
utilização
2007/2008Introdução à Programação22
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
2007/2008Introdução à Programação23
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
2007/2008Introdução à Programação24
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;
if(m < n)
r = m;
else
r = n;
while(m % r != 0 || n % r != 0)
--r;
return r;
}
Cabeçalho: como se usa
Corpo: como funciona ? (só o produtor é que se preocupa com esta parte)
Documentação: o que faz? quais os valores possíveis para os argumentos?
2007/2008Introdução à Programação25
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;
…
assert 0 < r;
assert m % r == 0;
assert n % r == 0;
return r;
}
Instruções de asserção (afirmação)
2007/2008Introdução à Programação26
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
@post return r (é o mdc de m e n) */
public static int mdc (final int m, final int n) {
if (m <= 0 || n <= 0)if (m <= 0 || n <= 0)
throw new IllegalArgumentExceptionthrow new IllegalArgumentException
("Pelo menos um dos argumentos é errado!");("Pelo menos um dos argumentos é errado!");
… return r;
}
Atenção às pré-condicões!
vverificar a validade erificar a validade dos argumentos dos argumentos antes de usar!antes de usar!
2007/2008Introdução à Programação27
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)
@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())if (s == null || x < 0 || x >= s.length())
throw new IllegalArgumentException("Wrong Argument");throw new IllegalArgumentException("Wrong Argument");
return s.charAt(x);
}
}
Atenção às pré-condicões!
vverificar a validade erificar a validade dos argumentos dos argumentos antes de usar!antes de usar!
2007/2008Introdução à Programação28
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.
2007/2008Introdução à Programação29
Especificação de contrato
Pré-condições e condições objectivo
Possível especificá-las:
Ao nível de métodos
Ao nível de instruções mais elementares
2007/2008Introdução à Programação30
Exemplo: absolutoDe()
/** Devolve o valor absoluto do parâmetro.
@pre ?.
@post ?. */
public static int absolutoDe (final int valor) {
...
}
O que faz
Como funcionaComo se usa
2007/2008Introdução à Programação31
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) {
...
}
2007/2008Introdução à Programação32
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!
2007/2008Introdução à Programação33
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)
2007/2008Introdução à Programação34
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) {
...
}
2007/2008Introdução à Programação35
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;
}
2007/2008Introdução à Programação36
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;
...
// 0 ≤ absoluto e
// (absoluto = valor ou absoluto = -valor)
return absoluto;
}
Asserções: afirmações acerca do estado do programa
Asserções: afirmações acerca do estado do programa
2007/2008Introdução à Programação37
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;
...
// 0 ≤ absoluto e
// (absoluto = valor ou absoluto = -valor)
assert 0 <= absoluto;
assert absoluto == valor || absoluto == -valor;
return absoluto;
}
Asserções: afirmações acerca do estado do programa
Instruções de asserção: verificação explícita de asserções. Para usar no Eclipse é necessário a flag de execução – ea.(Run/Run/(X)=Arguments/VM arguments): -ea
2007/2008Introdução à Programação38
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;
...
// 0 ≤ absoluto e
// (absoluto = valor ou absoluto = -valor)
assert 0 <= absoluto;
assert absoluto == valor || absoluto == -valor;
return absoluto;
}
Asserções: afirmações acerca do estado do programa
Instruções de asserção: verificação explícita de asserções. Para usar no Eclipse é necessário a flag de execução – ea.(Run/Run/(X)=Arguments/VM arguments): -ea
2007/2008Introdução à Programação39
absolutoDe()
Instruções que resolvem o problema:
absoluto = valor;
absoluto = -valor;
2007/2008Introdução à Programação40
absolutoDe(): PC1
// 0 ≤ absoluto e
// (absoluto = valor ou absoluto = -valor)
absoluto = -valor;
// 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)
2007/2008Introdução à Programação41
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)
2007/2008Introdução à Programação42
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;
}
2007/2008Introdução à Programação43
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 progra-mador 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)
2007/2008Introdução à Programação44
A ler...
Capítulo 6:
Y. Daniel Liang, "Introduction to Java Programming", 5ª Edição, Prentice-Hall, 2005.ISBN: 0-13-185721 - 5
2007/2008Introdução à Programação45
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.