terça-feira, 8 de setembro de 2009

Herança,Encapsulamento,Modificadores de acesso,Construtores

Herança:

Em orientação a Objetos surge o conceito de Herança, com intenções como diminuir duplicação de código Colocando membros(Variaveis e métodos) em comum em uma classe onde outras podem herdar dela e criar um relacionamento entre Classes.Temos o mesmo conceito de Taxonomia da Biologia.

A classe que contem membros em comum é chamado Parent Class ou Super Class. As Classes que herdam ou extends da classe que contem membros em comum são chamadas Child Class ou Sub Class.

Em java temos o conceito de Herança Simples oque significa que uma Classe so pode ter uma Parent Class/SuperClasse.
Para saber se uma Classe é realmente Child Class, faça o teste do "is a", se a Classe é uma Parent Class também então, ela esta dentro do conceito,


Vejamos o exemplo:



Clique na imagem para ampliar

Na figura acima,
Podemos Observar que:

1 - Chefe "is a (é um)" Encarregado
2 -
Chefe "is a (é um)" Funcionário
3 - Chefe tem tanto: nome,salario quanto bonusSalarial quanto carroEmpresa
4 - Chefe é uma Especialização de Encarregado e de Funcionário
5 - Chefe é apenas uma Child Class ou Sub Class de Encarregado e de Funcionário
6 - Encarregado
"is a (é um)" Funcionário
7 - Encarregado
tem tanto: nome,salario quanto bonusSalarial
8 - Encarregado é Child Class de Funcionário e Parent Class de Chefe
9 -
Encarregado é uma Especialização de Funcionário e Generalização de Chefe
10 -
Funcionário é Parent Class ou Super Class de Encarregado e de Chefe, nessa respectiva ordem
11 -
Funcionário tem nome e salário
12 -
Funcionário é uma Generalização de Encarregado
13 -
Funcionário é uma Generalização de Chefe
Ou seja,
*Chefe tem tudo que um Encarregado tem e tudo que um funcionário tem,
mais membros adicionais ao cargo
*Encarregado tem tudo que um funcionário tem, mais membros adicionais ao cargo
*Funcionário tem tudo que o cargo atribui a ele.

Esse conceito de criar um classe com base em um ja existente é chamada de SUBDIVISÃO DE CLASSE.



Como declarar uma SuperClasse?


Você Declara uma SuperClasse igual declara uma classe em java:

[modificador_de_acesso] class identificador{

bloco_de_codigo

}


Como Declarar um SubClass?

Use a keyword extends.


[modificador_de_acesso] class identificador extends identificador_parent_class


*modificador_de_acesso -
É uma keyword opcional, podemos ter public,abstract ou final, se nenhum dos três for especificado então consideramos o modificador de acesso default.
*
class - Indica que o escopo é uma declaração de Classe
*identificador -
O nome que você atribui a Classe
*extends -
Diz ao compilador que ela é uma Child Class
*
identificador_parent_class - É o identificador da Parent Class

Modificadores de acesso:


Source: http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html


Os membros(Método e Atributos) de uma classe podem ter quatro níveis de acesso.Classes só podem ter dois niveis de acesso ou public ou default(sem nenhum).Os modificadores de acesso indicam como será o acesso aquele membro ou aquela Classe, COMO vai se relacionar internamente ou externamente.

Modificador

Mesma Classe

Mesmo Pacote

SubClasse

Universo

public

Sim

Sim

Sim

Sim

protected

Sim

Sim

Sim


default

Sim

Sim



private

Sim




*Um modificador de acesso é considerado default, quando nenhum modificador é especificado.


Construtores:


Constutores são usados toda vez que um objeto é Instanciado.Construtores não são Membros de um classe.


Como declarar um construtor?


[modificador_de_acesso] class identificador {

[modificador_de_acesso] identificador([argumentos]){

bloco_de_codigo

}

}


*modificador_de_acesso -
É uma keyword opcional, que indica como o construtor será acessado externamente a classe.
*
identificador - É o nome do construtor, deve ser o mesmo nome da CLASSE
*argumentos - São variáveis locais ao bloco_de_codigo do construtor, Perceba que os argumentos são opcionais porem os [ ] - Parenteses NÃO.
*bloco_de_codigo - Conjunto de instruções que serão interpretadas quando o construtor for invocado

Vejamos exemplo:



public class MinhaClasse{

private int idade;


public
MinhaClasse(int minhaIdade){

idade = minhaIdade;

}


public static void main(String [ ] array){
MinhaClasse objeto = new MinhaClasse( 21);



}
}

*Relembrando alguns conceitos, Por causa de main, temos o "poder" de ter um PROCESSO VINHA LINHA DE COMANDO.





Clique na imagem para ampliar




Construtor Padrão:
Toda vez que o construtor não for explicitamente escrito ele é implicitamente colocado pelo compilador.Se você explicitamente declarar um construtor, você perde o construtor que o compilador ia colocar. Vejamos o exemplo:

Em sintaxe java:
public class Funcionario{


}


Em sintaxe bytecode:

public Funcionario();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return

}

Perceba que no exemplo acima, O construtor da classe NÃO foi explicitamente escrito porem, FOI implicitamente colocado pelo COMPILADOR.

Vejamos agora com o construtor explicitamente escrito:

Em Sintaxe java:

public class Funcionario{
public Funcionario( ){


}
}

Em Sintaxe bytecode:

public Funcionario();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return


}

Neste exemplo o construtor explicitamente dito é igual ao colocado pelo compilador, foi somente para exemplificar porem, o construtor implicito do compilador é substituido pelo explicito declarado.


Herança Simples Padrão:


Toda classe em java que não é especificado a Parent Class, Herda da Classe Object(java.lang.Object).A partir do momento que você especifica A parent Class de uma classe sua classe deixa de ser DIRITAMENTE uma child Class de object.

Vamos provar oque estou dizendo?

Em Sintaxe java:

public class Test{ //Declaração de Classe


}

Em Sintaxe bytecode:

Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return

}


Isso significa:

Vejamos um exemplo, Classe: Gerente extends Funcionario

public class Funcionario{

}

public class Gerente extends Funcionario{

}



Isso é chamado de UML



Como podemos Observar,
explicitamente Gerente é um funcionário logo, A parent Class de gerente é funcionário, Vejamos a class Gerente em bytecode:

Compiled from "Gerente.java"
public class Gerente extends Funcionario{
public Gerente();
Code:
0: aload_0
1: invokespecial #1; //Method Funcionario."":()V
4: return

}

Isso foi explicitamente feito, mais e a classe Funcionario...Vejamos bytecode de Funcionario:

Compiled from "Funcionario.java"
public class Funcionario extends java.lang.Object{
public Funcionario();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return

}

Isso quer dizer o seguinte, Gerente é um funcionário e também é um Objeto, vejamos o Porque:



Clique na imagem para ampliar
Oque podemos Tirar de conclusão sobre Gerente?
- Gerente é um funcionário
- Gerente é um Object(Pois Funcionário é um Object e Gerente é um funcionário)




Oque acontece se eu Instanciar um Objeto Gerente?

public class Gerente extends Funcionario{

public static void main(String array[ ]){
Gerente objeto = new Gerente( );// Instanciando um objeto, ou seja chamando
//o construtor da classe Gerente


}
}

Acabamos de Obter isso:


Clique na imagem para ampliar, Lembra-se do Gerente é um Funcionário e é um Object, Então agora faz sentido ne?



Oque acontece se eu Instanciar um Objeto Funcionario?
public class Funcionario{

public static void main(String array[ ]){
Funcionario objeto = new Funcionario( );// Instanciando um objeto, ou seja chamando
//o construtor da classe Funcionario


}
}





Clique na imagem para ampliar, Lembra-se que toda classe extends java.lang.Object quando não extends nenhuma outra explicitamente!!! Ou seja todo objeto Instanciado é também um objeto da Parent Class



Membros de classe:

Atributos e métodos são membros da classe, o construtor não é considerado um membro
- Membros com modificador de acesso public são considerados interface de uma classe, pois fazem a conexão com o mundo externo
- Membros com modificador de acesso private são considerados encapsulados


Encapsulamento:


Em orientação a objetos têm-se o conceito de encapsulamento que é esconder dados da sua classe e apenas deixá-los disponivel através de métodos. O conceito de encapsulamento é feito em java utilizando modificadores de acesso nos membros e construtor da classe.
Toda vez que um membro tem modificador de acesso public, ele é considerado uma interface, pois ele interage com o meio externo ao objeto, toda vez que um membro tem modificador de acesso private ele é considerado encapsulado pois não existe interação externa.


Exemplos:
Em um objeto com membros considerados interfaces(ou seja interagem com o meio externo) o acesso a eles é feito sem nenhum problema com a notação de ponto.

public class Pessoa{
public int idade; // veja que pelo modificador de acesso sabemos que é uma interface

}

public class ClasseTest{


public static void main(String array[ ]){
Pessoa jose = new Pessoa( ); jose.idade = 21; // Notação de ponto na Variavel de instancia Normalmente

}

}

Em sintax bytecode temos no método main:
public static void main(java.lang.String[]);
Code:
0: new #2; //class Pessoa
3: dup
4: invokespecial #3; //Method Pessoa."":()V
7: astore_1
8: aload_1
9: bipush 21
11: putfield #4; //Field Pessoa.idade:I
14: return

}
De uma forma resumida, na instrução 11 do bytecode teremos isso:
A instrução putfield nesse caso, requer o endereço do objeto e o inteiro que será colocado na instance variable do objeto




Clique na imagem para ampliar,e ao fim da instrução 11 teremos:

Clique na imagem para ampliar



Agora usando encapsulamento:

public class Pessoa{
private int idade; // membro encapsulado ou seja, não pode haver acesso externo a classe Pessoa

}

public class ClasseTest{


public static void main(String array[ ]){
Pessoa jose = new Pessoa( ); jose.idade = 21; // Notação de ponto na Variavel de instancia , Erro de compilação

}

}


Existe um Campo de força na variavel atributo, para ter acesso a ela somente via a mesma classe, Isso é chamado de Encapsulamento.



Clique na imagem para ampliar, Erro de compilação




Métodos get e set:


Métodos
get e set nada mais são doque boas práticas quando se usa encapsulamento, que é usar métodos que deem acesso aos membros encapsulados de uma classe, alem disso podemos ter um lógica antes de configurar o valor de algum membro, existe uma certa verificação de valores.

Métodos get tem retorno e não tem argumentos
Métodos set tem argumentos e não tem retorno


Exemplo:

public class Pessoa{
private int idade; // membro encapsulado ou seja, não pode haver acesso externo a classe Pessoa


public void setIdade(int x){
idade = x;

}

public int getIdade(){
return idade;

}

}

public class ClasseTest{


public static void main(String array[ ]){
Pessoa jose = new Pessoa( ); jose.setIdade(21);

}

}


Lembra-se que o acesso a membros private so pode ser feito na mesma classe? Pois bem os métodos
getIdade e setIdade estão na mesma classe e tem modificador de acesso public, oque permite o acesso externo a classe e interno ao membros encapsulados.



Clique na imagem para ampliar


Basicamente o acesso é feito ao método do objeto, e depois o atributo. Vejamos resumidamente:









É hora da revisão:
-
Child Class é a Mesma coisa que SubClass
- Parent Class é a Mesma coisa que SuperClass
- Java so tem o conceito de Herança simples, ou seja uma Sub Class so pode ter uma Super Classe
- Os modificadores de acesso indicam como será o acesso aquele membro externamente ou internamente.
- Classes só podem ter modificador de acesso public ou default
- Modificador de acesso default é quando nenhum outro é especificado explicitamente
- Membros de classe(métodos e atributos ) e construtores que tem modificador de acesso public são considerados interfaces da classe
-
Membros de classe(métodos e atributos ) e construtores que tem modificador de acesso private são encapsulados

Nenhum comentário:

Postar um comentário