Eu tenho um código Java simples que se parece com este em sua estrutura:
abstract public class BaseClass {
String someString;
public BaseClass(String someString) {
this.someString = someString;
}
abstract public String getName();
}
public class ACSubClass extends BaseClass {
public ASubClass(String someString) {
super(someString);
}
public String getName() {
return "name value for ASubClass";
}
}
Terei algumas subclasses de BaseClass
, cada uma implementando o getName()
método em sua própria maneira ( padrão de método de modelo ).
Isso funciona bem, mas não gosto de ter o construtor redundante nas subclasses. É mais para digitar e é difícil de manter. Se eu fosse alterar a assinatura do método do BaseClass
construtor, teria que alterar todas as subclasses.
Quando removo o construtor das subclasses, recebo este erro em tempo de compilação:
Implicit super constructor BaseClass() is undefined for default constructor. Must define an explicit constructor
O que estou tentando fazer é possível?
java
inheritance
dry
boilerplate
Joel
fonte
fonte
Respostas:
Você obtém este erro porque uma classe que não tem construtor tem um construtor padrão , que não tem argumentos e é equivalente ao seguinte código:
No entanto, como sua BaseClass declara um construtor (e, portanto, não tem o construtor padrão, sem argumentos que o compilador forneceria), isso é ilegal - uma classe que estende BaseClass não pode ser chamada
super();
porque não há um construtor sem argumento em BaseClass.Isso provavelmente é um pouco contra-intuitivo, porque você pode pensar que uma subclasse possui automaticamente qualquer construtor que a classe base possui.
A maneira mais simples de contornar isso é a classe base não declarar um construtor (e, portanto, ter o construtor não-arg padrão) ou ter um construtor não-arg declarado (sozinho ou ao lado de qualquer outro construtor). Mas muitas vezes essa abordagem não pode ser aplicada - porque você precisa de todos os argumentos que estão sendo passados para o construtor para construir uma instância legítima da classe.
fonte
BaseClass
mas faça-o simplesmente lançar umUnsupportedOperationException
ou algo assim. Não é a melhor solução (sugere falsamente que a classe pode suportar um construtor sem arg), mas é a melhor que posso pensar.Para quem procura esse erro no Google e chega aqui: pode haver outro motivo para recebê-lo. O Eclipse apresenta esse erro quando você tem configuração do projeto - incompatibilidade de configuração do sistema.
Por exemplo, se você importar o projeto Java 1.7 para o Eclipse e não tiver o 1.7 configurado corretamente, receberá este erro. Então você pode ir para
Project - Preference - Java - Compiler
eswitch to 1.6 or earlier
; ou vá paraWindow - Preferences - Java - Installed JREs
e adicione / corrija a instalação do JRE 1.7.fonte
É possível, mas não do jeito que você o tem.
Você tem que adicionar um construtor no-args à classe base e é isso!
Quando você não adiciona um construtor (qualquer) a uma classe, o compilador adiciona o construtor sem arg padrão para você.
Quando o padrão nenhum arg chama super (); e como você não o tem na superclasse, você recebe aquela mensagem de erro.
Isso é sobre a própria questão.
Agora, expandindo a resposta:
Você está ciente de que criar uma subclasse (comportamento) para especificar um valor diferente (dados) não faz sentido ?? !!! Espero que você faça.
Se a única coisa que muda é o "nome", então uma única classe parametrizada é o suficiente!
Então você não precisa disso:
ou
Quando você pode escrever isto:
Bem, é por isso que a herança é o artefato que cria o acoplamento HIGH, o que é indesejável em sistemas OO. Deve ser evitado e talvez substituído por composição.
Pense se você realmente precisa deles como subclasse. É por isso que você vê muitas vezes interfaces usadas em vez de:
Aqui B e C poderiam ter herdado de A, o que teria criado um acoplamento muito ALTO entre eles, ao usar interfaces o acoplamento é reduzido, se A decidir que não será mais "NameAware" as outras classes não quebrarão.
Claro, se você quiser reutilizar o comportamento, isso não funcionará.
fonte
Você também pode obter este erro quando o JRE não está definido. Nesse caso, tente adicionar a Biblioteca do sistema JRE ao seu projeto.
Sob Eclipse IDE:
fonte
Outra maneira é chamar super () com o argumento necessário como uma primeira instrução no construtor da classe derivada.
fonte
O Eclipse apresentará esse erro se você não tiver uma chamada para o construtor da superclasse como uma primeira instrução no construtor da subclasse.
fonte
Desculpe por necropostar, mas enfrentei esse problema apenas hoje. Para todos que também enfrentam esse problema - uma das possíveis razões - você não chama
super
na primeira linha do método. A segunda, a terceira e outras linhas disparam esse erro. A chamada de super deve ser a primeira chamada em seu método. Neste caso está tudo bem.fonte
Você pode resolver esse erro adicionando um construtor sem argumentos à classe base (conforme mostrado abaixo).
Felicidades.
fonte
someString
) definidos e, portanto, anula totalmente o propósito de como construtor.Eu tive esse erro e o corrigi removendo uma exceção lançada ao lado do método para um bloco try / catch
Por exemplo: DE:
PARA:
fonte