2 Dúvidas sobre modificadores (Declarations and Modifiers)

Opa,

O livro diz que é ilegal a combinação abstract e strictfp na declaração de um método, pois abstract significa “nenhum conhecimento sobre a implementação do método”, enquanto strictfp diz respeito à implementação.

Porém testei essa combinação em classes (abstract strictfp class), e compilou numa boa.
Qual a lógica nisso? Os métodos abstratos dessa classe (se existirem) obedecerão às normas do strictfp ou não?

A segunda dúvida é sobre o termo “override”. Qual a tradução disso em português? Eu achava que override é uma subclasse redefinir/sobrescrever/redeclarar um método da superclasse, mas me confundi ao ler o texto do livro:

Será que seria o mesmo, porém não se aplicaria polimorfismo nesse caso?

Agradeço quem puder ajudar :slight_smile:

[quote=“Schuenemann”]

A segunda dúvida é sobre o termo “override”. Qual a tradução disso em português? Eu achava que override é uma subclasse redefinir/sobrescrever/redeclarar um método da superclasse, mas me confundi ao ler o texto do livro:

Agradeço quem puder ajudar :)[/quote]

Override ou sobrescrever ou sobrescrita… dá na mesma… isso acontece quando vc sobrescreve um método… exemplo:


class A {
    public void X() {}
}


class B extends A {
    public void X() {}
}

Atn.
Dennys Fredericci

Não, ele diz que você não pode (override), mas pode (redefine).

[code]class A {
static int a() {return 0;}

}

class B extends A {
static int a() {return 1;}

public static void main(String[] args) {
    System.out.println(B.a());

    System.exit(0);
}

}[/code]

Imprime 1.

opa!

quanto ao abstract e strictfp, é o seguinte:

o sctrictfp diz que as variáveis irão seguir a especificação IEEE 754 (é essa? não lembro direito…)… definir uma classe abstrata com strictfp diz que as variáveis da classe (e dos métodos concretos) irão seguir este padrão, assim como declarar uma interface como strictfp (mas neste caso não existem métodos concretos)…

valeu,
té+

[quote=“rbaum”]opa!

quanto ao abstract e strictfp, é o seguinte:

o sctrictfp diz que as variáveis irão seguir a especificação IEEE 754 (é essa? não lembro direito…)… definir uma classe abstrata com strictfp diz que as variáveis da classe (e dos métodos concretos) irão seguir este padrão, assim como declarar uma interface como strictfp (mas neste caso não existem métodos concretos)…

valeu,
té+[/quote]

A IEEE é essa sim, mas creio que o strictfp diz respeito aos métodos apenas, uma vez que não é possível usar esse modificador numa variável.
Tudo bem, isso não é tão importante pra prova.

Agora, quanto à outra pergunta, vejam isso:

[code]class A {
static int a() { return 0; }
}

class B extends A {
static int a() { return 1; }
}

class C {
public static void main(String[] args) {
A a = new A();
B b = new B();

    A c = new B();

    System.out.print(a.a());
    System.out.print(b.a());
    System.out.print(c.a());
}

}[/code]
Imprime 010

Porém, tirando o static:

[code]class A {
int a() { return 0; }
}

class B extends A {
int a() { return 1; }
}

class C {
public static void main(String[] args) {
A a = new A();
B b = new B();

    A c = new B();

    System.out.print(a.a());
    System.out.print(b.a());
    System.out.print(c.a());
}

}[/code]

Imprime 011 8O

Qual a explicação pra isso?

aqui entramos em contradição… o strictfp é um modificador de classe e método, o qual informa que os valores de ponto flutuante contidos em seu escopo devem respeitar o padrão IEEE 754… eu não sei exatamente como isso funciona, mas acho que é isso…

[quote=“Schuenemann”]
Agora, quanto à outra pergunta, vejam isso:

[code]class A {
static int a() { return 0; }
}

class B extends A {
static int a() { return 1; }
}

class C {
public static void main(String[] args) {
A a = new A();
B b = new B();

    A c = new B();

    System.out.print(a.a());
    System.out.print(b.a());
    System.out.print(c.a());
}

}[/code]
Imprime 010

Porém, tirando o static:

[code]class A {
int a() { return 0; }
}

class B extends A {
int a() { return 1; }
}

class C {
public static void main(String[] args) {
A a = new A();
B b = new B();

    A c = new B();

    System.out.print(a.a());
    System.out.print(b.a());
    System.out.print(c.a());
}

}[/code]

Imprime 011 8O

Qual a explicação pra isso?[/quote]

isso aí acontece pelo seguinte:
métodos static não podem ser sobrescritos… métodos static tem suas dependências (não achei uma palavra melhor agora) resolvidas em tempo de compilação, pelo tipo de referência, que neste caso é A, depois B e depois A de novo… então, como vc viu, no primeiro caso, independente do tipo em runtime, o método static que foi invocado foi o de A para a 3ª variável… isso porque é resolvido em tempo de compilação…
já no segundo caso, sem métodos static, as dependencias são resolvidas em runtime… o segundo caso é um exemplo de sobrescrita… por isso que os resultados são diferentes…

valeu,
té+

Então, ao “sobrescrever” um método static não há polimorfismo?
Ou não tem nada a ver? :?:

exatamente! não há polimorfismo para métodos static!
métodos static não são sobrescritos, são “escondidos” (de novo me faltou o termo correto)… assim que eu encontrar o termo correto eu coloco aqui… eu não tenho certeza, mas a expressão usada em inglês é hidden (acho), traduzindo explicitamente seria isso, mas tenho que confirmar…

té+

Schuenemann,

A diferença é que os membros estáticos pertencem a classe e não a instância.

Você pode ter acesso a um membro estático usando o nome da classe ou uma instância dela, porém, neste último caso, como o membro não pertence ao objeto o compilador verificará apenas o tipo do objeto que está chamando o método estático em tempo de compilação. É o que aconteceu no seu primeiro código.

No segundo código ocorre polimorfismo normalmente.

[quote=“Robson”]A diferença é que os membros estáticos pertencem a classe e não a instância.

Você pode ter acesso a um membro estático usando o nome da classe ou uma instância dela, porém, neste último caso, como o membro não pertence ao objeto o compilador verificará apenas o tipo do objeto que está chamando o método estático em tempo de compilação. É o que aconteceu no seu primeiro código.[/quote]

Tudo bem, mas por que (no primeiro caso - membros static), para a variável c, c.a() chama o método correspondente a classe A, e não a B?

A c = new B(); System.out.print( c.a() ); // Equivale a A.a(), e não B.a()

Opa!

Isso acontece exatamente pelo que o Robson (não eu) falou… membros static pertencem a classe… suas dependencias são resolvidas em tempo de compilação e, em tempo de compilação, a variável de nome c é do tipo “A”…
se não fossem static seria diferente… aí a sobrescrita vale e as dependências são resolvidas em runtime, pela instância…

té+

Beleza, só fica meio estranho pra mim em " A c = new B(); " o método se comportar como na classe A (por que não na B, se tem o new B()? )… isso é simplesmente regra da linguagem, sem uma explicação?

Schuenemann escreveu:
[list]
isso é simplesmente regra da linguagem, sem uma explicação?
[/list]

Na verdade esta regra tem uma grande utilidade. É ela que permite o comportamento polimórfico. Vários objetos de subclasses podem ser instanciados e referenciados por referências de sua superclasse. Aí, em tempo de execução cada um vai executar seu próprio método. :wink:

Tudo bem, valeu gente :grin: