Overriding vs Hiding

no código abaixo:





Code:


class Base {

private void go() {

System.out.println("Base.go()");

}

public static void amethod() {

System.out.println("Base.amethod()");

}

public void doit() {

this.go();

}

}



class Child extends Base {

private void go() {

System.out.println("Child.go()");

}

public static void amethod() {

System.out.println("Child.amethod()");

}

public void doit() {

this.go();

}

}






A saída é:



Code:


Child.go()

Base.amethod()

Child.go()

Child.amethod()






No caso de amethod(), métodos static não são herdados, e por isso ocorre "hiding" ou "shadowing" do método, assim os métodos são chamados de acordo com a referência do objeto e não seu tipo em runtime. No caso de métodos privados, como go() não deveria ocorrer o mesmo? isto é, a primeira linha não deveria mostrar Base.go()???

desculpem, faltou a chamada:



Code:


public class THide1 {

public static void main (String[] args) {

Base b = new Child();

Child d = new Child();

b.doit();

b.amethod();

d.doit();

d.amethod();

}

}


26/01/2003 ás 10:03, marciolx wrote:

no código abaixo:





Code:


class Base {

private void go() {

System.out.println(´´Base.go()´´);

}

public static void amethod() {

System.out.println(´´Base.amethod()´´);

}

public void doit() {

this.go();

}

}



class Child extends Base {

private void go() {

System.out.println(´´Child.go()´´);

}

public static void amethod() {

System.out.println(´´Child.amethod()´´);

}

public void doit() {

this.go();

}

}






A saída é:



Code:


Child.go()

Base.amethod()

Child.go()

Child.amethod()






No caso de amethod(), métodos static não são herdados, e por isso ocorre "hiding" ou "shadowing" do método, assim os métodos são chamados de acordo com a referência do objeto e não seu tipo em runtime. No caso de métodos privados, como go() não deveria ocorrer o mesmo? isto é, a primeira linha não deveria mostrar Base.go()???

Não.

No caso de métodos privados o que acontece é simplesmente eles não serem herdados. Mas o compilador trata-os como qualquer método: ele utiliza o da classe que instanciou o objeto.

Nesse seu caso é ainda mais reforçado isso. Pra começar, você nem está chamando o método diretamente (claro, é private). Aí o seu método doit() da Child está utilizando a referência this, que aponta para este objeto que é um Child, e de qualquer forma o único método go() que essa classe está enchergando é o dela mesmo. Ela nem sabe que existe outro na superclasse… Portanto, executa ele.

Olha agora a parte divertida da coisa: pra fazer um método static ser chamado pela classe da instância e não pela referência, basta chamá-lo através de outro método, tipo o seu doit().

Observe o seguinte código:



Code:


class Base {



private void go() {



System.out.println("Base.go()");



}



public static void amethod() {



System.out.println("Base.amethod()");



}



public void doit() {



this.go();



}



public void dothat() {



this.amethod();



}



}







class Child extends Base {



private void go() {



System.out.println("Child.go()");



}



public static void amethod() {



System.out.println("Child.amethod()");



}



public void doit() {



this.go();



}



public void dothat() {



this.amethod();



}



}



public class THide1 {



public static void main (String[] args) {



Base b = new Child();



Child d = new Child();



b.doit();



b.dothat();



d.doit();



d.dothat();



}



}








Neste caso, o resultado é que todos os métodos chamados são os da classe Child, reforçando o que eu disse no outro exemplo sobre o this (apesar de que ainda acho que o fator predominante no seu exemplo é a visibilidadade do método).

ok! entendido, obrigado!