public class DemoSolido {
    interface SolidoMisurabile {
        double volume();
        double superficie();
    }

    static abstract class Solido implements SolidoMisurabile {
        private final double densita;

        protected Solido(double densita) {
            if (!Double.isFinite(densita) || densita <= 0) {
                throw new IllegalArgumentException("densità non valida");
            }
            this.densita = densita;
        }

        public final double massa() {
            return densita * volume();
        }
    }

    static final class Cubo extends Solido {
        private final double lato;

        Cubo(double lato, double densita) {
            super(densita);
            if (!Double.isFinite(lato) || lato <= 0) {
                throw new IllegalArgumentException("lato non valido");
            }
            this.lato = lato;
        }

        @Override
        public double volume() {
            return lato * lato * lato;
        }

        @Override
        public double superficie() {
            return 6 * lato * lato;
        }
    }

    public static void main(String[] args) {
        Cubo cubo = new Cubo(2, 3);
        SolidoMisurabile misurabile = cubo;
        System.out.println(misurabile.volume());
        System.out.println(misurabile.superficie());
        System.out.println(cubo.massa());
    }
}
