class Dad
{
protected static String me = "dad";
public void printMe()
{
System.out.println(me);
}
}
class Son extends Dad
{
protected static String me = "son";
}
public void doIt()
{
new Son().printMe();
}
A função doIt irá imprimir "pai". Existe uma maneira de fazê-lo imprimir "filho"?
java
inheritance
overriding
Dikla
fonte
fonte
Respostas:
Sim. Mas, no que diz respeito à variável, ela é substituída (Dar novo valor à variável. Dar nova definição à função é Substituir).
Just don't declare the variable but initialize (change) in the constructor or static block.
O valor será refletido ao usar nos blocos da classe pai
se a variável for estática, altere o valor durante a própria inicialização com o bloco estático,
ou então mudança no construtor.
Você também pode alterar o valor posteriormente em qualquer bloco. Será refletido na super classe
fonte
class Son extends Dad { static { me = 'son' } }
Em resumo, não, não há como substituir uma variável de classe.
Você não substitui as variáveis de classe em Java, mas as oculta. Substituir é, por exemplo, métodos. Ocultar é diferente de substituir.
No exemplo que você deu, declarando a variável de classe com o nome 'eu' na classe Filho, você oculta a variável de classe que ela herdaria de sua superclasse Pai, com o mesmo nome 'eu'. Ocultar uma variável dessa maneira não afeta o valor da variável de classe 'eu' na superclasse Pai.
Para a segunda parte da sua pergunta, sobre como fazê-lo imprimir "filho", eu definiria o valor através do construtor. Embora o código abaixo se afaste bastante da sua pergunta original, eu escreveria algo assim;
O JLS fornece muito mais detalhes sobre como ocultar na seção 8.3 - Declarações de campo
fonte
Person
deve substituir neste exemplo?Son
eDad
devem herdar de ePerson
, em seguida, chamarsuper("Son or Dad");
seus construtores.Sim, basta substituir o
printMe()
método:fonte
printMe()
método, ou mesmo tiver esse método, é um método estático?Você pode criar um getter e, em seguida, substituí-lo. É particularmente útil se a variável que você está substituindo for uma subclasse própria. Imagine que sua super turma tem um
Object
membro, mas na sua subclasse isso agora está mais definido para ser umInteger
.fonte
Se você deseja substituí-lo, não vejo um motivo válido para manter isso estático. Eu sugeriria o uso de abstração (veja o código de exemplo). :
Agora podemos adicionar o pai:
o filho:
e papai conheceu uma boa moça:
Parece que temos uma família, vamos dizer ao mundo seus nomes:
}
System.out Saída: Tommy Nancy Dad
System.err é o mesmo que acima (apenas com fonte vermelha)
JOption Output:
Tommy, depois
Nancy e depois
Papai
fonte
Isso parece uma falha de design.
Remova a palavra-chave estática e defina a variável, por exemplo, no construtor. Dessa maneira, Son apenas define a variável para um valor diferente em seu construtor.
fonte
Embora seja verdade que as variáveis de classe só podem estar ocultas nas subclasses e não serem substituídas, ainda é possível fazer o que você deseja sem substituir as
printMe ()
subclasses, e a reflexão é sua amiga. No código abaixo, omito o tratamento de exceções para maior clareza. Observe que declararme
comoprotected
não parece ter muito sentido nesse contexto, pois ficará oculto nas subclasses ...fonte
... imprimirá "filho".
fonte
https://docs.oracle.com/javase/tutorial/java/IandI/hidevariables.html
Chama-se Ocultando Campos
No link acima
fonte
apenas substituindo
printMe()
:a referência a
me
noDad.printMe
método aponta implicitamente para o campo estáticoDad.me
, de uma maneira ou de outra você está mudando o queprintMe
faz emSon
...fonte
Você não pode substituir variáveis em uma classe. Você pode substituir apenas métodos. Você deve manter as variáveis privadas, caso contrário, poderá obter muitos problemas.
fonte
Na verdade, imprime 'pai', pois o campo não é substituído, mas oculto. Existem três abordagens para imprimir 'filho':
Abordagem 1: substituir printMe
Abordagem 2: não oculte o campo e inicialize-o no construtor
Abordagem 3: use o valor estático para inicializar um campo no construtor
fonte
Variáveis não participam da substituição. Somente métodos fazem. Uma chamada de método é resolvida no tempo de execução, ou seja, a decisão de chamar um método é tomada no tempo de execução, mas as variáveis são decididas apenas no tempo de compilação. Portanto, essa variável é chamada cuja referência é usada para chamar e não do objeto de tempo de execução.
Dê uma olhada no seguinte trecho:
Quando você executa o código, o console mostra:
fonte
É claro que usar atributos privados, e getters e setters, seria a coisa recomendada a se fazer, mas eu testei o seguinte e funciona ... Veja o comentário no código
Sooo ... acabei de redefinir as regras de herança ou coloquei o Oracle em uma situação complicada? Para mim, a String estática protegida me é claramente substituída, como você pode ver quando executa este programa. Além disso, não faz sentido para mim porque os atributos não devem ser substituíveis.
fonte
Por que você deseja substituir variáveis quando é possível reatribuí-las facilmente nas subclasses.
Sigo esse padrão para solucionar o design da linguagem. Suponha um caso em que você tenha uma classe de serviço pesada em sua estrutura que precise ser usada em diferentes tipos de aplicações derivadas. Nesse caso, a melhor maneira de configurar a lógica da superclasse é reatribuir suas variáveis 'definidoras'.
fonte
Não. As variáveis de classe (também aplicáveis às variáveis de instância) não exibem o recurso de substituição em Java, pois as variáveis de classe são chamadas com base no tipo de objeto de chamada. Adicionada mais uma classe (Humana) na hierarquia para torná-la mais clara. Então agora nós temos
Filho estende Papai estende Humano
No código abaixo, tentamos iterar sobre uma matriz de objetos Human, Dad e Son, mas ele imprime os valores da Human Class em todos os casos, como o tipo de objeto de chamada como Human.
Vai imprimir
Se queremos acessar a variável de classe do objeto real a partir de uma variável de referência de sua classe pai, precisamos explicitamente informar isso ao compilador lançando a referência pai (objeto humano) para seu tipo.
Vai imprimir
Sobre como parte desta pergunta: - Como já sugerido, substitua o método printMe () na classe Son e, em seguida, chamando
A variável de classe do pai "me" ficará oculta porque a declaração mais próxima (do método printme () da classe Son) do "me" (na classe Son) terá precedência.
fonte
Basta chamar super.variable no construtor de subclasses
A saída é 10.
fonte