1. Datilografia
As variáveis que armazenam tipos de referência (classes) também podem ser convertidas em tipos diferentes. Mas isso só funciona dentro de uma única hierarquia de tipo. Vejamos um exemplo simples. Suponha que tenhamos a seguinte hierarquia de classes, na qual as classes abaixo herdam as classes acima.
Typecasting de tipos de referência, bem como os primitivos, também é categorizado como alargamento e estreitamento.
Vemos que a classe Cat herda a classe Pet, e a classe Pet, por sua vez, herda a classe Animal.
Se escrevermos um código como este:
Animal kitten = new Cat();
Esta é uma conversão de tipo de alargamento . Também é chamado de conversão implícita. Ampliamos a referência de gato para que ela agora se refira a um objeto Gato . Com uma conversão de tipo como essa, não poderemos usar a referência do gatinho para chamar métodos que estão presentes na classe Cat , mas ausentes na classe Animal .
Uma conversão estreita (ou elenco explícito) acontece na direção oposta:
Cat cat = (Cat) kitten;
Indicamos explicitamente que queremos converter a referência armazenada na variável gatinho (cujo tipo é Animal ) para o tipo Gato .
2. Verificando o tipo de um objeto
Mas você precisa ter muito cuidado aqui. Se você fizer isto:
Animal beast = new Cat();
Wolf grayWolf = (Wolf) beast;
O compilador permitirá esse código, mas haverá um erro quando o programa for executado! A JVM lançará uma exceção:
Exception in thread "main" java.lang.ClassCastException: Cat cannot be cast to a Wolf
As referências a um objeto Cat só podem ser armazenadas em variáveis cujo tipo é um ancestral da classe Cat: Pet, Animal ou Object.
Por que é que?
O ponto relevante aqui é que uma referência de objeto é usada para se referir aos métodos e variáveis desse objeto . E não haverá problemas se usarmos uma variável Animal para armazenar uma referência a um objeto Cat: o tipo Cat sempre tem variáveis e métodos do tipo Animal — ele os herdou!
Mas se a JVM nos permitisse armazenar uma referência a um objeto Cat em uma variável Wolf, poderíamos ter uma situação em que poderíamos tentar usar a variável grayWolf para chamar um método que não existe no objeto Cat armazenado nessa variável . É por isso que esse arranjo não é permitido.
Java possui um operador especial instanceof
que permite verificar se um objeto é de um determinado tipo e, portanto, pode ser armazenado em uma variável de determinado tipo. Parece bem simples:
variable instanceof Type
Exemplo:
Animal beast = new Cat();
if (beast instanceof Wolf)
{
Wolf grayWolf = (Wolf) beast;
}
Este código não causará erros — mesmo em tempo de execução.
Aqui estão mais alguns exemplos que ilustram a situação:
Ampliação da conversão do tipo | Descrição |
---|---|
|
Esta é uma conversão de alargamento clássica — nenhum operador de conversão de tipo é necessário. Agora apenas os métodos definidos na Na |
Conversão de tipo de restrição | |
|
Conversão de restrição clássica: você precisa adicionar uma verificação de tipo e um operador de conversão. A Cow cow variável armazena uma referência a um Whale objeto. Verificamos se esse é o caso e, em seguida, realizamos uma conversão de tipo (estreitamento). Ou como também é chamado:
um elenco de tipo
.
|
|
Você pode restringir um tipo de referência sem verificar o tipo do objeto. Se a cow variável se referir a um objeto que não seja um , será gerado Whale um .InvalidClassCastException |
3. Chamando o método original: a super
palavra-chave
Ao substituir o método de uma classe pai, às vezes, em vez de substituí-lo pelo nosso, queremos apenas complementá-lo ligeiramente.
Seria legal se pudéssemos colocar o método da classe pai em nosso método e então executar parte do nosso próprio código. Ou talvez primeiro execute nosso próprio código e, em seguida, chame o método da classe pai.
E Java nos permite fazer exatamente isso. Para chamar um método da classe pai, faça o seguinte:
super.method(arguments);
Exemplos:
class PeaceTime
{
public double getPi()
{
return 3.14;
}
}
class WarTime extends PeaceTime
{
public double getPi()
{
return super.getPi()*2; // 3.14*2
}
}
Em tempo de guerra, o valor de Pi
pode ser maior que 6! Claro, estamos brincando, mas este exemplo demonstra como tudo isso pode funcionar.
Aqui estão mais alguns exemplos para esclarecer um pouco as coisas:
Código | Descrição |
---|---|
|
Cow e Whale aulas |
|
A saída da tela será:
|
Isso é difícil. Honestamente, é uma das coisas mais difíceis em OOP . Dito isto, você precisa conhecê-lo e entendê-lo.
GO TO FULL VERSION