Por que as variáveis de interface são estáticas e finais por padrão em Java?
Por que as variáveis de interface são estáticas e finais por padrão em Java?
Respostas:
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.
static
modificador é 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 interface
não possa ser instanciado diretamente - você ainda pode ter instâncias de classes que implementam o interface
e é 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 final
significa.
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 !!!
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.
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.
( Esta não é uma resposta filosófica, mas mais prática ). O requisito para static
modificador é ó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 interface
campos 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 interface
propriedade não se tornou explicitamente final
pelo 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 Actionable
altera 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 NuclearAction
poderá ser afetado por outra classe CleanAction
, quando sua performAction()
chamada CleanAction
for 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 interface
vai usar essas variáveis, elas devem estar implicitamente final
.
Porque qualquer outra coisa faz parte da implementação e as interfaces não podem conter nenhuma implementação.
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.
static final
antes da variável que é realmente estática e final.
estático - porque a interface não pode ter nenhuma instância. e final - porque não precisamos alterá-lo.
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
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
Uma interface é um contrato entre duas partes que é invariável, esculpido na pedra e, portanto, final. Consulte Design por contrato .
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.
Na Java
interface, 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 final
que é diferente de uma variável de instância.
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.
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.
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));
}
}