Porque contextos estaticos nao sao herdados?

43 respostas
Arthur.hvt

Gostaria de saber o PORQUE dos metodos e variaveis estaticas nao serem herdadas.

Qual a desvantagem q poderia ocorrer se a JMV aceitasse que metodos estaticos fosse herdados?

Obrigado

43 Respostas

vanderlanio
Arthur.hvt:
Gostaria de saber o PORQUE dos metodos e variaveis estaticas nao serem herdadas.

Qual a desvantagem q poderia ocorrer se a JMV aceitasse que metodos estaticos fosse herdados?

Obrigado

Não sei se interpretei mal sua pergunta , mas como assin não são herdados !? O exemplo abaixo e verdadeiro !
public class A {
 public static String t = "oi";

	public static void printT() {
		System.out.print(A.t);
	}
}

public class B extends A {
	public static void main(String[] args) {
		B.printT(); // herda metodo statico de A
		System.out.print(B.t);// herda atributo de A

	}
}
Arthur.hvt

nao, contextos estaticos nao sao herdados.

O que acontece no seu exemplo é que a classe B acessa a variavel e o metodo de diretamente da classe A.

Agora eu só nao sei o porque de nao poder ser herdado, ja que teria sentido em herdar (pelo menos pra mim).

rafaelglauber

Vamos supor que ele fosse “herdado” como você tá falando…qual seria o nível de acesso de um membro estático que não é mais da classe? por que já temos default, public, protected, private…sugestões???

=> Encare o static como mais um recurso que é muito útil por sinal.

Arthur.hvt

nao entendi o que voce quis dizer…

Porque o metodo estatico nao poderia ser herdado para pertencer a subclasse do mesmo jeito que pertence a superclasse?

Porque nao poderia ser modificado diretamente pela subclasse ser ter necessidade de sobreposiçao?

B

Variáveis e métodos estáticos são herdados da mesma forma que variáveis e métodos de instância.

O que pode acontecer é quando a classe ou os métodos são marcados como final na classe Pai, então estesnão podem ser herdados.

rafaelglauber

Bruno Laturner:

O que pode acontecer é quando a classe ou os métodos são marcados como final na classe Pai, então estesnão podem ser herdados.

Uma classe final não pode ser extendida e um metodo final não pode ser sobrescrito!!! Se fosse como você falou para que serviria uma classe não instanciável??? uma classe abstrata não é instanciável, mas isso é outra história!

sergiotaborda

Porque, por definição, não são membros de objetos. Apenas membros de objetos podem ser herdados.

Se isso acontecesse não existiram métodos estáticos, todos seriam membros de objetos.
A desvantagem é muito grande porque os métodos estáticos , por estarem num nivel diferentes dos de objeto, podem fazer coisas que os de objeto não podem. Sem essa capacidade as funcionaldiades da linguagem Java seriam muito menores e a sua utilidade seria quase nula e/ou os programas seriam muito mais complexos para conseguir os mesmos efeitos.

Arthur.hvt

mas, se eu declarar um metodo numa superclasse e herdar em uma subclasse, o metodo da subclasse sera OUTRO metodo, certo? Nao tera nenhuma ligaçao com o metodo da superclasse, diferente dos metodos estaticos.

Se eu declarar 2 metodos estaticos de mesma assinatura em classes diferentes serao metodos diferentes. Por que com a herança nao posso fazer a subclasse “copiar” o metodo estatico da superclasse e faze-la pertencer a subclasse tambem?

peczenyj
class C {
    public void doIt() { System.out.println("classe C"); }    
    public static void doItStatic() { System.out.println("[static] classe C"); }
}

class D extends C{
    public void doIt() { System.out.println("classe D"); }    
    public static void doItStatic() { System.out.println("[static] classe D"); }
}
public class Teste{
        public static void main(String [] args){
                C c = new C();
                D d = new D();
                C dc = new D();

                System.out.println("C c = new C()");
                c.doIt();c.doItStatic();
                System.out.println("D d = new D()");
                d.doIt();d.doItStatic();
                System.out.println("C dc = new D()");
                dc.doIt();dc.doItStatic();
        }
}
Produz:
C c = new C()
classe C
[static] classe C
D d = new D()
classe D
[static] classe D
C dc = new D()
classe D
[static] classe C

O que é muito divertido :)

D

Isso acontece porque o metodo static não tem relacionamento com objeto e sim com classe, ou seja nesses casos sempre é levada em consideração a referencia da qual o metodo está sendo chamado.

Uma prova disso é que a seguinte chamada é valida

C dc = null; dc.doItStatic();

Isso é uma boa pegadinha do tipo SCJP.

sergiotaborda

Arthur.hvt:

Se eu declarar 2 metodos estaticos de mesma assinatura em classes diferentes serao metodos diferentes. Por que com a herança nao posso fazer a subclasse “copiar” o metodo estatico da superclasse e faze-la pertencer a subclasse tambem?

Porque não é a classe que copia coisas é o objeto. E métodos estáticos, por definição, não pertencem ao objeto.

B

rafaelglauber:
Bruno Laturner:

O que pode acontecer é quando a classe ou os métodos são marcados como final na classe Pai, então estesnão podem ser herdados.

Uma classe final não pode ser extendida e um metodo final não pode ser sobrescrito!!! Se fosse como você falou para que serviria uma classe não instanciável??? uma classe abstrata não é instanciável, mas isso é outra história!

Instanciar não é sobreescrever, muito menos é estender.

A keyword final faz exatamente o que eu disse acima, mas ela não tem nada a ver com com instanciar classes.

Arthur.hvt

acho que estou entendendo…

Quer dizer que herança é resolvida em tempo de execuçao?

se eu chamar um metodo estatico por uma referencia, a JMV estara modificando diretamente na classe que o objeto se refere? Ou modifica na classe do tipo da referencia?

Se a resposta for sim, acho que consegui pegar :wink:

rafaelglauber

Bruno Laturner:
rafaelglauber:
Bruno Laturner:

O que pode acontecer é quando a classe ou os métodos são marcados como final na classe Pai, então estesnão podem ser herdados.

Uma classe final não pode ser extendida e um metodo final não pode ser sobrescrito!!! Se fosse como você falou para que serviria uma classe não instanciável??? uma classe abstrata não é instanciável, mas isso é outra história!

Instanciar não é sobreescrever, muito menos é estender.

A keyword final faz exatamente o que eu disse acima, mas ela não tem nada a ver com com instanciar classes.

dá uma lida aqui: http://ivanqueiroz.wordpress.com/2008/03/30/declaraes-e-modificadores-de-classes-java/

EDIT> veja se você não uma leve confusão com static.

Marky.Vasconcelos

DaviPiala:
Isso acontece porque o metodo static não tem relacionamento com objeto e sim com classe, ou seja nesses casos sempre é levada em consideração a referencia da qual o metodo está sendo chamado.

Uma prova disso é que a seguinte chamada é valida

C dc = null; dc.doItStatic();

Isso é uma boa pegadinha do tipo SCJP.

Gostei dessa pegadinha melhor eu me acostumar, já que pretendo tirar a certificação no meio do ano.

B

rafaelglauber:
dá uma lida aqui: http://ivanqueiroz.wordpress.com/2008/03/30/declaraes-e-modificadores-de-classes-java/

Já li e já sei disso. Leia novamente:

Bruno Laturner:

O que pode acontecer é quando a classe ou os métodos são marcados como final na classe Pai, então estes não podem ser herdados.

peczenyj

como final eles são herdados :wink:

rafaelglauber

sobre final:

classe final: A classe não pode ser subclassificada, ou seja, ninguém pode extender ela.
método final: O método não pode ser sobrescrito por uma subclasse.
variável final: A variável não pode receber um valor novo depois de uma atribuição incial.

Qual foi a besteira que eu falei??? Esses conceitos acima foram tirados do livro K&B.

Arthur.hvt

Este foi seu erro rapaz.

metodos finais SÃO herdados, mas nunca sobrescritos.

Andre_Brito

Nossa… eu me confundi com essas do static… Fiquei preocupado agora :expressionless:

B

Ah, da próxima vez eu coloco a frase inteira! herdados e sobreescritos.

rafaelglauber

Mas Bruno, um membro final é herdado sim…faça um teste, crie uma classe e coloque nela um metodo final e verá que um objeto dessa classe tem acesso (se vc não tiver colocado private nele)…o que você não poderá fazer é criar uma subclasse que faça uma sobrescrita nesse método…Em se tratando de classe o final tem a função de não deixar a classe ser extendida, ou seja, ninguém conseguiria criar uma outra classe que extenda dessa classe final, mas eu posso sim criar objetos dessa classe que vão ter acesso a todos os membros possíveis (default, public, protected…) da classe supostamente qualificada como final.

W

e so lembrar tudo que nao for static e private é herdado com extends…

static obviamente tem que ser estatico independente do contexto(Objeto) , entao logo ele nem fica no objeto e sim na classe.
entao se nao ta no objeto ele nao é herdado…

final e so pra impedir de ser sobreescrito, porem nao impede de ser herdado, afinal herança e pra vc reutilizar algo, e algo final pode ser reutilizado por seus filhos.

D

Static não é um assunto complicado, mas o pessoal está tendo alguma dificuldade, executem o exemplo abaixo:

O método static é herdado!

class A
{
	public static void metodo()
	{
		System.out.println("metodo A");
	}
	
}

class B extends A
{
	
}

public class ExemploStatic
{
	public static void main(String []args)
	{
		B b = new B();
		b.metodo();
		
		B.metodo();
		
	}
	
}

Alguns detalhes que apoiam a herança de métodos static é que como os métodos normais, não posso reduzir a visibilidade de um método static em uma subclasse.

Isso porque a visibilidade(encare como disponibilidade) dos métodos é dependente da Classe(referência).

Oq muda em relação a metódos normais é que os métodos static são independetes de um objeto.

Um métod static o não faz nem ideia de que a sua referencia tem um objeto associado(Ele leva em consideração a referencia da qual ele foi chamado), segue um exemplo:

class A
{
	public static void metodo()
	{
		System.out.println("metodo A");
	}
	
}

class B extends A
{
	public static void metodo()
	{
		System.out.println("metodo B");
	}
}

public class ExemploStatic
{
	public static void main(String []args)
	{
		A a = new B();
		a.metodo();
		
	}
	
}

Tanto que até isso aqui funciona:

A a = null;
a.metodo();

Assim espero que todos tenham entendido o static.

Abraço

Arthur.hvt

DaviPiala…

Eu acho ainda que contextos estaticos NÃO são herdados.

Pra mim, o que acontece no seu primeiro exemplo é que como a JMV nao acha o metodo no escopo da classe B, ele sobe a hierarquia para procurar, e quando encontra o metodo()na classe A, o executa.

Quando voce o chama por uma referencia, a JMV entende que se deve procurar o metodo() diretamente pela classe da referencia, ja que é uma referencia b(nome) do tipo B(classe).

No segundo exemplo, o metodo nao é sobrescrito, e sim sobreposto, pois quando se faz sobreposiçao, se torna IMPOSSIVEL acessar o mesmo metodo() de A(superclasse) pela classe B(subclasse), só se voce chamar diretamente por ele.

Ja me deparei com gente que fala que É herdado, e aqueles que dizem que NÃO são herdados(inclusive autores de livros como Java Como Programar)

Arthur.hvt

a prova…

class ExemploStatic{

	public static void main(String []args)	{
		B b = new B();
		b.metodo();
		
		B.metodo();
		
	}
	
}

class A{
	
	static String a = "Classe A";
	
	public static void metodo()	{
		System.out.println(a);
	}	
}

class B extends A{

	static String a = "Classe B";

}

Imprime:

Classe A
Classe A
D

Arthur

Meditei sobre o assunto e cheguei em uma conclusão que realmente não são herdados , pelo seguinte motivo:

-Em uma visão purista um método nunca existe sem um objeto!(Por isso não precisamos ter um objeto, para termos o método). Os métodos static quebram o paradigma OO, isso na minha opinião.

O static é uma opção flexivel que em java nos permite ter esse tipo de coportamento.

Java tem esse comportamente especial com relação com os metodos static, onde uma sub-classe recebe por "shadowing " os métodos static de sua classe base.

Bom exemplo

Eu gostei desse exemplo reforça que a JVM busca pela definição do metodo na hierarquia de classes.

W

essa facilidade da sun so fez complicar a cabeça de muita gente com relação aos statics, metodo static existem mesmo sem um objeto ter sido instanciado e tambem pode
ser usado sem instanciar objetos…

o static fico meio que sem lugar mesmo e foi parar nas classes,afinal pra onde mais ele poderia ir?

D

Eu nunca havia meditado tanto sobre static como nesses ultimos dois dias!

Creio que essa conversa foi muito produtiva!

Obrigado a todos!

netShot

Na documentação do java tem um exemplo bem legal de static:

Arthur.hvt

Só para entender o MOTIVO disso, eu queria saber:

  • herança é resolvida em tempo de compilação? (ou seja, a subclasse herda as funcionalidades da superclasse quando é compilada?)

  • herança é resolvida em tempo de execução?(ou seja, a subclasse herda as funcionalidades da superclasse quando é criada uma instancia da classe, e os construtores sao chamados e tals…)

B

Bem, o que eu posso dizer sobre o static é que ele pertence à classe, e não ao objeto.

Isso significaria que objetos sofrem herança, mas classes não? A herança é resolvida em tempo de compilação, mas é aplicada somente aos objetos, que só existem em tempo de execução?

Arthur.hvt

e é exatamente nisso que eu estava pensando :thumbup:

W

se o objeto é somente uma entidade real da classe, entao a classe tambem tem herança, o comportamento e definido em tempo de compilação,porque ao digitar o código agente já sabe o comportamento esperado para o objeto.

Arthur.hvt

como assim se propagasse para as outras classes? ó.Ó

um metodo estatico pode ser usado em outras classes do mesmo jeito que um metodo comum, a nao ser que seja private

a ainda acho que a herança é resolvida em tempo de execuçao, quando os construtores sao chamados, até a classe Object

W

sim, esquece oque eu falei so faz confundir mais, quando eu falo em herança eu falo do conceito, se ela fosse decicida somente na execução como você poderia programar a chamada dela ? já que quando vc ta programando você ainda nao compilou entende ?
agora o objeto so herda na execução e claro já que ele nao existe antes da execução…

ps: retiro oque falei sobre os statics

Arthur.hvt

Nao cara… o static nao é herdado…

W

hahah pior que nos primeiros posts eu falei que nao era mas o codigo abaixo me fez confundir aqui =\

class Static{
	public static void doSome(){
		System.out.println("static1");
	}
}
public class Static2 extends Static {	
	public static void main(String [] args){
		
		Static2.doSome();		
	}	
}

mas tentei usar a tag @Override e realmente ele nao deixa

Arthur.hvt

entao… O que quero dizer é que metodos estaticos nao sao herdados porque a herança ocorre no objeto, e como contextos estaticos nao fazem parte do objeto…

Correto?

W

bom meu modo de pensar é diferente, pra mim a herança acontence em todo lugar ,ate porque temos classes abstratas , interfaces que fazem uso da herança
e elas nem tem um objeto.

Arthur.hvt

metodos abstratos nao impedem de outras classes herdarem dela, até porque, foi criado exatamente pra isso, pra servirem como subclasses.

e interfaces também, nao impede em nada de se ter subclasses dele.

Arthur.hvt

revendo o topico, percebi que o sergiotaborda respondeu a minha pergunta com todas as letras, e bem do modo que eu imaginava…

Obrigado, acho que isso esclarece muita coisa =)

W

Arthur.hvt:
metodos abstratos nao impedem de outras classes herdarem dela, até porque, foi criado exatamente pra isso, pra servirem como subclasses.

e interfaces também, nao impede em nada de se ter subclasses dele.

mas ai voce ta se contra-dizendo que porque voce disse que a herança só existe nos objetos e não nas classes…

oque voce disse agora é justamente oque eu penso a classe herda comportamento e atributos de outra tambem logo tambem tira proveito da herança, ou seja a reutilizacao
de codigo via extends já e um uso do conceito de herança,bom mas oque importa e que você ja intendeu oque voce queria.

anyway conversar sobre java e sempre legal ainda mais pra mim que vou fazer scjp em breve tenho que ir relembrando essas coisas, discutir conceito aqui no guj e a melhor forma de guardar bem eles na memória.

abraço até +

Criado 28 de maio de 2008
Ultima resposta 31 de mai. de 2008
Respostas 43
Participantes 11