Classe astratta in Java

Cos’è una “class astratta” in Java?

Una class astratta è una class che non può essere istanziata. Una class astratta viene utilizzata creando una sottoclass ereditaria che può essere istanziata. Una class astratta fa alcune cose per la sottoclass ereditaria:

  1. Definire i metodi che possono essere utilizzati dalla sottoclass ereditaria.
  2. Definire i metodi astratti che la sottoclass ereditaria deve implementare.
  3. Fornire un’interfaccia comune che consente di intercambiare la sottoclass con tutte le altre sottoclassi.

Ecco un esempio:

abstract public class AbstractClass { abstract public void abstractMethod(); public void implementedMethod() { System.out.print("implementedMethod()"); } final public void finalMethod() { System.out.print("finalMethod()"); } } 

Si noti che “abstractMethod ()” non ha alcun corpo del metodo. Per questo motivo, non puoi fare quanto segue:

 public class ImplementingClass extends AbstractClass { // ERROR! } 

Non esiste un metodo che implementa abstractMethod() ! Quindi non c’è modo per la JVM di sapere che cosa deve fare quando ottiene qualcosa come il new ImplementingClass().abstractMethod() .

Ecco un ImplementingClass corretto.

 public class ImplementingClass extends AbstractClass { public void abstractMethod() { System.out.print("abstractMethod()"); } } 

Si noti che non è necessario definire finalMethod() o finalMethod() . Erano già stati definiti da AbstractClass .

Ecco un altro ImplementingClass corretto.

 public class ImplementingClass extends AbstractClass { public void abstractMethod() { System.out.print("abstractMethod()"); } public void implementedMethod() { System.out.print("Overridden!"); } } 

In questo caso, hai implementedMethod() overMiddenhodet implementedMethod() .

Tuttavia, a causa della parola chiave final , quanto segue non è ansible.

 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!"); } } 

Non è ansible farlo perché l’implementazione di finalMethod() in AbstractClass è contrassegnata come l’implementazione finale di finalMethod() : non saranno consentite altre implementazioni, mai.

Ora puoi anche implementare una class astratta due volte:

 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()"); } } 

Ora da qualche parte potresti scrivere un altro metodo.

 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()" } 

Si noti che, anche se abbiamo dichiarato b un tipo di AbstractClass , viene visualizzato "Overriden!" . Questo perché l'object istanziato era in realtà un ImplementingClass , la cui implementedMethod() è ovviamente sovrascritta. (Potresti aver visto questo definito come polimorfismo).

Se desideriamo accedere a un membro specifico per una determinata sottoclass, dobbiamo prima eseguire il downdown in tale sottoclass:

 // 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(); 

Infine, non puoi fare quanto segue:

 public class ImplementingClass extends AbstractClass, SomeOtherAbstractClass { ... // implementation } 

È ansible estendere una sola class alla volta. Se è necessario estendere più classi, devono essere interfacce. Puoi farlo:

 public class ImplementingClass extends AbstractClass implements InterfaceA, InterfaceB { ... // implementation } 

Ecco un'interfaccia di esempio:

 interface InterfaceA { void interfaceMethod(); } 

Questo è fondamentalmente lo stesso di:

 abstract public class InterfaceA { abstract public void interfaceMethod(); } 

L'unica differenza è che il secondo modo non consente al compilatore di sapere che in realtà è un'interfaccia. Questo può essere utile se vuoi che le persone implementino solo la tua interfaccia e nessun altro. Tuttavia, come regola generale per principianti, se la tua class astratta ha solo metodi astratti, dovresti probabilmente renderla un'interfaccia.

Quanto segue è illegale:

 interface InterfaceB { void interfaceMethod() { System.out.print("ERROR!"); } } 

Non è ansible implementare metodi in un'interfaccia. Ciò significa che se si implementano due interfacce diverse, i diversi metodi in tali interfacce non possono collidere. Poiché tutti i metodi in un'interfaccia sono astratti, devi implementare il metodo e, poiché il tuo metodo è l'unica implementazione nell'albero di ereditarietà, il compilatore sa che deve usare il tuo metodo.

Una class Java diventa astratta nelle seguenti condizioni:

1. Almeno uno dei metodi è contrassegnato come astratto:

 public abstract void myMethod() 

In tal caso, il compilatore ti costringe a contrassegnare l’intera class come astratta.

2. La class è contrassegnata come astratta:

 abstract class MyClass 

Come già detto: se hai un metodo astratto, il compilatore ti costringe a contrassegnare l’intera class come astratta. Ma anche se non hai alcun metodo astratto puoi comunque contrassegnare la class come astratta.

Uso comune:

Un uso comune delle classi astratte è quello di fornire uno schema di una class simile a un’interfaccia. Ma a differenza di un’interfaccia, può già fornire funzionalità, cioè alcune parti della class sono implementate e alcune parti sono appena delineate con una dichiarazione di metodo. (“astratto”)

Una class astratta non può essere istanziata, ma è ansible creare una class concreta basata su una class astratta, che può quindi essere istanziata. Per fare ciò devi ereditare dalla class astratta e scavalcare i metodi astratti, cioè implementarli.

Una class dichiarata usando la parola chiave abstract è conosciuta come abstract class . L’astrazione è un processo che nasconde i dettagli dell’implementazione dei dati e mostra solo le funzionalità all’utente. L’astrazione ti consente di concentrarti su cosa fa l’object invece di come lo fa.

Le cose principali della class astratta

  • Una class astratta può o non può contenere metodi astratti. Ci possono essere metodi non astratti.

    Un metodo astratto è un metodo che viene dichiarato senza un’implementazione (senza parentesi e seguito da un punto e virgola), come questo:

    ex: abstract void moveTo(double deltaX, double deltaY);

  • Se una class ha almeno un metodo astratto, allora quella class deve essere astratta

  • Le classi astratte non possono essere istanziate (non ti è permesso creare oggetti della class Abstract)

  • Per usare una class astratta, devi ereditarla da un’altra class. Fornire implementazioni a tutti i metodi astratti in esso.

  • Se si eredita una class astratta, è necessario fornire implementazioni a tutti i metodi astratti in essa contenuti.

Dichiarazione di class astratta La specifica della parola chiave abstract prima della class durante la dichiarazione lo rende astratto. Dai un’occhiata al codice qui sotto:

 abstract class AbstractDemo{ } 

Declare metodo astratto Specificare la parola chiave abstract prima del metodo durante la dichiarazione lo rende astratto. Dai un’occhiata al codice qui sotto,

 abstract void moveTo();//no body 

Perché abbiamo bisogno di astrarre classi

In un’applicazione di disegno orientata agli oggetti, è ansible disegnare cerchi, rettangoli, linee, curve di Bézier e molti altri oggetti grafici. Tutti questi oggetti hanno determinati stati (per esempio: posizione, orientamento, colore della linea, colore di riempimento) e comportamenti (per esempio: moveTo, rotazione, ridimensionamento, disegno) in comune. Alcuni di questi stati e comportamenti sono gli stessi per tutti gli oggetti grafici (ad esempio: colore di riempimento, posizione e sposta a). Altri richiedono un’implementazione diversa (ad es: ridimensiona o disegna). Tutti gli oggetti grafici devono essere in grado di disegnare o ridimensionare se stessi, differiscono solo nel modo in cui lo fanno.

Questa è una situazione perfetta per una superclass astratta. È ansible sfruttare le somiglianze e dichiarare che tutti gli oggetti grafici ereditano dallo stesso object padre astratto (ad esempio: GraphicObject ) come mostrato nella seguente figura. inserisci la descrizione dell'immagine qui

Innanzitutto, si dichiara una class astratta, GraphicObject , per fornire variabili membro e metodi che sono interamente condivisi da tutte le sottoclassi, come la posizione corrente e il metodo moveTo. GraphicObject anche dichiarato metodi astratti, come disegnare o ridimensionare, che devono essere implementati da tutte le sottoclassi, ma devono essere implementati in modi diversi. La class GraphicObject può avere un aspetto simile a questo:

 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 del metodo astratto nelle sottoclassi Ogni sottoclass non astratta di GraphicObject , come Circle e Rectangle , deve fornire implementazioni per i metodi 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 } } 

All’interno del metodo main puoi chiamare tutti i metodi come questo:

 public static void main(String args[]){ GraphicObject c = new Circle(); c.draw(); c.resize(); c.moveTo(4,5); } 

Modi per raggiungere l’astrazione in Java

Ci sono due modi per ottenere l’astrazione in java

  • Classe astratta (da 0 a 100%)
  • Interfaccia (100%)

Classe astratta con costruttori, membri di dati, metodi, ecc

 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); } } 

Produzione:

 GraphicObject is created Draw the Circle Change position according to 6 and 4 

Ricorda due regole:

  • Se la class ha pochi metodi astratti e pochi metodi concreti, dichiaralo come una class abstract .

  • Se la class ha solo metodi astratti, dichiararla come interface .

Riferimenti:

  • TutorialsPoint – Java Abstraction
  • BeginnersBook – Metodo Java Abstract Class
  • Documento Java – Metodi e classi astratti
  • JavaPoint – Classe astratta in Java

È una class che non può essere istanziata e costringe le classi di implementazione a, possibilmente, a implementare metodi astratti che delinea.

Dalla documentazione di Oracle

Metodi e classi astratte:

Una class astratta è una class che è dichiarata astratta – può includere o meno metodi astratti

Le classi astratte non possono essere istanziate, ma possono essere sottoclassate

Un metodo astratto è un metodo che viene dichiarato senza un’implementazione (senza parentesi e seguito da un punto e virgola), come questo:

 abstract void moveTo(double deltaX, double deltaY); 

Se una class include metodi astratti, la class stessa deve essere dichiarata astratta, come in:

 public abstract class GraphicObject { // declare fields // declare nonabstract methods abstract void draw(); } 

Quando una class astratta è sottoclass, la sottoclass di solito fornisce implementazioni per tutti i metodi astratti nella sua class genitore. Tuttavia, se così non fosse, anche la sottoclass deve essere dichiarata astratta .

Poiché le abstract classs e le interfaces abstract classs sono correlate, dai uno sguardo alle domande SE seguenti:

Qual è la differenza tra un’interfaccia e una class astratta?

Come dovrei aver spiegato la differenza tra un’interfaccia e una class astratta?

Ottieni le tue risposte qui:

Classe astratta vs interfaccia in Java

Una class astratta può avere un metodo finale?

A proposito, quelle sono domande che hai chiesto di recente. Pensa a una nuova domanda per build la reputazione …

Modificare:

Appena realizzato, che i poster di questa e le domande di riferimento hanno lo stesso nome o almeno un nome simile, ma l’ID utente è sempre diverso. Quindi, c’è un problema tecnico, che keyur ha problemi ad accedere di nuovo e trovare le risposte alle sue domande o questa è una sorta di gioco per intrattenere la comunità SO;)

Semplicemente parlando, puoi pensare ad una class astratta come ad un’interfaccia con un po ‘più di funzionalità.

Non è ansible creare un’istanza di un’interfaccia, che vale anche per una class astratta.

Sulla tua interfaccia puoi semplicemente definire le intestazioni del metodo e TUTTI gli implementatori sono obbligati a implementarle tutte . Su una class astratta puoi anche definire le intestazioni del tuo metodo ma qui – alla differenza dell’interfaccia – puoi anche definire il corpo (di solito un’implementazione predefinita) del metodo. Inoltre quando le altre classi si estendono (si noti, non si implementa e quindi si può avere anche solo una class astratta per class figlio) della class astratta, non sono obbligate ad implementare tutti i metodi della class astratta, a meno che non si specifichi un metodo astratto ( in tal caso funziona come per le interfacce, non è ansible definire il corpo del metodo).

 public abstract class MyAbstractClass{ public abstract void DoSomething(); } 

Altrimenti, per i normali metodi di una class astratta, gli “ereditari” possono semplicemente usare il comportamento predefinito o sovrascriverlo, come al solito.

Esempio:

 public abstract class MyAbstractClass{ public int CalculateCost(int amount){ //do some default calculations //this can be overriden by subclasss if needed } //this MUST be implemented by subclasss public abstract void DoSomething(); } 

Piccola aggiunta a tutti questi messaggi.

A volte potresti voler dichiarare una class e ancora non sapere come definire tutti i metodi che appartengono a quella class. Ad esempio, potresti voler dichiarare una class chiamata Writer e includere in essa un metodo membro chiamato write () . Tuttavia, non si sa come scrivere codice () perché è diverso per ogni tipo di dispositivo Writer. Naturalmente, si prevede di gestirlo derivando sottoclassi di Writer, come Stampante, Disco, Rete e Console.

Una class astratta non può essere istanziata direttamente, ma deve essere derivata dall’essere utilizzabile. Una class DEVE essere astratta se contiene metodi astratti: direttamente

 abstract class Foo { abstract void someMethod(); } 

o indirettamente

 interface IFoo { void someMethod(); } abstract class Foo2 implements IFoo { } 

Tuttavia, una class può essere astratta senza contenere metodi astratti. È un modo per prevenire l’istanziazione diretta, ad es

 abstract class Foo3 { } class Bar extends Foo3 { } Foo3 myVar = new Foo3(); // illegal! class is abstract Foo3 myVar = new Bar(); // allowed! 

Il secondo stile di classi astratte può essere usato per creare classi “interfaccia-like”. A differenza delle interfacce, una class astratta può contenere metodi non astratti e variabili di istanza. È ansible utilizzare questo per fornire alcune funzionalità di base per estendere le classi.

Un altro schema frequente è quello di implementare la funzionalità principale nella class astratta e definire parte dell’algoritmo in un metodo astratto che deve essere implementato da una class estesa. Esempio stupido:

 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 } } 

Soluzione – class base (abstract)

 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(); } 

Classe che può avere sia metodi concreti che non concreti, cioè con corpo e senza corpo. I metodi 1 senza implementazione devono contenere la parola chiave astratta “abstract” 2-abstract non può essere istanziata

Una class astratta è una class dichiarata astratta – può includere o meno metodi astratti. Le classi astratte non possono essere istanziate, ma possono essere sottoclassate.

In altre parole, una class dichiarata con una parola chiave astratta, è nota come class astratta in java. Può avere metodi astratti (metodo senza corpo) e non astratti (metodo con corpo).

Nota importante: – Le classi astratte non possono essere utilizzate per creare istanze di oggetti, possono essere utilizzate per creare riferimenti a oggetti, poiché l’approccio di Java al Polymorphism di runtime viene implementato mediante l’uso di riferimenti a superclass. Pertanto, deve essere ansible creare un riferimento a una class astratta in modo che possa essere utilizzato per puntare a un object sottoclass. Vedrai questa funzione nell’esempio seguente

 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(); } } 

Membri della class

Una class astratta può avere campi statici e metodi statici. Puoi usare questi membri statici con un riferimento di class (ad esempio, AbstractClass.staticMethod ()) come faresti con qualsiasi altra class.

Non dimenticarlo.

Una class astratta è una class che non è completamente implementata ma fornisce qualcosa di un progetto per sottoclassi. Può essere parzialmente implementato in quanto contiene metodi concreti completamente definiti, ma può anche contenere metodi astratti. Questi sono metodi con una firma ma nessun corpo del metodo. Qualsiasi sottoclass deve definire un corpo per ogni metodo astratto, altrimenti deve essere dichiarato astratto. Poiché le classi astratte non possono essere istanziate, devono essere estese da almeno una sottoclass per poter essere utilizzate. Pensa alla class astratta come alla class generica e le sottoclassi sono lì per riempire le informazioni mancanti.