Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


Programação Orientada a Objetos - Apostilas - Computação Científica Parte1, Notas de estudo de Informática

Apostilas de Computação Científica sobre o estudo da Programação Orientada a Objetos, Princípios da programação na linguagem Java, Operações sobre objetos.

Tipologia: Notas de estudo

2013

Compartilhado em 19/04/2013

Ipanema27
Ipanema27 🇧🇷

4.5

(170)

1 / 40

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
DEPARTAMENTO DE ENG ENHAR IA DE COM PUTAÇÃO E AUTOM AÇÃO INDU STRIA L
FACULDADE DE ENGENHARIA E TRICA E DE COMP UTAÇ ÃO
UNIV ERSIDADE ESTADUAL DE CAMP INAS
Programação Orientada a Objetos:
Uma Abordagem com Java
Ivan Luiz Marques Ricarte
2001
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28

Pré-visualização parcial do texto

Baixe Programação Orientada a Objetos - Apostilas - Computação Científica Parte1 e outras Notas de estudo em PDF para Informática, somente na Docsity!

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO E AUTOMAÇÃO INDUSTRIAL

FACULDADE DE ENGENHARIA ELÉTRICA E DE COMPUTAÇÃO

UNIVERSIDADE ESTADUAL DE CAMPINAS

Programação Orientada a Objetos:

Uma Abordagem com Java

Ivan Luiz Marques Ricarte

Sumário

Capítulo 1

Fundamentos da programação orientada

a objetos

Neste capítulo são apresentados os conceitos básicos que permeiam o uso das técnicas de orien- tação a objetos na programação, sempre utilizando a linguagem Java como motivador. Objetos são instâncias de classes, que determinam qual informação um objeto contém e como ele pode manipulá-la. Um dos grandes diferenciais da programação orientada a objetos em relação a outros paradigmas de programação que também permitem a definição de estruturas e operações sobre essas estruturas está no conceito de herança, mecanismo através do qual definições existentes podem ser facilmente estendidas. Juntamente com a herança deve ser enfatizada a importância do polimorfismo, que permi- te selecionar funcionalidades que um programa irá utilizar de forma dinâmica, durante sua execução.

1.1 Classes

A definição de classes e seus inter-relacionamentos é o principal resultado da etapa de projeto de software. Em geral, esse resultado é expresso em termos de alguma linguagem de modelagem, tal como UML. Uma classe é um gabarito para a definição de objetos. Através da definição de uma classe, descreve-se que propriedades — ou atributos — o objeto terá. Além da especificação de atributos, a definição de uma classe descreve também qual o compor- tamento de objetos da classe, ou seja, que funcionalidades podem ser aplicadas a objetos da classe. Essas funcionalidades são descritas através de métodos. Um método nada mais é que o equivalente a um procedimento ou função, com a restrição que ele manipula apenas suas variáveis locais e os atributos que foram definidos para a classe. Uma vez que estejam definidas quais serão as classes que irão compor uma aplicação, assim como qual deve ser sua estrutura interna e comportamento, é possível criar essas classes em Java. Na Unified Modeling Language (UML), a representação para uma classe no diagrama de classes é tipicamente expressa na forma gráfica, como mostrado na Figura 1.1. Como se observa nessa figura, a especificação de uma classe é composta por três regiões: o nome da classe, o conjunto de atributos da classe e o conjunto de métodos da classe.

Programação orientada a objetos com Java 1.2. Objetos

NomeClasse visibilidade nomeAtributo : tipo = valor default visibilidade nomeAtributo : tipo = valor default

...

visibilidade nomeMétodo(listaArgumentos) : tipoRetorno visibilidade nomeMétodo(listaArgumentos) : tipoRetorno

...

Figura 1.1: Uma classe em UML.

O nome da classe é um identificador para a classe, que permite referenciá-la posteriormente — por exemplo, no momento da criação de um objeto. O conjunto de atributos descreve as propriedades da classe. Cada atributo é identificado por um nome e tem um tipo associado. Em uma linguagem de programação orientada a objetos pura, o tipo é o nome de uma classe. Na prática, a maior parte das linguagens de programação orientada a objetos oferecem um grupo de tipos primitivos, como inteiro, real e caráter, que podem ser usados na descrição de atributos. O atributo pode ainda ter um valor_default opcional, que especifica um valor inicial para o atributo. Os métodos definem as funcionalidades da classe, ou seja, o que será possível fazer com objetos dessa classe. Cada método é especificado por uma assinatura , composta por um identificador para o método (o nome do método), o tipo para o valor de retorno e sua lista de argumentos, sendo cada argumento identificado por seu tipo e nome. Através do mecanismo de sobrecarga (overloading) , dois métodos de uma classe podem ter o mesmo nome, desde que suas assinaturas sejam diferentes. Tal situação não gera conflito pois o compilador é capaz de detectar qual método deve ser escolhido a partir da análise dos tipos dos argumentos do método. Nesse caso, diz-se que ocorre a ligação prematura (early binding) para o método correto. O modificador de visibilidade pode estar presente tanto para atributos como para métodos. Em princípio, três categorias de visibilidade podem ser definidas:

público, denotado em UML pelo símbolo +: nesse caso, o atributo ou método de um objeto dessa classe pode ser acessado por qualquer outro objeto (visibilidade externa total);

privativo, denotado em UML pelo símbolo - : nesse caso, o atributo ou método de um objeto dessa classe não pode ser acessado por nenhum outro objeto (nenhuma visibilidade externa);

protegido, denotado em UML pelo símbolo #: nesse caso, o atributo ou método de um objeto dessa classe poderá ser acessado apenas por objetos de classes que sejam derivadas dessa através do mecanismo de herança (ver Seção 1.3).

1.2 Objetos

Objetos são instâncias de classes. É através deles que (praticamente) todo o processamento ocorre em sistemas implementados com linguagens de programação orientadas a objetos. O uso racional de

Programação orientada a objetos com Java 1.3. Herança

1.3 Herança

O conceito de encapsular estrutura e comportamento em um tipo não é exclusivo da orientação a objetos; particularmente, a programação por tipos abstratos de dados segue esse mesmo conceito. O que torna a orientação a objetos única é o conceito de herança. Herança é um mecanismo que permite que características comuns a diversas classes sejam fa- toradas em uma classe base, ou superclasse. A partir de uma classe base, outras classes podem ser especificadas. Cada classe derivada ou subclasse apresenta as características (estrutura e métodos) da classe base e acrescenta a elas o que for definido de particularidade para ela. Há várias formas de relacionamentos em herança:

Extensão: a subclasse estende a superclasse, acrescentando novos membros (atributos e/ou méto- dos). A superclasse permanece inalterada, motivo pelo qual este tipo de relacionamento é normalmente referenciado como herança estrita.

Especificação: a superclasse especifica o que uma subclasse deve oferecer, mas não implementa ne- nhuma funcionalidade. Diz-se que apenas a interface (conjunto de especificação dos métodos públicos) da superclasse é herdada pela subclasse.

Combinação de extensão e especificação: a subclasse herda a interface e uma implementação pa- drão de (pelo menos alguns de) métodos da superclasse. A subclasse pode então redefinir métodos para especializar o comportamento em relação ao que é oferecido pela superclasse, ou ter que oferecer alguma implementação para métodos que a superclasse tenha declarado mas não implementado. Normalmente, este tipo de relacionamento é denominado herança polimórfica.

A última forma é, sem dúvida, a que mais ocorre na programação orientada a objetos. Algumas modelagens introduzem uma forma de herança conhecida como contração. Contração é uma uma variante de herança onde a subclasse elimina métodos da superclasse com o objetivo de criar uma “classe mais simples”. A eliminação pode ocorrer pela redefinição de métodos com corpo vazio. O problema com este mecanismo é que ele viola o princípio da substituição , segundo o qual uma subclasse deve poder ser utilizada em todos os pontos onde a superclasse poderia ser utilizada. Se a contração parece ser uma solução adequada em uma hierarquia de classes, provavelmente a hierarquia deve ser re-analisada para detecção de inconsistências (problema pássaros-pinguins). De modo geral, o mecanismo de contração deve ser evitado.

1.4 Polimorfismo

Polimorfismo é o princípio pelo qual duas ou mais classes derivadas de uma mesma superclasse podem invocar métodos que têm a mesma identificação (assinatura) mas comportamentos distintos, especializados para cada classe derivada, usando para tanto uma referência a um objeto do tipo da superclasse. Esse mecanismo é fundamental na programação orientada a objetos, permitindo definir funcionalidades que operem genericamente com objetos, abstraindo-se de seus detalhes particulares quando esses não forem necessários.

Programação orientada a objetos com Java 1.4. Polimorfismo

Para que o polimorfismo possa ser utilizado, é necessário que os métodos que estejam sendo definidos nas classes derivadas tenham exatamente a mesma assinatura do método definido na super- classe; nesse caso, está sendo utilizado o mecanismo de redefinição de métodos (overriding). Esse mecanismo de redefinição é muito diferente do mecanismo de sobrecarga de métodos, onde as listas de argumentos são diferentes. No caso do polimorfismo, o compilador não tem como decidir qual o método que será utilizado se o método foi redefinido em outras classes — afinal, pelo princípio da substituição um objeto de uma classe derivada pode estar sendo referenciado como sendo um objeto da superclasse. Se esse for o caso, o método que deve ser selecionado é o da classe derivada e não o da superclasse. Dessa forma, a decisão sobre qual dos métodos método que deve ser selecionado, de acordo com o tipo do objeto, pode ser tomada apenas em tempo de execução, através do mecanismo de ligação tardia. O mecanismo de ligação tardia também é conhecido pelos termos em inglês late binding , dynamic binding ou ainda run-time binding.

Programação orientada a objetos com Java 2.1. Tipos primitivos

em memória. O valor default de um atributo de classe do tipo char, se não especificado, é o caráter NUL (código hexadecimal 0000). Um valor literal do tipo caráter é representado entre aspas simples (apóstrofes), como em:

char umCaracter = ’A’;

Nesse caso, a variável ou atributo umCaracter recebe o caráter A, correspondente ao código hexadecimal 0041 ou valor decimal 65. Valores literais de caracteres podem também ser representados por seqüências de escape, como em ’\n’ (o caráter newline ). A lista de seqüências de escape reconhecidas em Java é apresentada na Tabela 2.1.

\b backspace \t tabulação horizontal \n newline \f form feed \r carriage return " aspas \’ aspas simples \ contrabarra \xxx o caráter com código de valor octal xxx, que pode assumir valo- res entre 000 e 377 na representação octal \uxxxx o caráter Unicode com código de valor hexadecimal xxxx, onde xxxx pode assumir valores entre 0000 e ffff na representação hexadecimal.

Tabela 2.1: Caracteres representados por seqüências de escape.

Seqüências de escape Unicode (precedidas por \u) são processadas antes das anteriores, podendo aparecer não apenas em variáveis caracteres ou strings (como as outras seqüências) mas também em identificadores da linguagem Java. Valores numéricos inteiros em Java podem ser representados por variáveis do tipo byte , short , int ou long. Todos os tipos contém valores inteiros com sinal, com representação interna em com- plemento de dois. O valor default para atributos desses tipos é 0. Cada um desses tipos de dados tem seu espaço de armazenamento definido na especificação da linguagem, não sendo dependente de diferentes implementações. Variáveis do tipo byte ocupam 8 bits de armazenamento interno. Com esse número de bits, é possível representar valores na faixa de - 128 a +127. Variáveis do tipo short ocupam 16 bits, podendo assumir valores na faixa de -32.768 a +32.767. Variáveis do tipo int ocupam 32 bits, podendo assumir valores na faixa de -2.147.483. a +2.147.483.647. Finalmente, variáveis do tipo long ocupam 64 bits, podendo assumir valores na faixa de -9.223.372.036.854.775.808 a +9.223.372.036.854.775.807. Constantes literais do tipo long podem ser identificadas em código Java através do sufixo l ou L, como em

long valorQuePodeCrescer = 100L;

Programação orientada a objetos com Java 2.2. Identificadores

Ao contrário do que ocorre em C, não há valores inteiros sem sinal (unsigned) em Java. Adicio- nalmente, as combinações da forma long int ou short int são inválidas em Java. Valores reais, com representação em ponto flutuante, podem ser representados por variáveis de tipo float ou double. Em qualquer situação, a representação interna desses valores segue o padrão de representação IEEE 754, sendo 0.0 o valor default para tais atributos. Como para valores inteiros, o espaço de armazenamento e conseqüentemente a precisão de valo- res associados a esses tipos de dados são definidos na especificação da linguagem. Variáveis do tipo float ocupam 32 bits, podendo assumir valores na faixa de     a       !#"%$ , com nove dígitos significativos de precisão. Variáveis do tipo double ocupam 64 bits, po- dendo assumir valores de &'( ) ) *  ) +, -"%./ a 01  2*   2*) +3 !#"%4%$ , com 18 dígitos significativos de precisão. Constantes literais do tipo float podem ser identificadas no código Java pelo sufixo f ou F; do tipo double, pelo sufixo d ou D.

2.2 Identificadores

Identificadores são seqüências de caracteres Unicode, que devem obedecer às seguintes regras:  Um nome pode ser composto por letras, por dígitos e pelos símbolos _ e $.

 Um nome não pode ser iniciado por um dígito (0 a 9).

 Letras maiúsculas são diferenciadas de letras minúsculas.

 Uma palavra-chave da linguagem Java (veja Apêndice A) não pode ser um identificador.

Java diferencia as letras minúsculas da maiúsculas. Assim, as duas variáveis

int socorro; int soCorro;

são variáveis diferentes. Além dessas regras obrigatórias, o uso da convenção padrão para identificadores Java torna a codificação mais uniforme e pode facilitar o entendimento de um código. Embora não seja obrigató- rio, o conhecimento e uso da seguinte convenção padrão para atribuir nomes em Java pode facilitar bastante a manutenção de um programa:

 Nomes de classes são iniciados por letras maiúsculas.

 Nomes de métodos, atributos e variáveis são iniciados por letras minúsculas.

 Em nomes compostos, cada palavra do nome é iniciada por letra maiúscula — as palavras não são separadas por nenhum símbolo.

Detalhes sobre as convenções de codificação sugeridas pelos projetistas da linguagem Java podem ser encontrados no documento Code Conventions for the JavaTM Programming Language^2. (^2) http://www.dca.fee.unicamp.br/projects/sapiens/calm/References/Java/codeconv/ CodeConventions.doc8.html

Programação orientada a objetos com Java 2.3. Expressões

deslocamento à direita, operador binário infixo denotado pelo símbolo >> que desloca a repre- sentação interna do primeiro operando para a direita pelo número de posições indicado pelo segundo operando. Os bits inseridos à esquerda terão o mesmo valor do bit mais significativo da representação interna;

deslocamento à direita com extensão 0, operador binário infixo denotado pelo símbolo >>> que desloca a representação interna do primeiro operando para a direita pelo número de posições indicado pelo segundo operando. Os bits inseridos à esquerda terão o valor 0.

2.3.2 Expressões retornando valores booleanos

As operações lógicas booleanas operam sobre valores booleanos. Operadores booleanos incluem:

complemento lógico, operador unário prefixo denotado pelo símbolo! que retorna true se o argu- mento é false ou retorna false se o argumento é true;

OR lógico booleano, operador binário infixo denotado pelo símbolo | que retorna true se pelo me- nos um dos dois argumentos é true;

OR lógico condicional, operador binário infixo denotado pelo símbolo || que opera como o cor- respondente booleano; porém, se o primeiro argumento já é true, o segundo argumento não é nem avaliado;

AND lógico booleano, operador binário infixo denotado pelo símbolo & que retorna false se pelo menos um dos dois argumentos é false;

AND lógico condicional, operador binário infixo denotado pelo símbolo && que opera como o cor- respondente booleano; porém, se o primeiro argumento já é false, o segundo argumento não é nem avaliado;

XOR booleano, operador binário infixo denotado pelo símbolo ^ que retorna true quando os dois argumentos têm valores lógicos distintos. Condições permitem realizar testes baseados nas comparações entre valores numéricos. Opera- dores condicionais incluem:

maior, operador binário infixo denotado pelo símbolo > que retorna true se o primeiro valor for exclusivamente maior que o segundo;

maior ou igual, operador binário infixo denotado pelo símbolo >= que retorna true se o primeiro valor for maior que ou igual ao segundo;

menor, operador binário infixo denotado pelo símbolo < que retorna true se o primeiro valor for exclusivamente menor que o segundo;

menor ou igual, operador binário infixo denotado pelo símbolo <= que retorna true se o primeiro valor for menor que ou igual ao segundo;

igual, operador binário infixo denotado pelo símbolo == que retorna true se o primeiro valor for igual ao segundo;

Programação orientada a objetos com Java 2.3. Expressões

diferente, operador binário infixo denotado pelo símbolo != que retorna true se o primeiro valor não for igual ao segundo.

2.3.3 Outros tipos de expressões

Assim como C e C++, Java oferece o operador condicional ternário denotado pelos símbolos ? :. Na expressão b? s1 : s2, b é uma expressão que resulta em um valor booleano (va- riável ou expressão). O resultado da expressão será o resultado da expressão (ou variável) s1 se b for verdadeiro, ou o resultado da expressão (ou variável) s2 se b for falso. O operador binário = atribui o valor da expressão do lado direito à variável à esquerda do opera- dor. Os tipos da expressão e da variável devem ser compatíveis. O operador de atribuição pode ser combinado com operadores aritméticos e lógicos, como em C e C++. Assim, a expressão

a += b

equivale a

a = a + b

Métodos em Java têm sua execução encerrada de duas maneiras possíveis. A primeira é válida quando um método não tem um valor de retorno (o tipo de retorno é void): a execução é encerrada quando o bloco do corpo do método chega ao final. A segunda alternativa encerra a execução do método através do comando return. Se o método tem tipo de retorno void, então o comando é usado sem argumentos:

return;

Caso o método tenha um valor de retorno especificado, então a expressão assume a forma

return expressão;

onde o valor de retorno é o resultado da expressão, que deve ser compatível com o tipo de retorno especificado para o método.

2.3.4 Controle do fluxo de execução

A ordem de execução normal de comandos em um método Java é seqüencial. Comandos de fluxo de controle permitem modificar essa ordem natural de execução através dos mecanismos de escolha ou de iteração. A estrutura if permite especificar um comando (ou bloco de comandos, uma seqüência de expres- sões delimitada por chaves, { e }) que deve apenas ser executado quando uma determinada condição for satisfeita:

if (condição) { bloco_comandos }

Quando o bloco de comandos é composto por uma única expressão, as chaves que delimitam o corpo do bloco podem ser omitidas:

Programação orientada a objetos com Java 2.3. Expressões

O comando for permite expressar iterações combinando uma expressão de inicialização, um teste de condição e uma expressão de incremento:

for (inicialização; condição; incremento) { bloco_comandos }

Embora Java não suporte o operador , (vírgula) presente em C e C++, no comando for múltiplas expressões de inicialização e de incremento podem ser separadas por vírgulas. Os comandos continue e break permitem expressar a quebra de um fluxo de execução. O uso de break já foi utilizado juntamente com switch para delimitar bloco de comandos de cada case. No corpo de uma iteração, a ocorrência do comando break interrompe a iteração, passando o controle para o próximo comando após o comando de iteração. O comando continue também interrompe a execução da iteração, mas apenas da iteração corrente. Como efeito da execução de continue, a condição de iteração é reavaliada e, se for verdadeira, o comando de iteração continua executando. Em situações onde há diversos comandos de iteração aninhados, os comandos break e conti- nue transferem o comando de execução para o ponto imediatamente após o bloco onde ocorrem. Se for necessário especificar transferência para o fim de outro bloco de iteração, os comandos break e continue rotulados podem ser utilizados:

label: { for (...; ...; ...) { ... while (...) { ... if (...) break label; ... } ... } ... }

2.3.5 Comentários

Comentários em Java podem ser expressos em três formatos distintos. Na primeira forma, uma “barra dupla” // marca o início do comentário, que se estende até o fim da linha. A segunda forma é o comentário no estilo C tradicional, onde o par de símbolos /* marca o início de comentário, que pode se estender por diversas linhas até encontrar o par de símbolos /, que delimita o fim do comentário. O outro estilo de comentário é específico de Java e está associado à geração automática de docu- mentação do software desenvolvido. Nesse caso, o início de comentário é delimitado pelas seqüên- cias de início /* e de término */. O texto entre essas seqüências será utilizado pela ferramenta javadoc (ver Seção 2.7.1) para gerar a documentação do código em formato hipertexto.

Programação orientada a objetos com Java 2.4. Operações sobre objetos

Para gerar esse tipo de documentação, os comentários devem estar localizados imediatamente antes da definição da classe ou membro (atributo ou método) documentado. Cada comentário pode conter uma descrição textual sobre a classe ou membro, possivelmente incluindo tags HTML, e diretrizes para o programa javadoc. As diretrizes para javadoc são sempre precedidas por @, como em

@see nomeClasseOuMembro

que gera na documentação um link para a classe ou membro especificado, precedido pela frase “See also ”. A documentação de uma classe pode incluir as diretrizes @author, que inclui o texto na seqüên- cia como informação sobre o autor do código na documentação; e @version, que inclui na docu- mentação informação sobre a versão do código. A documentação de um método pode incluir as diretrizes @param, que apresenta o nome e uma descrição de cada argumento do método; @return, que apresenta uma descrição sobre o valor de retorno; e @exception, que indica que exceções podem ser lançadas pelo método (ver Seção 2.6.1). Para maiores informações, veja o texto How to Write Doc Comments for Javadoc^3.

2.4 Operações sobre objetos

A criação de um objeto dá-se através da aplicação do operador new. Dada uma classe Cls, é possível (em princípio) criar um objeto dessa classe usando esse operador:

Cls obj = new Cls();

O “método” à direita do operador new é um construtor da classe Cls. Um construtor é um (pseudo-)método especial, definido para cada classe. O corpo desse método determina as atividades associadas à inicialização de cada objeto criado. Assim, o construtor é apenas invocado no momento da criação do objeto através do operador new. A assinatura de um construtor diferencia-se das assinaturas dos outros métodos por não ter ne- nhum tipo de retorno — nem mesmo void. Além disto, o nome do construtor deve ser o próprio nome da classe. O construtor pode receber argumentos, como qualquer método. Usando o mecanismo de sobre- carga, mais de um construtor pode ser definido para uma classe. Toda classe tem pelo menos um construtor sempre definido. Se nenhum construtor for explici- tamente definido pelo programador da classe, um construtor default , que não recebe argumentos, é criado pelo compilador Java. No entanto, se o programador da classe criar pelo menos um método construtor, o construtor default não será criado automaticamente — se ele o desejar, deverá criar um construtor sem argumentos explicitamente. No momento em que um construtor é invocado, a seguinte seqüência de ações é executada para a criação de um objeto:

  1. O espaço para o objeto é alocado e seu conteúdo é inicializado (bitwise) com zeros.
  2. O construtor da classe base é invocado. (^3) urlhttp://java.sun.com/products/jdk/javadoc/writingdoccomments.html

Programação orientada a objetos com Java 2.4. Operações sobre objetos

cada um desses objetos. Dessa forma, o programador não precisa se preocupar com a remoção explícita de objetos. Outra operação que pode envolver um objeto é sua verificação de tipo. Dado um objeto obj e uma classe Cls, é possível verificar dinamicamente (durante a execução do método) se o objeto pertence ou não à classe usando o operador instanceof. Este retorna true se o objeto à esquerda do operador é da classe especificada à direita do operador. Assim,

obj instanceof Cls

retornaria true se obj fosse da classe Cls.

2.4.1 Arranjos

Arranjos são agregados homogêneos de valores que podem agrupar literais ou objetos. A declaração de um arranjo, como

int array1[];

apenas cria uma referência para um arranjo de inteiros — porém o arranjo não foi criado. Assim como objetos, arranjos são criados com o operador new:

array1 = new int[100];

Essa expressão cria espaço para armazenar 100 inteiros no arranjo array1. As duas expressões poderiam ter sido combinadas em uma sentença incluindo a declaração e a criação de espaço:

int array1[] = new int[100];

Arranjos podem ser alternativamente criados com a especificação de algum conteúdo:

int array2[] = {2, 4, 5, 7, 9, 11, 13};

O acesso a elementos individuais de um arranjo é especificado através de um índice inteiro. O elemento inicial, assim como em C e C++, tem índice 0. Assim, do exemplo acima, a expressão

int x = array2[3];

faz com que a variável x receba o valor 7, o conteúdo da quarta posição. O acesso a elementos do arranjo além do último índice permitido — por exemplo, a array2[7] — gera um erro em tempo de execução, ou uma exceção (ver Seção 2.6.1). A dimensão de um arranjo pode ser obtida através da propriedade length presente em todos os arranjos. Assim, a expressão

int y = array2.length;

faz com que y receba o valor 7, o número de elementos no arranjo array2.

Programação orientada a objetos com Java 2.4. Operações sobre objetos

2.4.2 Strings

Ao contrário do que ocorre em C e C++, strings em Java não são tratadas como seqüências de caracteres terminadas por NUL. São objetos, instâncias da classe java.lang.String. Uma string pode ser criada como em: String s = "abc";

O operador + pode ser utilizado concatenar strings: System.out.println("String s: " + s);

Se, em uma mesma expressão, o operador + combinar valores numéricos e strings , os valores numé- ricos serão convertidos para strings e então concatenados. A classe String define um conjunto de funcionalidades para manipular strings através de seus métodos. Para obter o número de caracteres em uma string , o método int length() é usado. Assim, a expressão

s.length();

retornaria o valor 3. Para criar uma nova string a partir da concatenar duas strings , o método String concat(String outro) pode ser usado. Por exemplo,

String t = s.concat(".java");

faria com que a string t tivesse o conteúdo “abc.java”. Para comparar o conteúdo de duas strings há três formas básicas. O método equals(String outro) compara as duas strings , retornando verdadeiro se seus conteúdos forem exatamente iguais. Assim,

t.equals(s);

retornaria falso, mas

s.equals("abc");

retornaria verdadeiro. O método equalsIgnoreCase(String outro) tem a mesma funcio- nalidade mas ignora se as letras são maiúsculas ou minúsculas. Assim,

s.equalsIgnoreCase("ABC");

também retornaria verdadeiro. A terceira forma é através do método compareTo(String ou- tro), que retorna um valor inteiro igual a zero se as duas strings forem iguais, negativo se a string à qual o método for aplicado preceder lexicograficamente a string do argumento (baseado nos valores Unicode dos caracteres) ou positivo, caso contrário. Há também um método compareToIgnore- Case(String str). Para extrair caracteres individuais de uma string , pode-se utilizar o método charAt(int pos), que retorna o caráter na posição especificada no argumento (0 é a primeira posição). Para obter subs- trings de uma string , o método substring() pode ser utilizado. Esse método tem duas assinaturas: