O que é uma "classe abstrata" em Java?
O que é uma "classe abstrata" em Java?
Respostas:
Uma classe abstrata é uma classe que não pode ser instanciada. Uma classe abstrata é usada criando uma subclasse herdada que pode ser instanciada. Uma classe abstrata faz algumas coisas para a subclasse herdada:
Aqui está um exemplo:
abstract public class AbstractClass
{
abstract public void abstractMethod();
public void implementedMethod() { System.out.print("implementedMethod()"); }
final public void finalMethod() { System.out.print("finalMethod()"); }
}
Observe que "abstractMethod ()" não possui nenhum corpo de método. Por esse motivo, você não pode fazer o seguinte:
public class ImplementingClass extends AbstractClass
{
// ERROR!
}
Não há método que implemente abstractMethod()
! Portanto, não há como a JVM saber o que deve fazer quando obtém algo comonew ImplementingClass().abstractMethod()
.
Aqui está um correto ImplementingClass
.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
}
Observe que você não precisa definir implementedMethod()
ou finalMethod()
. Eles já foram definidos porAbstractClass
.
Aqui está outro correto ImplementingClass
.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
}
Nesse caso, você substituiu implementedMethod()
.
No entanto, devido à final
palavra - chave, o seguinte não é possível.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
public void finalMethod() { System.out.print("ERROR!"); }
}
Você não pode fazer isso porque a implementação de finalMethod()
in AbstractClass
está marcada como a implementação final definalMethod()
: nenhuma outra implementação será permitida, nunca.
Agora você também pode implementar uma classe abstrata duas vezes:
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
}
// In a separate file.
public class SecondImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("second abstractMethod()"); }
}
Agora em algum lugar você poderia escrever outro método.
public tryItOut()
{
ImplementingClass a = new ImplementingClass();
AbstractClass b = new ImplementingClass();
a.abstractMethod(); // prints "abstractMethod()"
a.implementedMethod(); // prints "Overridden!" <-- same
a.finalMethod(); // prints "finalMethod()"
b.abstractMethod(); // prints "abstractMethod()"
b.implementedMethod(); // prints "Overridden!" <-- same
b.finalMethod(); // prints "finalMethod()"
SecondImplementingClass c = new SecondImplementingClass();
AbstractClass d = new SecondImplementingClass();
c.abstractMethod(); // prints "second abstractMethod()"
c.implementedMethod(); // prints "implementedMethod()"
c.finalMethod(); // prints "finalMethod()"
d.abstractMethod(); // prints "second abstractMethod()"
d.implementedMethod(); // prints "implementedMethod()"
d.finalMethod(); // prints "finalMethod()"
}
Observe que, embora tenhamos declarado b
um AbstractClass
tipo, ele é exibido "Overriden!"
. Isso ocorre porque o objeto que instanciamos era, na verdade ImplementingClass
, um , e implementedMethod()
é claro que ele foi substituído. (Você pode ter visto isso conhecido como polimorfismo.)
Se desejamos acessar um membro específico para uma subclasse específica, devemos converter essa subclasse primeiro:
// Say ImplementingClass also contains uniqueMethod()
// To access it, we use a cast to tell the runtime which type the object is
AbstractClass b = new ImplementingClass();
((ImplementingClass)b).uniqueMethod();
Por fim, você não pode fazer o seguinte:
public class ImplementingClass extends AbstractClass, SomeOtherAbstractClass
{
... // implementation
}
Apenas uma classe pode ser estendida por vez. Se você precisar estender várias classes, elas deverão ser interfaces. Você consegue fazer isso:
public class ImplementingClass extends AbstractClass implements InterfaceA, InterfaceB
{
... // implementation
}
Aqui está um exemplo de interface:
interface InterfaceA
{
void interfaceMethod();
}
É basicamente o mesmo que:
abstract public class InterfaceA
{
abstract public void interfaceMethod();
}
A única diferença é que a segunda maneira não permite que o compilador saiba que na verdade é uma interface. Isso pode ser útil se você quiser que as pessoas implementem apenas sua interface e nenhuma outra. No entanto, como regra geral para iniciantes, se sua classe abstrata tiver apenas métodos abstratos, você provavelmente deve transformá-la em uma interface.
O seguinte é ilegal:
interface InterfaceB
{
void interfaceMethod() { System.out.print("ERROR!"); }
}
Você não pode implementar métodos em uma interface. Isso significa que, se você implementar duas interfaces diferentes, os métodos diferentes nessas interfaces não poderão colidir. Como todos os métodos em uma interface são abstratos, é necessário implementar o método e, como o método é a única implementação na árvore de herança, o compilador sabe que precisa usar o método.
c.implementedMethod()
imprimir "Overriden!"? SecondImplementingClass
não substitui implementedMethod()
.
Uma classe Java se torna abstrata nas seguintes condições:
1. Pelo menos um dos métodos está marcado como abstrato:
public abstract void myMethod()
Nesse caso, o compilador obriga a marcar toda a classe como abstrata.
2. A turma é marcada como abstrata:
abstract class MyClass
Como já foi dito: Se você possui um método abstrato, o compilador obriga a marcar toda a classe como abstrata. Mas mesmo se você não tiver um método abstrato, poderá marcar a classe como abstrata.
Uso comum:
Um uso comum de classes abstratas é fornecer um esboço de uma classe semelhante à de uma interface. Mas, diferentemente de uma interface, ela já pode fornecer funcionalidade, ou seja, algumas partes da classe são implementadas e outras são apenas descritas com uma declaração de método. ("resumo")
Uma classe abstrata não pode ser instanciada, mas você pode criar uma classe concreta com base em uma classe abstrata, que pode ser instanciada. Para fazer isso, você deve herdar da classe abstrata e substituir os métodos abstratos, ou seja, implementá-los.
abstract
palavra-chave é tudo o que é necessário para uma classe ser abstrata. Mas uma classe concreta não pode conter um abstract
método . Portanto, se sua classe possui um abstract
método, ele deve ser declarado como uma abstract
classe para o compilador.
Uma classe declarada usando a palavra-chave abstract é conhecida como abstract class
. Abstração é um processo de ocultar os detalhes de implementação de dados e mostrar apenas funcionalidade ao usuário. A abstração permite que você se concentre no que o objeto faz, e não como ele faz.
Principais coisas da classe abstrata
Uma classe abstrata pode ou não conter métodos abstratos. Pode haver métodos não abstratos.
Um método abstrato é um método que é declarado sem uma implementação (sem chaves e seguido por um ponto e vírgula), assim:
ex: abstract void moveTo(double deltaX, double deltaY);
Se uma classe tiver pelo menos um método abstrato, essa classe deverá ser abstrata
Classes abstratas não podem ser instanciadas (você não tem permissão para criar objetos da classe Abstrata)
Para usar uma classe abstrata, você deve herdá-la de outra classe. Forneça implementações para todos os métodos abstratos nele.
Se você herdar uma classe abstrata, precisará fornecer implementações para todos os métodos abstratos nela.
Declarar classe abstrata A
especificação da abstract
palavra-chave antes da classe durante a declaração a torna abstrata. Dê uma olhada no código abaixo:
abstract class AbstractDemo{ }
Declarar método abstrato A
especificação da abstract
palavra-chave antes do método durante a declaração o torna abstrato. Dê uma olhada no código abaixo,
abstract void moveTo();//no body
Por que precisamos abstrair classes
Em um aplicativo de desenho orientado a objetos, você pode desenhar círculos, retângulos, linhas, curvas de Bezier e muitos outros objetos gráficos. Todos esses objetos têm determinados estados (por exemplo: posição, orientação, cor da linha, cor de preenchimento) e comportamentos (por exemplo:: mover, girar, redimensionar, desenhar) em comum. Alguns desses estados e comportamentos são os mesmos para todos os objetos gráficos (por exemplo: cor de preenchimento, posição e moveTo). Outros requerem implementação diferente (por exemplo: redimensionar ou desenhar). Todos os objetos gráficos devem ser capazes de desenhar ou redimensionar a si mesmos, apenas diferem em como o fazem.
Esta é uma situação perfeita para uma superclasse abstrata. Você pode tirar proveito das semelhanças e declarar todos os objetos gráficos como herdados do mesmo objeto pai abstrato (por exemplo:), GraphicObject
como mostrado na figura a seguir.
Primeiro, você declara uma classe abstrata,, GraphicObject
para fornecer variáveis e métodos de membros que são totalmente compartilhados por todas as subclasses, como a posição atual e o método moveTo. GraphicObject
também declararam métodos abstratos, como desenhar ou redimensionar, que precisam ser implementados por todas as subclasses, mas devem ser implementados de maneiras diferentes. A GraphicObject
classe pode ser algo como isto:
abstract class GraphicObject {
void moveTo(int x, int y) {
// Inside this method we have to change the position of the graphic
// object according to x,y
// This is the same in every GraphicObject. Then we can implement here.
}
abstract void draw(); // But every GraphicObject drawing case is
// unique, not common. Then we have to create that
// case inside each class. Then create these
// methods as abstract
abstract void resize();
}
Uso do método abstrato nas subclasses
Cada subclasse não abstrata de GraphicObject
, como Circle
e Rectangle
, deve fornecer implementações para os métodos draw
e resize
.
class Circle extends GraphicObject {
void draw() {
//Add to some implementation here
}
void resize() {
//Add to some implementation here
}
}
class Rectangle extends GraphicObject {
void draw() {
//Add to some implementation here
}
void resize() {
//Add to some implementation here
}
}
Dentro do main
método, você pode chamar todos os métodos como este:
public static void main(String args[]){
GraphicObject c = new Circle();
c.draw();
c.resize();
c.moveTo(4,5);
}
Maneiras de obter abstração em Java
Existem duas maneiras de obter abstração em java
Classe abstrata com construtores, membros de dados, métodos, etc.
abstract class GraphicObject {
GraphicObject (){
System.out.println("GraphicObject is created");
}
void moveTo(int y, int x) {
System.out.println("Change position according to "+ x+ " and " + y);
}
abstract void draw();
}
class Circle extends GraphicObject {
void draw() {
System.out.println("Draw the Circle");
}
}
class TestAbstract {
public static void main(String args[]){
GraphicObject grObj = new Circle ();
grObj.draw();
grObj.moveTo(4,6);
}
}
Resultado:
GraphicObject is created
Draw the Circle
Change position according to 6 and 4
Lembre-se de duas regras:
Se a classe tiver poucos métodos abstratos e poucos métodos concretos, declare-a como uma abstract
classe.
Se a classe tiver apenas métodos abstratos, declare-a como um interface
.
Referências:
É uma classe que não pode ser instanciada e força a implementação de classes para, possivelmente, implementar métodos abstratos que ela descreve.
Simplesmente falando, você pode pensar em uma classe abstrata como uma Interface com um pouco mais de capacidade.
Você não pode instanciar uma interface, que também vale para uma classe abstrata.
Na sua interface, você pode apenas definir os cabeçalhos do método e TODOS os implementadores são forçados a implementar todos eles. Em uma classe abstrata, você também pode definir os cabeçalhos do método, mas aqui - à diferença da interface - também é possível definir o corpo (geralmente uma implementação padrão) do método. Além disso, quando outras classes estendem (observe, não implementam e, portanto, você também pode ter apenas uma classe abstrata por classe filho) sua classe abstrata, elas não são forçadas a implementar todos os seus métodos da sua classe abstrata, a menos que você tenha especificado um método abstrato ( nesse caso, funciona como para interfaces, você não pode definir o corpo do método).
public abstract class MyAbstractClass{
public abstract void DoSomething();
}
Caso contrário, para métodos normais de uma classe abstrata, os "herdeiros" podem simplesmente usar o comportamento padrão ou substituí-lo, como de costume.
Exemplo:
public abstract class MyAbstractClass{
public int CalculateCost(int amount){
//do some default calculations
//this can be overriden by subclasses if needed
}
//this MUST be implemented by subclasses
public abstract void DoSomething();
}
Da documentação do oracle
Resumo Métodos e Classes:
Uma classe abstrata é uma classe que é declarada abstrata - pode ou não incluir métodos abstratos
Classes abstratas não podem ser instanciadas, mas podem ser subclassificadas
Um método abstrato é um método que é declarado sem uma implementação (sem chaves e seguido por um ponto e vírgula), assim:
abstract void moveTo(double deltaX, double deltaY);
Se uma classe incluir métodos abstratos, a própria classe deverá ser declarada abstrata, como em:
public abstract class GraphicObject {
// declare fields
// declare nonabstract methods
abstract void draw();
}
Quando uma classe abstrata é subclassificada, a subclasse geralmente fornece implementações para todos os métodos abstratos em sua classe pai. No entanto, se isso não acontecer, a subclasse também deve ser declarada abstrata .
Desde abstract classes
e interfaces
relacionados, dê uma olhada nas perguntas abaixo SE:
Qual é a diferença entre uma interface e uma classe abstrata?
Como devo ter explicado a diferença entre uma interface e uma classe abstrata?
Obtenha suas respostas aqui:
Classe abstrata vs Interface em Java
Uma classe abstrata pode ter um método final?
Entre - essas são as perguntas que você fez recentemente. Pense em uma nova pergunta para construir reputação ...
Editar:
Acabei de perceber que os cartazes desta e das perguntas referenciadas têm o mesmo ou pelo menos um nome semelhante, mas o ID do usuário é sempre diferente. Então, também, há um problema técnico, que o keyur tem problemas para fazer login novamente e encontrar as respostas para suas perguntas ou esse é um tipo de jogo para entreter a comunidade SO;)
Pouca adição a todos esses posts.
Às vezes, você pode declarar uma classe e ainda não sabe como definir todos os métodos que pertencem a essa classe. Por exemplo, você pode declarar uma classe chamada Writer e incluir nela um método membro chamado write () . No entanto, você não sabe codificar write () porque é diferente para cada tipo de dispositivo Writer. Obviamente, você planeja lidar com isso derivando subclasses de Writer, como Impressora, Disco, Rede e Console.
Uma classe abstrata não pode ser instanciada diretamente, mas deve ser derivada para ser utilizável. Uma classe DEVE ser abstrata se contiver métodos abstratos: diretamente
abstract class Foo {
abstract void someMethod();
}
ou indiretamente
interface IFoo {
void someMethod();
}
abstract class Foo2 implements IFoo {
}
No entanto, uma classe pode ser abstrata sem conter métodos abstratos. É uma maneira de impedir a instanciação direta, por exemplo
abstract class Foo3 {
}
class Bar extends Foo3 {
}
Foo3 myVar = new Foo3(); // illegal! class is abstract
Foo3 myVar = new Bar(); // allowed!
O último estilo de classes abstratas pode ser usado para criar classes "semelhantes a interfaces". Diferentemente das interfaces, uma classe abstrata pode conter métodos não abstratos e variáveis de instância. Você pode usar isso para fornecer alguma funcionalidade básica para estender classes.
Outro padrão frequente é implementar a funcionalidade principal na classe abstrata e definir parte do algoritmo em um método abstrato a ser implementado por uma classe estendida. Exemplo estúpido:
abstract class Processor {
protected abstract int[] filterInput(int[] unfiltered);
public int process(int[] values) {
int[] filtered = filterInput(values);
// do something with filtered input
}
}
class EvenValues extends Processor {
protected int[] filterInput(int[] unfiltered) {
// remove odd numbers
}
}
class OddValues extends Processor {
protected int[] filterInput(int[] unfiltered) {
// remove even numbers
}
}
public abstract class Place {
String Name;
String Postcode;
String County;
String Area;
Place () {
}
public static Place make(String Incoming) {
if (Incoming.length() < 61) return (null);
String Name = (Incoming.substring(4,26)).trim();
String County = (Incoming.substring(27,48)).trim();
String Postcode = (Incoming.substring(48,61)).trim();
String Area = (Incoming.substring(61)).trim();
Place created;
if (Name.equalsIgnoreCase(Area)) {
created = new Area(Area,County,Postcode);
} else {
created = new District(Name,County,Postcode,Area);
}
return (created);
}
public String getName() {
return (Name);
}
public String getPostcode() {
return (Postcode);
}
public String getCounty() {
return (County);
}
public abstract String getArea();
}
Uma classe abstrata é uma classe que é declarada abstrata - pode ou não incluir métodos abstratos. Classes abstratas não podem ser instanciadas, mas podem ser subclassificadas.
Em outras palavras, uma classe declarada com a palavra-chave abstract é conhecida como classe abstrata em java. Pode ter métodos abstratos (método sem corpo) e não abstratos (método com corpo).
Nota importante: - Classes abstratas não podem ser usadas para instanciar objetos, elas podem ser usadas para criar referências a objetos, porque a abordagem de Java ao polimorfismo em tempo de execução é implementada através do uso de referências de superclasse. Portanto, deve ser possível criar uma referência a uma classe abstrata para que possa ser usada para apontar para um objeto de subclasse. Você verá esse recurso no exemplo abaixo
abstract class Bike{
abstract void run();
}
class Honda4 extends Bike{
void run(){
System.out.println("running safely..");
}
public static void main(String args[]){
Bike obj = new Honda4();
obj.run();
}
}
Uma classe abstrata é aquela que não está totalmente implementada, mas fornece uma espécie de blueprint para subclasses. Pode ser parcialmente implementado, pois contém métodos concretos totalmente definidos, mas também pode conter métodos abstratos. Estes são métodos com uma assinatura, mas sem corpo de método. Qualquer subclasse deve definir um corpo para cada método abstrato, caso contrário, também deve ser declarado abstrato. Como as classes abstratas não podem ser instanciadas, elas devem ser estendidas por pelo menos uma subclasse para serem utilizadas. Pense na classe abstrata como a classe genérica, e as subclasses existem para preencher as informações ausentes.
Não faz nada, apenas forneça um modelo comum que será compartilhado para sua subclasse