Por que as variáveis ​​de interface são estáticas e finais por padrão?

274

Por que as variáveis ​​de interface são estáticas e finais por padrão em Java?

Jothi
fonte
41
Você não deve colocar nenhuma variável dentro do Interfaces.
cherouvim
34
Porque as interfaces definem contratos que podem ser implementados de várias maneiras. O valor de uma variável é implementação.
cherouvim
10
Certamente, quando sabemos que todas as classes que implementam a interface têm algumas variáveis ​​constantes (nomes de campos, por exemplo).
Aniket Thakur
É uma boa idéia transformar uma variável em uma classe em uma instância da interface que a classe implementa? Eu ja ouvi isso antes.
Doug Hauf
As interfaces em java seguem o princípio ACID, final devido à normalização em C. @cherouvim O tipo de uma variável é a implementação, uma variável deve ser declarada, com ou sem valor, e a definição de uma variável é o valor. Se você alterar o valor de uma variável não é reimplementação, sua redefinição.
217 Grim Grim

Respostas:

264

No FAQ sobre design de interface Java, de Philip Shaw:

As variáveis ​​de interface são estáticas porque as interfaces Java não podem ser instanciadas por si mesmas; o valor da variável deve ser atribuído em um contexto estático no qual nenhuma instância existe. O modificador final garante que o valor atribuído à variável da interface seja uma constante verdadeira que não possa ser reatribuída pelo código do programa.

fonte

cherouvim
fonte
39
Observe que as classes abstratas não podem ser instanciadas "por si mesmas", e essas nem podem ter variáveis ​​de instância.
macias
18
Esta explicação para o staticmodificador é completamente falsa. As variáveis ​​de instância pública de uma classe fazem parte de sua interface e não há razão para que elas não sejam abstraídas em um Java interface, assim como os métodos de instância. Não importa que um Java interfacenão possa ser instanciado diretamente - você ainda pode ter instâncias de classes que implementam o interfacee é sensato exigir que elas tenham uma determinada variável de instância pública. Quanto à parte final, isso não oferece uma explicação - apenas descreve o que finalsignifica.
Pyrocrasty
3
A citação acima é melhor no contexto. O motivo é que "as variáveis ​​de interface devem ser constantes Java". A citação estava apenas explicando por que essa constante seria estática e final. Isso é verdade, mas a verdadeira questão é: por que as variáveis ​​não são permitidas como parte da interface real (ou seja, especificando os nomes e tipos de membros não privados que devem ocorrer em uma classe de implementação). Se eles quisessem "constantes de interface" especiais, poderiam ter usado uma nova sintaxe ou apenas decidido que quaisquer variáveis ​​realmente definidas em uma interface são constantes de interface.
Pyrocrasty
6
As interfaces não podem ter variáveis ​​de instância para evitar a herança múltipla de problemas de estado. Consulte docs.oracle.com/javase/tutorial/java/IandI/… . Uma classe não pode estender mais de uma classe devido ao mesmo motivo.
Denis
1
Como métodos padrão introduzido e eles têm exemplo, ainda variável de instância não é suportado ...
M.kazem Akhgary
41

Como a interface não possui um objeto direto, a única maneira de acessá-los é usando uma classe / interface e, por isso, se a variável existir, a interface deve ser estática, caso contrário, não será acessível ao mundo exterior. Agora, como é estático, ele pode conter apenas um valor e qualquer classe que o implemente pode alterá-lo e, portanto, tudo ficará confuso.

Portanto, se houver uma variável de interface, ela será implicitamente estática, final e obviamente pública !!!

dganesh2002
fonte
Obviamente, uma variável de instância estaria acessível se fosse permitida em um Java interface. Uma classe implementaria a interface, declarando a variável de instância (conforme exigido pela interface). Seu construtor (ou outro método) define a variável de instância. Quando uma instância da classe é instanciada, você poderá acessar sua variável de instância.
Pyrocrasty
Java permite que métodos estáticos com corpos existam em uma interface. Aqueles poderiam acessar as variáveis ​​estáticas. Eles simplesmente não pode alterá-los, o que significa que as funções estáticas não pode armazenar todos os dados
simpleuser
36

public : pela acessibilidade em todas as classes, assim como os métodos presentes na interface

static : como a interface não pode ter um objeto, o interfaceName.variableName pode ser usado para fazer referência a ele ou diretamente ao variableName na classe que o implementa.

final : torná-las constantes. Se duas classes implementarem a mesma interface e você conceder a elas o direito de alterar o valor, ocorrerá conflito no valor atual da var, e é por isso que apenas uma vez é permitida a inicialização.

Além disso, todos esses modificadores estão implícitos em uma interface, você realmente não precisa especificar nenhum deles.

Nutan
fonte
15

( Esta não é uma resposta filosófica, mas mais prática ). O requisito para staticmodificador é óbvio, o que foi respondido por outros. Basicamente, como as interfaces não podem ser instanciadas, a única maneira de acessar seus campos é torná-los um campo de classe - static.

A razão por que os interfacecampos se tornam automaticamente final(constantes) é impedir que diferentes implementações alterem acidentalmente o valor da variável de interface, o que pode inadvertidamente afetar o comportamento das outras implementações. Imagine o cenário abaixo em que uma interfacepropriedade não se tornou explicitamente finalpelo Java:

public interface Actionable {
    public static boolean isActionable = false;

    public void performAction();
}

public NuclearAction implements Actionable {

    public void performAction() {
        // Code that depends on isActionable variable
        if (isActionable) {
            // Launch nuclear weapon!!!
        }
    }
}

Agora, pense no que aconteceria se outra classe que implementasse Actionablealtera o estado da variável de interface:

public CleanAction implements Actionable  {

    public void performAction() {
        // Code that can alter isActionable state since it is not constant
        isActionable = true;
    }
}

Se essas classes forem carregadas em uma única JVM por um carregador de classes, o comportamento de NuclearActionpoderá ser afetado por outra classe CleanAction, quando sua performAction()chamada CleanActionfor executada após a execução de (na mesma thread ou de outra forma), o que, neste caso, pode ser desastroso. (semanticamente é isso).

Como não sabemos como cada implementação de um interfacevai usar essas variáveis, elas devem estar implicitamente final.

Malvon
fonte
9

Porque qualquer outra coisa faz parte da implementação e as interfaces não podem conter nenhuma implementação.

Amir Afghani
fonte
1
então qual é o motivo da final.
Jothi 12/03/10
7
Para indicar que é uma constante. Java não tem uma palavra-chave const. final estático é como você declara constantes.
Amir Afghani
5
Desde o Java 8, eles podem conter uma implementação, mas é altamente recomendável não usá-lo se você não precisar de compatibilidade com versões anteriores. :)
codepleb
6
public interface A{
    int x=65;
}
public interface B{
    int x=66;
}
public class D implements A,B {
    public static void main(String[] a){
        System.out.println(x); // which x?
    }
}

Aqui está a solução.

System.out.println(A.x); // done

Eu acho que é a única razão pela qual as variáveis ​​de interface são estáticas.

Não declare variáveis ​​dentro da Interface.

Asif Mushtaq
fonte
3
De fato, sem a especificação "Ax", ele não seria compilado ", por isso é realmente seguro usar variáveis ​​(que implicitamente são finais estáticos públicos) nas interfaces.
Marco
Não concordo com a resposta, pois a @Marco disse que nem compilaria. Até agora não encontrei nenhuma outra desvantagem, talvez apenas porque você não vê escrito static finalantes da variável que é realmente estática e final.
Micer
5

estático - porque a interface não pode ter nenhuma instância. e final - porque não precisamos alterá-lo.

RubyDubee
fonte
15
"não precisamos" == "não temos permissão", não misture os significados.
peterh - Restabelece Monica 15/03
3

Porque:

Static : como não podemos ter objetos de interfaces, devemos evitar o uso de variáveis ​​de membro no nível do objeto e usar variáveis ​​no nível da classe, como estáticas.

Final : para que não tenhamos valores ambíguos para as variáveis ​​(problema de diamante - herança múltipla).

E, de acordo com a interface da documentação, é um contrato e não uma implementação.

referência: resposta de Abhishek Jain sobre quora

Arun Raaj
fonte
2

Java não permite variáveis ​​abstratas e / ou definições de construtor em interfaces. Solução: Simplesmente pendure uma classe abstrata entre sua interface e sua implementação, que apenas estende a classe abstrata da seguinte forma:

 public interface IMyClass {

     void methodA();
     String methodB();
     Integer methodC();

 }

 public abstract class myAbstractClass implements IMyClass {
     protected String varA, varB;

     //Constructor
     myAbstractClass(String varA, String varB) {
         this.varA = varA;
         this.varB = VarB;
     }

     //Implement (some) interface methods here or leave them for the concrete class
     protected void methodA() {
         //Do something
     }

     //Add additional methods here which must be implemented in the concrete class
     protected abstract Long methodD();

     //Write some completely new methods which can be used by all subclasses
     protected Float methodE() {
         return 42.0;
     }

 }

 public class myConcreteClass extends myAbstractClass {

     //Constructor must now be implemented!
     myClass(String varA, String varB) {
         super(varA, varB);
     }

     //All non-private variables from the abstract class are available here
     //All methods not implemented in the abstract class must be implemented here

 }

Você também pode usar uma classe abstrata sem qualquer interface, se tiver certeza de que não deseja implementá-la juntamente com outras interfaces posteriormente. Observe que você não pode criar uma instância de uma classe abstrata; DEVE estendê-la primeiro.

(A palavra-chave "protected" significa que apenas classes estendidas podem acessar esses métodos e variáveis.)

spyro

spyro
fonte
1

Uma interface é um contrato entre duas partes que é invariável, esculpido na pedra e, portanto, final. Consulte Design por contrato .

Anssi
fonte
1

Interface: serviço de requisitos do sistema.

Na interface, as variáveis ​​são atribuídas por padrão pelo modificador de acesso público, estático e final . Porque :

público: algumas vezes essa interface pode ser colocada em outro pacote. Portanto, ele precisa acessar a variável de qualquer lugar do projeto.

static: Como essa classe incompleta, não é possível criar objeto. Portanto, no projeto, precisamos acessar a variável sem objeto para que possamos acessar com a ajuda deinterface_filename.variable_name

final: Suponha que uma interface seja implementada por muitas classes e todas as classes tentem acessar e atualizar a variável de interface. Portanto, isso leva a inconsistências na alteração de dados e afeta todas as outras classes. Por isso, é necessário declarar o modificador de acesso com final.

Vishal Sheth
fonte
0

Na Javainterface, não é possível declarar nenhuma variável de instância. O uso de uma variável declarada em uma interface como variável de instância retornará um erro de tempo de compilação.

Você pode declarar uma variável constante, usando o static finalque é diferente de uma variável de instância.

Giri
fonte
Isso está completamente errado. O compilador não irá reclamar, a menos que você o torne privado ou protegido. Sob o capô, como outros já mencionaram, eles são convertidos para final estático público. E acho que é bem óbvio o porquê. Como a interface visa ditar o comportamento, não o estado.
Mikayil Abdullayev 12/03/19
0

A interface pode ser implementada por qualquer classe e, se esse valor for alterado por uma das classes de implementação, haverá um erro para outras classes de implementação. Interface é basicamente uma referência para combinar duas entidades correlacionadas, mas diferentes. Por esse motivo, a variável declarante dentro da interface será implicitamente final e também estática, pois a interface não pode ser instanciada.

user3889476
fonte
0

Pense em um aplicativo da Web em que você tenha definido a interface e outras classes o implementem. Como você não pode criar uma instância da interface para acessar as variáveis, você precisa ter uma palavra-chave estática. Como estática, qualquer alteração no valor será refletida em outras instâncias que o implementaram. Então, para evitá-lo, nós os definimos como finais.

srikant
fonte
0

Apenas experimentada no Eclipse, a variável na interface é o padrão para ser final, portanto você não pode alterá-la. Comparadas com a classe pai, as variáveis ​​são definitivamente alteráveis. Por quê? Do meu ponto de vista, variável em classe é um atributo que será herdado por filhos, e os filhos podem alterá-lo de acordo com sua necessidade real. Pelo contrário, a interface define apenas o comportamento, não o atributo. A única razão para colocar variáveis ​​na interface é usá-las como consts relacionados a essa interface. No entanto, essa não é uma boa prática de acordo com o seguinte trecho:

"A colocação de constantes em uma interface era uma técnica popular nos primeiros dias de Java, mas agora muitos consideram um uso desagradável de interfaces, já que as interfaces devem lidar com os serviços fornecidos por um objeto, não com seus dados. Além disso, as constantes usadas por uma classe geralmente são um detalhe de implementação, mas colocá-los em uma interface os promove à API pública da classe ".

Eu também tentei colocar estática ou não faz nenhuma diferença. O código é o seguinte:

public interface Addable {
    static int count = 6;

    public int add(int i);

}

public class Impl implements Addable {

    @Override
    public int add(int i) {
        return i+count;
    }
}

public class Test {

    public static void main(String... args) {
        Impl impl = new Impl();

        System.out.println(impl.add(4));
    }
}
muyong
fonte