Menu
Coddy logo textTech

Classi e metodi astratti

Fa parte della sezione Programmazione orientata agli oggetti del percorso Java di Coddy. Lezione 32 di 87.

A volte vuoi definire una classe che funga da modello, ma che non dovrebbe mai essere istanziata direttamente. Per esempio, una classe generica Shape ha senso come classe genitore, ma che aspetto avrebbe una «forma» senza una forma specifica? È qui che entrano in gioco le classi astratte.

Una classe astratta viene dichiarata con la parola chiave abstract e non può essere istanziata. Può contenere sia metodi normali con implementazioni sia metodi astratti senza corpo:

public abstract class Shape {
    protected String color;
    
    public Shape(String color) {
        this.color = color;
    }
    
    // Metodo astratto - senza implementazione
    public abstract double getArea();
    
    // Metodo normale - con implementazione
    public String getColor() {
        return color;
    }
}

I metodi astratti dichiarano cosa deve fare una sottoclasse, ma non come. Qualsiasi classe non astratta che estende una classe astratta deve fornire implementazioni per tutti i metodi astratti:

public class Circle extends Shape {
    private double radius;
    
    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

Puoi comunque usare le classi astratte come tipi di riferimento, abilitando il polimorfismo:

Shape shape = new Circle("red", 5.0);
System.out.println(shape.getArea());  // Chiama l'implementazione di Circle

Le classi astratte sono ideali quando le sottoclassi condividono codice comune, ma devono implementare determinati comportamenti in modo diverso. Impongono un contratto consentendo al contempo il riutilizzo del codice.

challenge icon

Sfida

Facile

Creiamo un sistema di elettrodomestici che dimostri la potenza delle classi astratte. Creerai una classe base Appliance che definisce cosa deve fare ogni elettrodomestico, lasciando ai tipi specifici di elettrodomestico la decisione su come farlo esattamente.

Organizzerai il codice in quattro file:

  • Appliance.java: crea una classe astratta che funge da modello per tutti gli elettrodomestici. Ogni elettrodomestico ha un campo brand (String) e un campo wattage (int). Includi un costruttore che inizializzi entrambi i campi, metodi getter per ciascuno e un metodo normale getInfo() che restituisca: [brand] - [wattage]W. Definisci un metodo astratto operate() che le sottoclassi devono implementare: rappresenta il modo in cui ogni elettrodomestico svolge la propria funzione principale.
  • WashingMachine.java: crea una classe concreta che estende Appliance. Le lavatrici hanno un campo aggiuntivo capacity (int) che rappresenta la capacità di carico in kg. Usa super per gestire l'inizializzazione della classe genitore. Implementa il metodo operate() per stampare: [brand] washing machine is washing [capacity]kg of clothes
  • Microwave.java: crea un'altra classe concreta che estende Appliance. I microonde hanno un campo power (int) che rappresenta la percentuale del livello di potenza. Implementa operate() per stampare: [brand] microwave is heating at [power]% power
  • Main.java: unisci tutti gli elementi usando il polimorfismo. Riceverai cinque input: il nome di una marca, la potenza in watt, la capacità della lavatrice, un altro nome di marca e il livello di potenza del microonde. Crea una WashingMachine e un Microwave, quindi memorizzali in un array di riferimenti Appliance. Scorri l'array e, per ogni elettrodomestico, stampa le sue informazioni usando getInfo(), quindi chiama operate().

Riceverai cinque input in questo ordine: prima marca (String), prima potenza in watt (int), capacità in kg (int), seconda marca (String) e livello di potenza (int).

L'output dovrebbe mostrare quattro righe: per ogni elettrodomestico, vedrai la riga con le sue informazioni seguita dal comportamento operativo. Nota come la classe astratta ti permetta di trattare diversi elettrodomestici in modo uniforme, mentre ognuno funziona a modo suo!

Provalo tu

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Leggi gli input
        String brand1 = scanner.nextLine();
        int wattage1 = scanner.nextInt();
        int capacity = scanner.nextInt();
        scanner.nextLine(); // consuma il carattere di nuova riga
        String brand2 = scanner.nextLine();
        int power = scanner.nextInt();
        
        // TODO: Crea un oggetto WashingMachine con brand1, wattage1 e capacity
        
        // TODO: Crea un oggetto Microwave con brand2, wattage1 (o un wattage appropriato) e power
        
        // TODO: Crea un array di riferimenti ad Appliance e memorizza entrambi gli oggetti
        
        // TODO: Scorri l'array e, per ogni elettrodomestico:
        // - Stampa le sue informazioni usando getInfo()
        // - Chiama operate()
    }
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Java online