A partir do estudo desta unidade, você deverá ser capaz de:
compreender o funcionamento da linguagem JAVA usando Programação Orientada a Objetos;
criar classes, objetos e realizar seus relacionamentos possíveis usando JAVA;
realizar relações de herança entre as classes construídas em Java;
criar e usar adequadamente interfaces utilizando a linguagem Java.
PLANO DE ESTUDOS
A cada tópico desta unidade, você encontrará autoatividades com o objetivo de reforçar o conteúdo apresentado.
Bem-vindo à Unidade 2 da disciplina de Programação Orientada a Objetos. Nesta etapa, vamos conhecer algumas estruturas simples relacionadas à programação orientada a objetos.
Nesta Unidade abordaremos alguns conteúdos relacionados ao tema de classes e objetos, tais quais construtores, uso da palavra reservada “this” bem como utilizar inicializadores e pacotes.
Quais os objetivos de aprendizagem da Unidade 2? Confira:
Compreender o funcionamento da linguagem JAVA usando Programação Orientada a Objetos;
Criar classes, objetos e realizar seus relacionamentos possíveis usando JAVA;
Realizar relações de herança entre as classes construídas em Java;
Criar e usar adequadamente interfaces utilizando a linguagem Java.
O paradigma orientado a objetos tomou forma a partir do conceito inicial de uma nova abordagem de programação, enquanto o interesse em design e métodos de análise veio muito mais tarde.
A primeira linguagem orientada a objetos foi Simula (Simulação de sistemas reais) que foi desenvolvida em 1960 por pesquisadores do Centro Norueguês de Computação.
Em 1970, Alan Kay e seu grupo de pesquisa no Xerox PARK criaram um computador pessoal chamado Dynabook e a primeira linguagem de programação pura orientada a objetos (OOPL) - Smalltalk, para a programação do Dynabook.
Na década de 1980, Grady Booch publicou um artigo intitulado Object Oriented Design que apresentava principalmente um design para a linguagem de programação, Ada. Nas edições seguintes, ele estendeu suas ideias a um método completo de design orientado a objetos.
Na década de 1990, Coad incorporou ideias comportamentais a métodos orientados a objetos.
As outras inovações significativas foram As Técnicas de Modelagem de Objetos (OMT) de James Rumbaugh e Object-Oriented Software Engineering (OOSE), de Ivar Jacobson.
Que tal relacionar-se com os colegas por meio de um Fórum? Esse recurso favorece o diálogo, a troca de opiniões e de saberes, estimulando o debate e a reflexão em torno de temas, situações, problemas ou ideias encontradas em nossa vida acadêmica e pessoal.
Que tal realizar um Objeto de Aprendizagem? Sugerimos o artigo "Introdução à Programação Orientada a Objetos em Java", que serve para contextualizar brevemente sobre a Linguagem Java.
Vamos à indicação de documentários e vídeos? Eles também servem a propósitos didáticos, complementando a educação formal.
O Dicionário do Programador é o quadro semanal do Canal Código Fonte TV onde você poderá aprender mais sobre termos, tecnologias ou palavras do maravilhoso mundo da programação! Ele é uma ideia antiga, que tomou vida graças a grande ajuda da HostGator Brasil. O tema da vez é: Programação Orientada a Objetos - POO.
Por fim, lembre-se de reservar uma hora do seu dia para os estudos (por meio da leitura Do Livro Didático), para o desenvolvimento das Autoatividades e para buscar conhecimento por meio de outras referências bibliográficas. Restando dúvidas, entre em contato com a tutoria interna e os professores disponíveis nos diversos canais de comunicação disponibilizados.
Vamos prosseguir nossos estudos na Unidade 3?
SIGA EM FRENTE!
1 INTRODUÇÃO
Java é uma linguagem orientada a objetos, então conceitos como "classe" e "objeto" desempenham um papel fundamental nele. Qualquer programa em Java pode ser representado como um conjunto de objetos interativos.
O modelo ou descrição de um objeto é uma classe, e um objeto representa uma instância dessa classe. Também podemos desenhar a seguinte analogia. Todos temos alguma ideia de uma pessoa - tendo dois braços, duas pernas, cabeça, tronco, etc. Há algum padrão - este padrão pode ser chamado de classe. Uma pessoa real (na verdade, um exemplo desta classe) é um objeto desta classe.
Acadêmico, no Tópico 1, abordaremos alguns conteúdos relacionados ao tema de classes e objetos, como, por exemplo, construtores, uso da palavra reservada “this” e uso de inicializadores e pacotes.
2 CONSTRUTORES
A classe é definida usando a palavra-chave da classe:
Neste caso, a classe se chama Pessoa. Após o nome da classe há chaves, entre as quais o corpo da classe é colocado - ou seja, seus campos e métodos.
Qualquer objeto pode ter duas características principais:
estado- alguns dos dados que um objeto armazena;
comportamento - ações que um objeto pode executar.
Para armazenar o estado de um objeto em uma classe, você usa os campos ou variáveis da classe. Os métodos são usados para determinar o comportamento de um objeto em uma classe.
Por exemplo, uma classe de “pessoa”, que representa uma “pessoa” pode ter a seguinte definição:
A classe Pessoa define dois campos: o name representa o nome da pessoa, e age representa a idade da pessoa. E o método displayInfo também é definido, que não retorna nada e simplesmente produz esses dados para o console.
Agora vamos usar essa classe. Para isso, defina o seguinte programa:
Normalmente, as classes são definidas em diferentes arquivos. Neste caso, para simplificar, definimos duas classes no mesmo arquivo. Vale ressaltar que, neste caso, apenas uma classe pode ter um modificador público (neste caso, a classe do Programa), e o próprio arquivo de código deve ser nomeado após essa classe, ou seja, neste caso, o arquivo deve ser chamado de Programa.java.
Uma classe representa um novo tipo, para que possamos definir variáveis que representam esse tipo. Por exemplo, aqui no método principal, uma variável é definida, o que representa a classe Pessoa. Mas até agora, essa variável não aponta para nenhum objeto e por padrão tem um valor nulo. Em geral, não podemos usá-lo ainda, então primeiro precisamos criar um objeto da classe Pessoa.tom
Além dos métodos usuais, as classes podem definir métodos especiais chamados construtores. Construtores são chamados quando um novo objeto desta classe é criado. Os construtores iniciam o objeto. Desta forma, se nenhum construtor for definido em uma classe, um construtor sem parâmetros será criado automaticamente para essa classe.
A classe Pessoa acima definida não tem construtores. Portanto, um construtor padrão é criado automaticamente para ele, que podemos usar para criar o objeto Pessoa. Em particular, vamos criar um objeto:
Para criar um objeto Pessoa, use a expressão: new Pessoa()tom. O novo operador aloca memória no objeto Pessoa. E então, o construtor padrão é chamado uma vez que não tem parâmetros. Como resultado, após a execução desta expressão, uma área será alocada na memória onde todos os dados do objeto Pessoa serão armazenados. E a variável receberá uma referência ao objeto criado.
Se o construtor não inicializar os valores das variáveis do objeto, eles receberão seus valores padrões. Para variáveis numéricas do tipo, este é o número 0, e para o tipo de corda e classes, é nulo, ou seja, nenhum valor (null).
Após a criação do objeto, podemos acessar as variáveis do objeto Pessoa através da variável tom e definir ou obter seus valores, por exemplo, tom.name = "Tom"
Como resultado, veremos no console:
Se você quiser que alguma lógica seja feita quando você criar um objeto, por exemplo, se os campos da classe receberem alguns valores específicos, você pode definir seus próprios construtores na classe. Por exemplo:
Existem agora três construtores definidos na classe, cada um deles tem um número diferente de parâmetros e define os valores dos campos da classe.
Saída do console do programa:
3 USO DO THIS
Em todos os métodos normais (ou seja, métodos estáticos não estáticos, já que static é um método de construção de classe, nenhum objeto está envolvido), o sistema padrão inclui “this” implicitamente nos parâmetros formais do método super.
Por exemplo, o método study() é, na verdade, study(this, super) que armazena o endereço de um objeto. Super armazena o endereço da classe pai do objeto para que os parâmetros reais do método possam ser chamados por meio dela.
Em Java, a palavra-chave this tem muitos usos. Sendo está uma variável de referência, que se refere ao objeto atual.
Observe os exemplos:
A palavra-chave this pode ser usada para:
se referir a variáveis de instância da classe atual;
chamar um método da classe atual (implicitamente);
chamar o construtor da classe atual;
ser passada como um parâmetro para o método de chamada;
ser passada como um parâmetro ao chamar um construtor;
ser usada para retornar uma instância da classe atual de um método.
3.1 INSTÂNCIAS
A palavra-chave this pode ser usada para se referir a variáveis de instância da classe atual. Se houver uma ambiguidade entre variáveis de instância e parâmetros, a palavra-chave this pode ser usada para especificar explicitamente variáveis de classe para resolver algumas ambiguidades.
Vamos primeiro lidar com um exemplo que não usa a palavra-chave this:
O resultado da execução do código acima é assim:
No exemplo acima, os parâmetros (parâmetros formais) e variáveis de instância (rollno e name) são os mesmos. Portanto, use a palavra-chave “this” para distinguir entre variáveis locais e variáveis de instância.
O resultado da execução do código acima é:
Se as variáveis locais (parâmetros formais) e as variáveis de instância forem diferentes, não será necessário usar a palavra-chave this, como no programa a seguir:
O resultado da execução do código acima é assim:
3.2 MÉTODOS DE CLASSES ATUAIS
Você pode usar a palavra-chave this para chamar métodos na classe atual. Se você não usar essa palavra-chave, o compilador adicionará automaticamente essa palavra-chave quando o método for chamado.
A chamada do construtor this() pode ser usada para chamar o construtor da classe atual. Ele é usado para reutilizar o construtor. Em outras palavras, ele é usado para vincular o construtor.
Ou seja, “this ();” é chamado uma vez e a classe também é chamada uma vez.
O resultado da execução do código acima é:
Chame o construtor parametrizado do construtor padrão [, ou seja, construtores diferentes chamam uns aos outros por this();]:
O resultado da execução do código acima é :
A chamada do construtor this() é usada para reutilizar um construtor de um construtor. Ele mantém o encadeamento entre construtores, ou seja, é usado para encadear construtores. Dê uma olhada no exemplo a seguir para mostrar o uso real dessa palavra-chave.
O resultado da execução do código acima é:
No exemplo a seguir, a instrução this() não cabe na primeira linha, portanto, a compilação falha.
O resultado da execução do código acima é:
Em circunstâncias em que uma classe pai tem um construtor padrão, a chamada para super é inserida automaticamente pelo compilador. Uma vez que todas as classes em Java adquirem do Object, o construtor de objetos deve ser chamado de qualquer maneira e deve ser realizado primeiro. A inserção automática de super() pelo compilador reconhece isso.
3.3 MÉTODO COMO PARÂMETRO
A palavra-chave “this” também pode ser passada como parâmetro em um método. É usado principalmente para manipulação de eventos. Considere o seguinte exemplo:
O resultado da execução do código acima é:
O método de invocação () da classe Método invoca o método subjacente representado por este objeto Método, no objeto especificado com os parâmetros especificados. Parâmetros individuais automaticamente para combinar parâmetros formais primitivos. Tanto os parâmetros primitivos quanto os de referência estão sujeitos a conversões de invocação de métodos, conforme necessário.
Em caso de manipulação de eventos uma referência de classe deve ser fornecida a outra. Ele é usado para reutilizar um objeto em vários métodos.
4 INICIALIZADORES E PACOTES
Além do construtor, a inicialização inicial do objeto poderia ser realizada usando o iniciador do objeto. O inicializador vai até qualquer construtor. Ou seja, no inicializador podemos colocar código comum a todos os construtores
Saída do console:
Normalmente, em Java, as classes são embaladas. Os pacotes permitem que você organize as classes logicamente em conjuntos. Por padrão, java já tem uma série de pacotes embutidos, por exemplo, java.lang, java.util, java.io, etc., além disso, os pacotes podem ter pacotes aninhados, ou seja, pacotes dentro de pacotes..
Organizar classes como pacotes evita conflitos de nomes entre as classes. Afinal, muitas vezes há situações em que os desenvolvedores chamam suas classes pelo mesmo nome. Pertencer a um pacote ajuda a garantir que os nomes sejam inequívocos.
Desta forma, para especificar que uma classe pertence a um pacote específico, você deve usar a diretiva package, seguida pelo nome do pacote.
Normalmente, os nomes dos pacotes correspondem à estrutura física do projeto, ou seja, a organização dos diretórios em que os arquivos de código-fonte estão localizados. E o caminho para os arquivos no projeto corresponde ao nome do pacote desses arquivos. Por exemplo, se as classes pertencem ao pacote mypack, essas classes são colocadas na pasta mypack no projeto.
As classes não devem ser definidas em pacotes. Se um pacote não for definido para uma classe, a classe é considerada no pacote padrão que não tem um nome.
Por exemplo, vamos criar um diretório de estudos na pasta para os arquivos de origem. Nele, crie um arquivo java Programa com o seguinte código:
A diretiva no início do arquivo indica que as classes Programa e Pessoa , definidas aqui, pertencem ao pacote de estudo, ou seja: package study.
Quando trabalhamos em um ambiente de desenvolvimento, como o Netbeans e o IDE — conceito estudado na unidade anterior, cuida de toda a compilação de pacotes e seus arquivos. Assim, só precisamos apertar o botão, e tudo estará pronto. No entanto, se compilarmos um programa na linha de comando, então podemos encontrar algumas dificuldades. Então considere esse aspecto.
Para compilar o programa, primeiro na linha de comando/terminal usando o comando cd, vá para a pasta onde está localizado o diretório de estudos.
Por exemplo, no meu caso, este é o diretório C:\java (ou seja, o arquivo de código-fonte está localizado em C:\java\study\Program.java).
Para compilar, execute o comando:
Os arquivos .class Programa.class e Pessoa compilados aparecerão na pasta de estudo. Para executar o programa, execute o comando:
4.1 IMPORTAÇÃO DE PACOTES E CLASSES
Se precisarmos usar classes de outros pacotes, precisamos conectar esses pacotes e classes. As exceções são as classes no pacote java.lang, por exemplo, os quais são automaticamente conectadas ao programa.String
Por exemplo, a classe Scanner familiar dos tópicos anteriores está no pacote java.util, para podermos acessá-lo da seguinte maneira:
Para tanto, especificamos o caminho completo para o arquivo no pacote quando criamos seu objeto. No entanto, essa mistura de nomes de pacotes nem sempre é conveniente, e alternativamente podemos importar pacotes e classes para o projeto usando a diretiva de importação especificada após a diretiva do pacote:
A diretiva é especificada no início do código, seguida pelo nome da classe plug-in (neste caso, a classe Scanner).
No exemplo acima, só conectamos uma classe, mas o pacote contém muito mais classes. E para não conectar cada classe separadamente, podemos conectar imediatamente todo o pacote:java.util
A diretiva é especificada no início do código, seguida pelo nome da classe plug-in (neste caso, a classe Scanner).
No exemplo acima, só conectamos uma classe, mas o pacote contém muito mais classes. E para não conectar cada classe separadamente, podemos conectar imediatamente todo o pacote:java.util
Agora podemos usar qualquer classe do pacote java.util.
É possível que usemos duas classes com o mesmo nome de dois pacotes diferentes, por exemplo, a classe Data está presente tanto no pacote java.util quanto no pacote java.sql. E se precisarmos usar essas duas classes ao mesmo tempo, então precisamos especificar o caminho completo para essas classes no pacote:
4.2 IMPORTAÇÃO ESTÁTICA
Java também tem uma forma especial de importação: importação estática. Para fazer isso, com a diretiva, o modificador é usado é import static
É aqui que as classes de Sistema e Matemática são estaticamente importadas. Essas classes têm métodos estáticos. Graças à operação de importação estática, podemos usar esses métodos sem o nome da classe. Por exemplo, escrever não, mas, uma vez que a função , que retorna a raiz quadrada do número, é estática. (Mais tarde, olharemos para os membros da classe estática.)Math.sqrt(20)sqrt(20)sqrt()
O mesmo vale para a classe Sistema: define um objeto estático, para podermos usá-lo sem especificar a classe.out.
RESUMO DO TÓPICO 1
Neste tópico, você aprendeu:
Compreendeu o conceito de classes e objetos e sua estrutura usando a linguagem Java.
Aprendeu a utilizar adequadamente construtores para criar novas classes usando a linguagem Java.
Entendeu o funcionamento e a importância da palavra reservada “this” no paradigma de orientação a objetos em Java.
Utilizou de maneira adequada novas funcionalidades impulsionadas pelo uso de pacotes da linguagem Java.
AUTOATIVIDADE
1 Classes e Objetos são conceitos básicos de Programação Orientada a Objetos que giram em torno de entidades da realidade. Uma classe é um projeto ou protótipo definido pelo usuário a partir do qual os objetos são criados. Ele representa o conjunto de propriedades ou métodos que são comuns a todos os objetos de um tipo. Sobre orientação a, objetos e classes em Java, julgue a alternativa CORRETA:
a) ( ) Para armazenar o estado de um objeto em uma classe, você usa os campos ou variáveis da classe.
b) ( ) Objetos na linguagem Java não possuem nenhuma característica.
c) ( ) Os métodos são usados para determinar o comportamento de um modificador de acesso em uma classe.
d) ( ) Normalmente, as classes são definidas em arquivos únicos.
2 A programação orientada a objetos visa implementar entidades reais como herança, ocultação, polimorfismo, etc. na programação. O principal objetivo do POO é vincular os dados e as funções que operam neles para que nenhuma outra parte do código possa acessar esses dados, exceto essa função. Com base nas definições e conceitos da Programação Orientada a Objetos, analise as sentenças a seguir:
I- Uma classe representa um novo tipo, para que possamos definir variáveis que representam esse tipo.
II- Construtores são chamados sempre que há objetos antigos.
III- Além dos métodos usuais, as classes podem definir métodos especiais chamados construtores.
Assinale a alternativa CORRETA:
a) ( ) As sentenças I e II estão corretas.
b) ( ) Somente a sentença II está correta.
c) ( ) As sentenças I e III estão corretas.
d) ( ) Somente a sentença III está correta.
3 Construtores são usados para inicializar novos objetos. Campos são variáveis que fornecem o estado da classe e seus objetos, e métodos são usados para implementar o comportamento da classe e seus objetos. Existem vários tipos de classes, utilizadas em aplicações em tempo real, como classes aninhadas, classes anônimas, expressões lambda.
Conforme as características dos construtores, classifique V para as sentenças verdadeiras e F para as falsas:
( ) Se nenhum construtor for definido em uma classe, um construtor sem parâmetros será criado automaticamente para essa classe.
( ) O construtor em programação orientada a objetos é usado unicamente para criar variáveis e colocá-la em um lugar do código.
( ) Se o construtor não inicializar os valores das variáveis do objeto, eles receberão seus valores padrão.
Assinale a alternativa que apresenta a sequência CORRETA:
a) ( ) V – F – F.
b) ( ) V – F – V.
c) ( ) F – V – F.
d) ( ) F – F – V.
4 A palavra reservada “this” em Java é uma variável de referência que se refere ao objeto atual de um método ou de um construtor. O principal objetivo de usar esta palavra-chave em Java é remover a confusão entre atributos de classe e parâmetros com os mesmos nomes. Disserte sobre os usos variados desta palavra na linguagem Java.
5 O pacote em Java é um mecanismo para encapsular um grupo de classes, subclasses e interfaces. Um pacote é um contêiner de um grupo de classes relacionadas onde algumas das classes são acessíveis são expostas e outras são mantidas para fins internos.
Podemos reutilizar as aulas existentes dos pacotes quantas vezes precisarmos em nosso programa. Neste contexto, disserte sobre o uso desses pacotes nos programas em Java.
1 INTRODUÇÃO
Todos os membros da classe em java — campos e métodos — têm modificadores de acesso. Em tópicos passados, nos deparamos com o modificador. Os modificadores de acesso permitem especificar um escopo válido para os membros da classe, que é o contexto no qual uma determinada variável ou método public pode ser usado.
Java usa os seguintes modificadores de acesso:
public: um membro público, público ou de classe. Campos e métodos declarados com o modificador público são visíveis para outras classes no pacote atual e de pacotes externos;
private: uma classe privada ou membro de classe, em oposição ao modificador público. Um membro de classe privada está disponível apenas a partir do código na mesma classe;
protected: tal classe ou membro de classe é acessível de qualquer lugar da classe, ou pacote atual, ou em classes derivadas, mesmo que estejam em outros pacotes.
A ausência de um modificador para um método de campo ou classe implica que um modificador padrão é aplicado-lhe. Tais campos ou métodos são visíveis para todas as classes do pacote atual.
Acadêmico, no Tópico 2, abordaremos conteúdos relacionados a temática de membros de modificadores, tais quais, encapsulação, campos estáticos e objetos como parâmetro de métodos usando a linguagem Java.
2 ENCAPSULAMENTO
Consideremos modificadores de acesso vistos na introdução no exemplo do seguinte programa:
Conforme observado acima, o código inicia com o método principal criando o objeto Pessoa, este que possui sua classe logo abaixo. A classe possui os atributos name, age, address e phone. Esta ainda possui métodos declarados como displayName que mostra seu nome, displayAge que mostra sua idade, displayAdress que mostra seu endereço e displayPhone que mostra seu telefone.
Neste caso, ambas as classes estão localizadas no mesmo pacote, o pacote padrão, portanto, na classe Program, podemos usar todos os métodos e variáveis da classe Pessoa, que possuem um modificador padrão, público e protegido.
Contudo, campos e métodos com o modificador privado na classe do Programa não estarão disponíveis. Se a classe do Programa estivesse localizada em um pacote diferente, apenas campos e métodos com o modificador público estariam disponíveis para ele. Uma observação importante é que o modificador de acesso deve preceder o resto da definição variável ou método.
Por que não declarar todas as variáveis e métodos com um modificador para que estejam disponíveis em qualquer lugar do programa, independentemente do pacote ou classe? Veja, por exemplo, o campo da idade, que representa a idade. Se outra classe tiver acesso direto a este campo, então há a possibilidade de que um valor incorreto, por exemplo, um número negativo, seja passado para ele durante a operação do programa.
Porém, tal mudança de dados não é desejável. No entanto, ou queremos que alguns dados sejam alcançados diretamente para poderem ser exibidos no console ou apenas descobrimos seu valor. Portanto, recomenda-se que restrinja o acesso aos dados o máximo possível para protegê-los do acesso externo indesejado (tanto para obter o valor quanto para modificá-los). O uso de vários modificadores garante que os dados não são distorcidos ou alterados inadequadamente. Essa ocultação de dados dentro de uma hierarquia é chamada de encapsulamento.
Então, como regra, em vez de aplicar diretamente campos, os acessórios são usados. Observe o exemplo:
Sendo assim, em vez de trabalhar diretamente com os campos de name e age na classe Pessoa, trabalharemos com métodos que definem e devolvem os valores desses campos. O setName, setAge e métodos similares também são chamados de mutadores porque alteram os valores de um campo. E o getName, getAge e métodos similares são chamados de acessórios, porque com a ajuda deles obteremos o valor do campo.
Além disso, podemos colocar uma lógica adicional nesses métodos. Por exemplo, neste caso, quando você altera a idade, ele verifica se o novo valor corresponde à faixa válida.
3 CAMPOS ESTÁTICOS
Além dos métodos e campos usuais, uma classe pode ter campos estáticos, métodos, constantes e inicializadores. Por exemplo, a classe principal do programa tem um método principal, que é estático:
Para declarar variáveis estáticas, constantes, métodos e inicializadores, você especifica a palavra-chave static antes de declará-las.
Quando você cria objetos em uma classe, cada objeto cria sua própria cópia dos campos regulares não estáticos. E campos estáticos são comuns a toda a classe. Portanto, eles podem ser usados sem criar objetos de classe.
Observe o exemplo, criaremos uma variável estática:
Observe que a classe Pessoa contém um contador de variável estática incrementado no construtor e seu valor é atribuído ao id variável. Ou seja, quando cada novo objeto Pessoa for criado, essa variável aumentará, de modo que cada novo objeto Pessoa terá um valor de campo de identidade 1 maior do que o anterior.
Como a contra variável é estática, podemos referir-nos no programa pelo nome da classe:
Saída do console do programa:
3.1 CONSTANTES ESTÁTICOS
Também são constantes comuns a toda a classe.
Vale ressaltar que as constantes estáticas já foram utilizadas ativamente em todos os tópicos anteriores. Em particular, na expressão:
Outro fator importante é que “Out” representa apenas a constante estática da classe Sistema. Portanto, ele é acessado sem criar um objeto de classe Sistema.
3.2 INICIADORES ESTÁTICOS
Os iniciadores estáticos são projetados para inicializar variáveis estáticas ou para executar as ações em que são executadas quando o primeiro objeto é criado. Por exemplo, definiremos um inicializador estático:
O inicializador estático é definido como normal, apenas a palavra-chave é colocada antes dele. Neste caso, no inicializador estático, definimos o valor inicial do contador de campo estático e exibimos uma mensagem para o console.static
Dois objetos da classe Pessoa são criados no próprio programa. Portanto, a saída do console será assim:
Tenha em mente que o inicializador estático é chamado após a classe ser carregada e, de fato, antes que o primeiro objeto da classe seja criado.
3.3 MÉTODOS ESTÁTICOS
Métodos estáticos também se aplicam à classe na totalidade. Por exemplo, acima, o contador de variável estática era acessível externamente, e poderíamos alterar seu valor fora da classe Pessoa. Vamos torná-lo indisponível para edição de fora, mas legível. Para isso, use um método estático:
Agora a variável estática não está disponível do lado de fora, é privada. E seu valor é exibido usando o método display estático Counter. Para acessar um método estático, use o nome da classe: .Pessoa.displayCounter()
Ao usar métodos estáticos, devemos levar em conta as limitações: em métodos estáticos, só podemos chamar outros métodos estáticos e usar apenas variáveis estáticas.
Em geral, os métodos são definidos como estáticos, quando os métodos não afetam o estado do objeto, ou seja, seus campos e constantes não estáticos, e não adianta criar uma instância da classe para chamar o método. Por exemplo:
Neste caso, para a soma, subtrair e multiplicar métodos, não importa qual instância da classe a operação é utilizada. Esses métodos funcionam apenas com parâmetros, sem afetar o estado da classe. Portanto, podem ser definidos como estáticos.
4 OBJETOS COMO PARÂMETROS DE MÉTODO
Objetos de classe, como dados de tipos primitivos, podem ser passados para métodos. No entanto, neste caso, há uma peculiaridade — ao passar objetos como um valor, uma cópia da referência à área na memória onde este objeto está localizado é transmitida. Daremos uma olhada em um pequeno exemplo. Suponha que tenhamos a seguinte classe de pessoa:
Aqui, um objeto Pessoa é passado para o método changeName, cujo nome é alterado. Como uma cópia da referência à área de memória onde o objeto Pessoa reside será passada para o método, a variável kate e o parâmetro “p” do método changeName apontarão para o mesmo objeto na memória. Portanto, após a execução do método, o objeto kate que for passado para o método terá seu nome alterado de "Kate" para "Alice".
Outro fator deve ser distinguido deste caso:
Uma cópia da referência ao objeto Pessoa também é passada para o método “changePessoa”. No entanto, no método em si, não alteramos os valores individuais do objeto, mas recriamos o objeto usando o construtor e o novo operador. Como resultado, um novo espaço será alocado na memória para o novo objeto Pessoa, e uma referência a este objeto será atribuída ao parâmetro p:
Ou seja, após criar um objeto Pessoa, o parâmetro p e a variável kate no método principal armazenam referências a diferentes objetos. A variável kate que foi passada para o método continuará a armazenar uma referência ao objeto antigo na memória. Portanto, seu significado não muda.
RESUMO DO TÓPICO 2
Neste tópico, você aprendeu:
Compreendeu o conceito de encapsulação e seu uso dentro do paradigma de orientação a objetos usando a linguagem Java.
Entendeu o que são campos estáticos e suas interferências nas classes em Java.
Conheceu alguns membros e modificadores, bem como seus níveis de acesso usando a linguagem Java.
Utilizou objetos como parâmetros de método de modo a dinamizar o código usando o paradigma de orientação a objetos em Java.
AUTOATIVIDADE
1 Às vezes, você quer ter variáveis que são comuns a todos os objetos. Isso é feito com o modificador. Campos que têm o modificador em sua declaração são chamados campos estáticos ou variáveis de classe. Eles estão associados com a classe, em vez de com qualquer objeto. Cada instância da classe compartilha uma variável de classe, que está em um local fixo na memória. Qualquer objeto pode alterar o valor de uma variável de classe, mas as variáveis de classe também podem ser manipuladas sem criar uma instância da classe. Sobre campos estáticos, assinale a alternativa CORRETA:
a) ( ) Para declarar variáveis estáticas, constantes, métodos e inicializadores, você especifica a palavra-chave static antes de declará-las.
b) ( ) Quando você cria objetos em uma classe, cada objeto não cria sua própria cópia dos campos regulares não estáticos, é necessário declarar.
c) ( ) Campos estáticos não são comuns a todas as classes.
d) ( ) É necessário criar objetos e classes para se usar uma variável ou campo estático.
2 Pode haver momentos em que é útil ter valores que são compartilhados em todas as instâncias de uma determinada classe. Campos estáticos e constantes estáticas permitem esse tipo de compartilhamento por pertencer à classe e não aos objetos reais. Com base nas definições dos campos estáticos, analise as sentenças a seguir:
I- Os iniciadores estáticos são projetados para inicializar variáveis estáticas ou para executar as ações que são executadas quando o primeiro objeto é criado.
II- Tenha em mente que o inicializador estático é chamado antes de a classe ser carregada.
III- O inicializador estático é definido como normal, apenas a palavra-chave é colocada antes dele.
Assinale a alternativa CORRETA:
a) ( ) As sentenças I e II estão corretas.
b) ( ) Somente a sentença II está correta.
c) ( ) As sentenças I e III estão corretas.
d) ( ) Somente a sentença III está correta.
3 Em Java, modificadores de acesso são usados para definir a acessibilidade (visibilidade) de classes, interfaces, variáveis, métodos, construtores, membros de dados e os métodos de setter. De acordo com os princípios de modificadores de acesso em Java, classifique V para as sentenças verdadeiras e F para as falsas:
( ) Public: campos e métodos declarados com este modificador são visíveis para outras classes no pacote atual e de pacotes externos.
( ) Protected: está disponível apenas a partir do código na mesma classe.
( ) Private: tal classe ou membro de classe é acessível de qualquer lugar da classe ou pacote atual, ou em classes derivadas, mesmo que estejam em outros pacotes.
Assinale a alternativa que apresenta a sequência CORRETA:
a) ( ) V – F – F.
b) ( ) V – F – V.
c) ( ) F – V – F.
d) ( ) F – F – V.
4 Em Java, um método estático é um método que pertence a uma classe e não a uma instância de uma classe. O método é acessível a todas as instâncias de uma classe, mas métodos definidos em uma instância só podem ser acessados por esse objeto de uma classe. Disserte sobre algumas limitações dos métodos estáticos bem como o momento em que devem ser definidos.
5 O Objeto parâmetro é simplesmente um objeto invólucro para todos os parâmetros de um método. A vantagem do Objeto parâmetro sobre uma lista de parâmetros de método regular é que os campos de classe podem ter valores padrão. Uma vez criada a classe wrapper para a lista de parâmetros de método, uma classe de construtor correspondente também é criada. Normalmente é uma classe estática interna. Neste contexto, disserte sobre objetos de classe e dados primitivos.
1 INTRODUÇÃO
As classes podem ser aninhadas, ou seja, podem ser definidas dentro de outras classes. Um caso especial de classes aninhadas são as classes internas. Uma classe interna se comporta como uma classe regular, exceto que seus objetos só podem ser criados na classe externa.
Sendo assim, podemos dizer que a classe interna tem acesso a todos os campos da classe externa, incluindo aqueles que são fechados usando o modificador privado. Da mesma forma, uma classe externa tem acesso a todos os membros da classe interna, incluindo campos e métodos com o modificador privado.
Contudo, objetos de classes internas só podem ser criados na classe onde as classes internas estão à frente. Em outras classes externas, você não pode criar objetos na classe interna.
Acadêmico, no Tópico 3, abordaremos conteúdos relacionados ao tema de classes internas e aninhadas tais quais heranças, classes abstratas, hierarquia de herança e conversão de tipos.
2 HERANÇA
Um dos principais aspectos da programação orientada a objetos é a herança. Com a ajuda da herança, você pode expandir a funcionalidade das classes existentes adicionando novas funcionalidades ou alterando a antiga. Por exemplo, há a seguinte classe Pessoa que descreve um indivíduo:
Suponhamos que posteriormente queremos adicionar outra classe que descreve um Funcionário de uma empresa, a classe de Funcionários. Uma vez que esta classe implementa a mesma funcionalidade da classe Pessoa e uma vez que um Funcionário também é uma pessoa, seria racional fazer da classe Employee um derivado (herdeiro, subclasse) da classe Pessoa, que por sua vez é chamada de classe base, pai ou superclasse:
Para declarar uma classe a herdar de outra, você deve usar a palavra-chave estendida (extends) após o nome da classe que herda, seguido pelo nome da classe base. Para a classe Employee, a classe base é Pessoa portanto, a classe Employee herda todos os mesmos campos e métodos na classe Pessoa.
Portanto, se você tiver construtores definidos na classe base, você deve chamar um dos construtores da classe base na classe derivada usando a palavra-chave super. Por exemplo, a classe Pessoa tem um construtor que leva um único parâmetro. Portanto, na classe employee na construtora, você chama o construtor da classe Pessoa. Ou seja, a chamada representará um chamado para o construtor da classe Pessoa.
Assim, quando você chama o construtor, a palavra entre parênteses é seguida por uma enumeração dos argumentos que são passados. No entanto, o construtor da classe base deve ser chamado no início na construção da classe derivada. Portanto, a definição do nome do Funcionário é delegada ao construtor da classe base.
Todavia, mesmo que a classe derivada não produza nenhum outro trabalho no construtor, como no exemplo acima, você ainda precisa chamar o construtor da classe base.
Observe o exemplo seguir, usando classes:
A classe derivada tem acesso a todos os métodos e campos da classe base (mesmo que esteja em um pacote diferente) exceto aqueles definidos com o modificador privado. Neste caso, a classe derivada também pode adicionar seus próprios campos e métodos:
Nesse caso, a classe Employee agrega um campo da empresa que armazena o local de trabalho do Funcionário, bem como o método de trabalho.
2.1 MÉTODOS PREDOMINANTES
Uma classe derivada pode definir seus próprios métodos, ou pode substituir métodos que são herdados da classe base. Por exemplo, vamos substituir o método de exibição na classe Funcionário:
Antes do método substituído, você especifica uma @Override de anotação. Esta anotação não é necessária em princípio.
Quando você substitui um método, ele deve ter um nível de acesso pelo menos o mesmo nível do nível de acesso da classe base. Por exemplo, se um método tem um modificador público na classe base, o método deve ter um modificador público na classe derivada.
No entanto, neste caso, podemos ver que parte do método de exibição no Employee repete as ações do método de exibição da classe base. Portanto, podemos encurtar a classe de Funcionários:
Usando a super palavra-chave, também podemos nos referir à implementação de métodos de classe base.
2.2 USOS INDEVIDOS DE HERANÇA
Embora a herança seja um mecanismo muito interessante e eficaz, em algumas situações seu uso pode ser indesejável. Novamente, você pode impedir a herança usando a palavra-chave final. Por exemplo:
Se a classe Pessoa fosse definida dessa forma, o seguinte código seria errôneo e não funcionaria, uma vez que, portanto, proibimos a herança:
Além de proibir a herança, você também pode impedir a substituição de métodos individuais. Por exemplo acima, o método substituído é impedido de ser substituído:display()
Neste caso, a classe Employee não poderá substituir o método de exibição.
2.3 DESPACHO DE MÉTODO DINÂMICO
A herança e a capacidade de substituir métodos abrem grandes oportunidades para nós. Em primeiro lugar, podemos passar uma variável de superclasse uma referência ao objeto subclasse:
Como o Empregado herda da Pessoa, o objeto do Funcionário também é um objeto pessoa. Sendo assim, qualquer Funcionário da empresa também é uma pessoa.
No entanto, mesmo que a variável representa um objeto Pessoa, a máquina virtual interpreta que ele está realmente apontando para um objeto Funcionário. Portanto, quando os métodos são chamados, este objeto será chamado para a versão do método em que é definido na classe Employee, não em Pessoa. Por exemplo:
Saída do console deste programa:
Quando um método substituído é chamado, a máquina virtual encontra e chama exatamente a versão do método definida na subclasse. Esse processo também é chamado de pesquisa de método dinâmico ou despacho de método dinâmico.
3 CLASSES ABSTRATAS
Além das classes habituais, Java tem classes abstratas. Uma classe abstrata é semelhante a uma classe normal. Você também pode definir campos e métodos em uma classe abstrata, mas não pode criar um objeto ou instância de uma classe abstrata.
As classes abstratas são projetadas para fornecer funcionalidade básica para classes herdadas.
E as classes derivadas já implementam essa funcionalidade.
Ao definir classes abstratas, a palavra-chave abstract é usada:
Mas a principal diferença é que não podemos usar o construtor de uma classe abstrata para criar seu objeto. Por exemplo, o seguinte:
Além dos métodos convencionais, uma classe abstrata pode conter métodos abstratos, sendo que estes métodos são definidos usando a palavra-chave abstract e não têm implementação.
Afinal, por que precisamos de classes abstratas? Digamos que façamos um programa bancário e definamos três classes nele: Pessoa, que descreve uma pessoa, Funcionário, que descreve um Funcionário do banco, e Cliente, que representa um cliente do banco. Obviamente, as classes Funcionário e Cliente derivam da classe Pessoa, pois ambas as classes compartilham alguns campos e métodos comuns.
E como todos os objetos representarão um Funcionário ou um cliente do banco, não criaremos objetos diretamente da classe Pessoa. Então faz sentido torná-lo abstrato, não é mesmo?
Conforme observado acima, o código é o método principal, onde se cria dois objetos, um do tipo Employee e o Client. Uma observação importante nas classes logo abaixo é que tanto Employee e Client são extensões da classe Pesoa logo acima. Deste modo, Employee e Client herdam características de Pessoa.
Outro exemplo é o sistema de formas geométricas. Na realidade, não há figura geométrica como tal. Há um círculo, um retângulo, um quadrado, mas simplesmente não há figura. No entanto, tanto o círculo quanto o retângulo tem algo em comum e são figuras:
Conforme observado acima, o código acima possui uma classe abstrata chamada Figure. Esta possui duas variáveis “x” e “y” que são as coordenadas geográficas. Este código possui “getPerimeter”, ou seja, método abstrato para obter o perímetro, e “getArea”, método para obter a área. Já o “Rectangle” consiste no construtor com uma chamada para o construtor da classe Figure.
4 HIERARQUIA DE HERANÇA E CONVERSÃO DE TIPOS
Já vimos sobre transformar objetos de tipos simples. No entanto, com objetos de classe, as coisas são um pouco diferentes. Suponha que tenhamos a seguinte hierarquia de classes:
Conforme observado acima, o código acima possui um método principal onde se cria três objetos do tipo “Pessoa”, “tom”, “sam” e “bob”. Logo abaixo, temos a declaração dessa classe seguida das classes “Employee” ou seja, Funcionários da empresa que herda características da classe “Pessoa”. Por conseguinte, a classe “Client”, ou seja, cliente, que também herda características da classe “Pessoa”.
Nesta hierarquia de classe, você pode rastrear a seguinte cadeia de herança: Objeto (todas as classes herdam implicitamente do tipo Objeto) -> Pessoa -> Empregado| Cliente. Desta forma, as superclasses geralmente são colocadas acima das subclasses, então a classe Object está no topo da herança, e a classe Funcionário e Cliente está na parte inferior.
Um objeto de subclasse também representa um objeto de superclasse. Portanto, no programa podemos escrever da seguinte forma:
Esta é a chamada conversão de baixo para cima (de uma subclasse na parte inferior para uma superclasse no topo da hierarquia) ou upcasting. Esta conversão é automática.
Contudo, o inverso nem sempre é verdade. Por exemplo, o objeto Pessoa nem sempre é um objeto Funcionário ou cliente. Portanto, a conversão de cima para baixo ou downcasting de superclasse para subclasse não é realizada automaticamente. Neste caso, precisamos usar uma operação de conversão de tipo.
Neste caso, a variável sam é lançada para Empregado. E então, através do objeto “emp”, podemos acessar a funcionalidade do objeto Funcionário. Também podemos converter um objeto Employee em toda a linha reta de herança de Objeto para Funcionário.
Vejamos exemplos de execuções descendentes:
Mas considere outra situação:
Neste caso, uma variável de tipo Objeto armazena uma referência ao objeto Cliente. Podemos fazer com que este objeto seja dos tipos pessoa ou cliente sem erro. No entanto, se tentarmos converter para o tipo Funcionário, teremos um erro na hora da execução. Porque Kate não representa um objeto do tipo Empregado.
4.1 INSTÂNCIAS DO OPERADOR
No exemplo acima, podemos ver claramente que a variável kate é uma referência ao objeto Cliente, não ao objeto Funcionário. No entanto, muitas vezes os dados vêm de fora, e podemos não saber exatamente que tipo de objeto esses dados representam. Assim, há uma alta probabilidade de encontrar um erro. E antes de realizarmos a conversão de tipo, podemos verificar se podemos executar o casting usando a instância do operador:
A expressão verifica se a variável kate é um objeto do tipo Employee. Mas como não é explícito neste caso, tal cheque devolverá o valor de “kate instance of Employee false”, e a transformação não funcionará.
Desta forma, a expressão retornaria:
Deve-se notar que, a partir do Java 16, podemos simplificar a conversão do tipo da seguinte forma:
Expressão:
Verifica se a variável representa classe, e se representa (isto é, o operador retorna ), então cria uma variável de tipo . E no futuro, podemos usar essa variável clientKate e realizar várias operações nele. kateClientinstanceoftrueclientKateClient
LEITURA COMPLEMENTAR
INTRODUÇÃO A ORIENTAÇÃO A OBJETOS
Francisco José Gomes
João Tito Almeida Vianna
1 Programação Estruturada x Orientação a objetos
1.1 Programação Estruturada
Paradigma de programação que busca a obtenção de uma estrutura lógica clara; boa tanto para compreensão do código, como para manutenção do mesmo. Normalmente essa estrutura é interpretada linha por linha, havendo três tipos de estruturas básicas para navegar pelo código: sequência, seleção e repetição; como ilustrado na Figura 1. Os matemáticos Bohm, C. e Jacopini, G. provaram que qualquer programa pode ser escrito utilizando-se essas três estruturas básicas.
Figura 1 - PROGRAMAÇÃO ESTRUTURADA [1]
Além disso, este tipo de programação usa como unidade básica a "função". Define-se como função uma sequência de comandos que é executada ao longo do programa várias vezes. Tal sequência é definida em um módulo separado e chamada de dentro da estrutura principal do programa, ou até de outros programas. Além de tornar o programa mais organizado, a utilização de funções otimiza a utilização de memória pelo código.
A programação não-estruturada, com uso do comando "goto", foi caindo em desuso com o advento da estruturada e muito impulsionada pelo artigo publicado por Dijkstra [3]. A estrutura do programa fica comprometida em sua compreensão e manutenção. Basicamente falando, ao "debugar-se" um código, a indicação de erro na linha X não acarreta necessariamente que as linhas acima estão corretas e que o erro encontra-se desta linha em diante. Com a estrutura de "Goto" a busca do erro torna-se desnecessariamente complexa.
1.2 Orientação a objetos
Paradigma de programação que introduz a noção de "classe" e "objeto". Classes são estruturas de dados que contêm tanto campos de dados (variáveis próprias) como seus próprios métodos (funções). Um objeto é uma instância de uma classe, declarada dentro do programa (como uma variável do tipo "int" é declarada, um objeto de qualquer classe criada pelo programador também o deve ser). O surgimento desta estrutura está associado à facilitação da escrita de programas de computador, tornando o processo mais intuitivo.
Um programa orientado a objetos deve ser visto como um conjunto de objetos capazes de interagir entre si. Cada objeto consegue receber, processar e enviar dados, sendo uma "máquina independente".
Essa forma de programação induz o programador a manter o acesso aos dados somente quando a ação é associada a tal objeto. No caso da programação estruturada, enquanto o programa cresce de tamanho, a tendência é o surgimento de variáveis globais, as quais podem ser acessadas e modificadas de qualquer parte do código, tendendo a disseminar bugs.
Uma classe pode ser vista como um conjunto de funções (operações) que encapsulam um conjunto de variáveis (atributos), visando garantir o uso correto das mesmas; como ilustrado na Figura 2.
1.3 Visão geral
Figura 2 - REPRESENTAÇÃO DE OBJETO [1]
Para finalização do tópico introdutório, apresenta-se a
Tabela 1, da qual pode-se tirar uma visão básica da diferença entre os dois paradigmas de programação apresentados.
Enquanto na programação estruturada temos como unidade básica uma função, a qual pode ser chamada diversas vezes dentro do código e o enfoque é dado às ações executadas por cada comando; temos na programação estruturada a função básica sendo a classe, ou seja, a definição de um tipo de objeto, e o enfoque da programação gira em torno da ideia de objeto apresentada anteriormente.
Tabela 1: COMPARAÇÃO ENTRE PROGRAMAÇÃO ESTRUTURADA E ORIENTADA A OBJETOS
2 Orientação a objetos
2.1 Classe
Para desenvolvimento de um raciocínio é interessante pensar nas structs que podem ser criadas em programações estruturadas. A struct nada mais é do que a definição de um novo tipo de variável, dentro da qual se encontram algumas outras variáveis. Abaixo encontra-se um exemplo de estrutura criada na linguagem C.
typedef struct aluno
{
char nome[50];
int numeroDeMatricula; int dataDeNascimento[3]; char curso[30];
} aluno;
A definição de classe pode ser vista como uma struct com um nível a mais de complexidade. A classe é uma struct que, além de definir suas próprias variáveis, define as funções que lidarão com as mesmas. Abaixo um exemplo de classe criada na linguagem Java.
public class Aluno
{
private String nome;
private int numeroDeMatricula;
private int[] dataDeNascimento = new int[3]; private String curso;
public Aluno(String N, int Mat, int[] Nasc, String cur)
{
nome = N; numeroDeMatricula = Mat; dataDeNascimento = Nasc; curso = cur;
}
public void setNumeroMatricula(int novo)
{
numeroDeMatricula = novo
}
public void setCurso(String cur)
{
curso = cur;
}
public String getNome()
{
return nome;
}
}
Normalmente as variáveis de uma classe são denominadas atributos e suas funções, métodos. Além dos atributos e métodos, toda classe possui um construtor, chamado na criação de um objeto e garante a inicialização correta do mesmo. O construtor possui obrigatoriamente o mesmo nome da classe. A ordem de definição dos componentes de uma classe é livre.
É possível criar mais de um construtor para a classe, ou método com o mesmo nome. Para tal deve os parâmetros passados para o referido método devem ser diferentes.
Observando o código acima com cuidado, percebe-se a presença de outra declaração antes do tipo de variável ou função. Em orientação a objetos, os atributos e métodos de uma determinada classe podem receber três especificadores de acesso a membro:
• public: acessível de qualquer parte do programa.
• private: acessível somente através das funções da própria classe.
• protected: acessível à classe e também a suas subclasses (tópico, que será discutido mais a frente).
2.1.1 Encapsulamento
Encapsular é proteger os atributos de uma classe, tornando-os acessíveis somente através de seus métodos. Esta é uma prática bastante difundida entre os programas orientados a objeto, pois a responsabilidade de modificar os atributos da classe é dela mesma, não de quem deseja realizar a ação executada pelo método. A Figura 2 ilustra o encapsulamento.
Conhecendo os especificadores de acesso a membro, já podemos dizer que para realização do encapsulamento em uma classe, os atributos definidos devem ser do tipo private e os métodos do tipo public.
Um padrão muito difundido é a criação de funções "getVariavel" e "setVariavel", as quais retornam o valor contido na variável e mudam o valor da mesma, respectivamente. Esta fica sendo então a única maneira de acessar os atributos de uma classe.
2.2 Herança
A herança permite definir uma classe como a extensão de outra. Esta propriedade permite o aproveitamento de código, evitando duplicação; além de facilitar a manutenção do mesmo.
Um exemplo pode ser dado a partir da análise de contas de banco. Todas as contas de um banco possuem um saldo, podem receber depósitos, realizar saques. Ainda assim existem diferentes tipos de contas, como conta-corrente e poupança. Na poupança, por exemplo, deve ser incluído um rendimento mensal sobre o saldo presente nela.
Este é um caso claro onde a herança pode e deve ser utilizada. A criação de uma série de métodos comuns às contas na classe "Conta" é sucedida pela criação de diversas classes que herdam toda a sua estrutura (atributos e métodos). Além disso, os métodos criados na subclasse (Conta Corrente, Poupança, ... ) podem sobrescrever os da superclasse (Conta), devendo para isso ter o mesmo nome.
2.3 Polimorfismo
Denomina-se polimorfismo o fato de uma mesma chamada de método poder invocar métodos diferentes. Este conceito acaba sendo uma consequência natural do uso da herança. Como explicado no item anterior, ao sobrescrever-se um determinado método de uma superclasse, consequentemente abre-se a possibilidade do polimorfismo.
3 Bibliografia
[1] Reis, G. R., Material do minicurso: "C++ e Programação Orientada a Objetos", ministrado na XXXIII Semana da Engenharia, 2010.
[2] Bohm, Corrado; and Giuseppe Jacopini (May 1966). "Flow Diagrams, Turing Machines and Languages with Only Two Formation Rules". Communications of the ACM 9 (5): 366–371.
[3] Dijkstra, E. "Go-to statement considered harmful", em Commun. ACM 11 (1968), 3: 147–148. (http://www.cs.utexas.edu/~EWD/ewd02xx/EWD215.PDF
Fonte: GOMES, F. J.; VIANNA, J. T. A. Introdução a orientação a objetos. Disponível em: https://www.ufjf.br/peteletrica/files/2012/10/Curso-Orienta%C3%A7%C3%A3o-a-objetos.pdf. Acesso em: 23 ago. 2022.
RESUMO DO TÓPICO 3
Neste tópico, você aprendeu:
Conheceu as definições de classes internas e aninhadas no contexto da programação orientada a objetos em Java.
Entendeu o significado de herança, bem como a sua relação com a criação de novas classes e o aproveitamento de código.
Aprendeu quando se deve usar e quando se deve usar a herança em contextos utilizando a linguagem Java.
Compreendeu o conceito de hierarquia de heranças bem como a conversão de dados usando programação orientada a objetos e Java.
AUTOATIVIDADE
1 Em Java, a classe interna refere-se à classe que é declarada dentro da classe ou interface que foram introduzidas principalmente, para resumir, as mesmas classes logicamente relacionáveis como Java é puramente orientada para objetos, por isso aproximá-lo do mundo real. Sobre o conceito de classes internas e aninhadas, assinale a alternativa CORRETA:
a) ( ) Uma classe interna se comporta como uma classe regular, exceto que seus objetos só podem ser criados dentro da classe externa.
b) ( ) A classe interna não tem acesso a todos os campos da classe externa.
c) ( ) Objetos de classes internas podem ser criados em qualquer classe e em qualquer trecho do código.
d) ( ) É possível criar objetos na classe interna.
2 Herança em Java é um mecanismo no qual um objeto adquire todas as propriedades e comportamentos de um objeto pai. É uma parte importante da programação orientada a objetos. A ideia por trás da herança em Java é que você pode criar novas classes que são construídas sobre as classes existentes. Com base nas definições de orientação a objetos, analise as sentenças a seguir:
I- Com a ajuda da herança, você pode expandir a funcionalidade das classes existentes adicionando novas funcionalidades ou alterando a antiga.
II- A classe derivada tem acesso apenas a alguns métodos e campos da classe base.
III- Para declarar uma classe a herdar de outra, você deve usar a palavra-chave estendida após o nome da classe herdante, seguido pelo nome da classe base.
Assinale a alternativa CORRETA:
a) ( ) As sentenças I e II estão corretas.
b) ( ) Somente a sentença II está correta.
c) ( ) As sentenças I e III estão corretas.
d) ( ) Somente a sentença III está correta.
3 Uma classe java é declarada abstrata usando a palavra-chave 'abstrata' e pode conter métodos abstratos e não abstratos. Não pode ser instaurado, ou seus objetos não podem ser criados. Uma classe herdada da classe abstrata tem que fornecer a implementação para os métodos abstratos declarados na classe abstrata. Uma classe abstrata pode conter construtores, métodos estáticos e métodos finais também. De acordo com os princípios das classes abstratas, classifique V para as sentenças verdadeiras e F para as falsas:
( ) As classes abstratas são projetadas para fornecer funcionalidade básica para classes herdadas.
( ) Podemos usar o construtor de uma classe abstrata para criar seu objeto.
( ) A classe derivada deve substituir e implementar todos os métodos abstratos que existem na classe abstrata subjacente.
Assinale a alternativa que apresenta a sequência CORRETA:
a) ( ) V – F – F.
b) ( ) V – F – V.
c) ( ) F – V – F.
d) ( ) F – F – V.
4 Na programação orientada a objetos, podemos usar a herança quando sabemos que há uma relação "é um" entre uma criança e sua classe de pais.
Observe o código abaixo:
Com base na afirmação e no trecho de código acima, disserte sobre o uso de herança em Java bem como o uso de construtores.
5 As classes abstratas são semelhantes às interfaces. Você não pode instanciar-los, e eles podem conter uma mistura de métodos declarados com ou sem uma implementação. No entanto, com aulas abstratas, você pode declarar campos que não são estáticos e finais, e definir métodos de concreto público, protegido e privado. Disserte sobre a importância de usar classes abstratas em nossos códigos.