Sombreamento de propriedades e métodos

Como vai,

Vi este termo sendo utilizado em um material da PUC-RIO e o exemplo é:

class Heranca {
    public static void main (String arg[]) {
        Base base = new Base();
        Derivada derivada = new Derivada();
        Base baseDerivada = new Derivada();
        int x = base.i;
        int y = derivada.i;
        int z = baseDerivada.i;
        String xstr = base.teste();
        String ystr = derivada.teste();
        String zstr = baseDerivada.teste();
        System.out.println("Teste de Herança");
        System.out.println("Propriedades => "+x+" - "+y+" - "+z);
        System.out.println("Metodos      => "+xstr+" - "+ystr+" - "+zstr);
}

Temos as classes :

class Base {
    int i = 1;
    String teste() {
        return "Base";
    }
}

class Derivada extends Base {
    int i = 2;
    String teste() {
        return "Derivada";
    }
}

Quando utilizamos o main da classe Heranca o resultado é

Teste de Herança
Propriedades => 1 - 2 - 1
Metodos      => Base - Derivada - Derivada

O que na verdade acontece quando se faz:

Base baseDerivada = new Derivada();

Estou declarando uma variável do tipo Base e inicializado-a com um novo Objeto da classe Derivada. É isso mesmo?

E esse conceito de “Sombreamento de propriedades e métodos”, aguém conhece?

Obrigado,

Aha! achei isso neste link

Overloading, Overriding, and Shadowing

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcn7/html/vbconobjectsinvisualbasic.asp

Overloading, overriding, and shadowing are similar concepts that can be easy to confuse. Although all three techniques allow you to create members with the same name, there are some important differences.

* Overloaded members are used to provide different versions of a property or method that have the same name, but that accept different number of parameters, or parameters with different data types.
* Overridden properties and methods are used to replace an inherited property or method that is not appropriate in a derived class. Overridden members must accept the same data type and number of arguments. Derived classes inherit overridden members.
* Shadowed members are used to locally replace a member that has broader scope. Any type can shadow any other type. For example, you can declare a property that shadows an inherited method with the same name. Shadowed members cannot be inherited

é para vb, mas conceitos são conceitos… (aham, shadowing = sombreamento)

Obrigado por sua resposta.

Na verdade rodei as classes e fiquei sem entender porque foi utilizado

Base baseDerivada = new Derivada();

Declarei um variável do tipo base e a inicializei com um objeto de outra classe.

Como isso pode ajudar?

Será que minhas definições de declaração e inicialização estão erradas?

Abs,

Aha, agora você está com uma dúvida legal.

Base b = new Derivada();

Isso é um dos princípios da POO (Programação Orientada a Objeto).
Isso é igual àquele exemplo que o pessoal usa com bichos, para facilitar vou usar os bichos mesmo para mostrar.

Base = Animal
Derivada = Cachorro

Animal a = new Cachorro();

Você pode fazer a = new Cachorro() porque todo cachorro é um animal. Mas você não pode fazer Cachorro c = new Animal(); porque nem todo animal é um cachorro. No seu caso, você está usando Base b = new Derivada porque toda Derivada é um objeto do tipo Base. Mas nem todo objeto do tipo Base é uma Derivada. E não é obrigatório você usar sempre
Derivada d = new Derivada();
ou
Cachorro c = new Cachorro();

porque muitas vezes você só precisa chamar um método que já existe na classe base, como:

Animal a = new Cachorro();
a.comer(); // isto funciona para qualquer animal
a.respirar(); // isto também

Quando você precisa momentaneamente de algo que só funciona para cachorros, você pode fazer um cast:

((Cachorro)a).latir(); // isto só funciona para cachorros, (e alguns outros bichos também)

Agora vamos pra um outro exemplo…
Classe Heranca:

class Heranca {
	public static void main (String arg[]) {
		Base base = new Base();
		Derivada derivada = new Derivada();
		Base baseDerivada = new Derivada();
		int x = base.i;
		int y = derivada.i;
		int z = baseDerivada.i;
		int xx = base.getI();
		int yy = derivada.getI();
		int zz = baseDerivada.getI();

		String xstr = base.teste();
		String ystr = derivada.teste();
		String zstr = baseDerivada.teste();
		System.out.println("Teste de Herança");
		System.out.println("Propriedades => "+x+" - "+y+" - "+z);
		System.out.println("P. por metod => "+xx+" - "+yy+" - "+zz);

		System.out.println("Metodos => "+xstr+" - "+ystr+" - "+zstr);
	}
}

Classe Base

class Base {
	int i = 1;
	String teste() {
		return "Base";
	}
	int getI(){
		return i;
	}
}

Classe Derivada

class Derivada extends Base {
	int i = 2;
	String teste() {
		return "Derivada";
	}
	int getI(){
		return i;
	}
}

Resultado da execução da Heranca

hehehehehe

Kina, obrigado mas fiquei mais enrrolado.

Na chamada do método eu retorno (int zz = baseDerivada.getI():wink: o número 2, pois esse método está pegando o atributo que esta com o valor 2, quando eu acesso o atributo diretamente ele esta com 1?

Isso acontece porque na verdade estou acessando um atributo da classe Base?

Obrigado,

Olá,

Estude polimorfismo.

O que você está fazendo é utilizando uma subclasse que sobrescreve os atributos da classe mãe.

Obrigado pela dica, mas a classe que está sobrescrevendo é a Derivada e o atributo i nela esta recebendo o valor de 2.

A dúvida é que o valor mostrado é 1, justamente o valor do atributo na superclasse.

Com a sugestão da Kina, com a utilização do método para dar o Get no atributo ele está com o valor correto mas com o acesso direto não.

Abs,

Pois é, isso é especificado pelo polimorfismo em java.

Outra dica é semrpe olhar a especificação da linguagem :wink: