gianluca.aguzzi@unibo.it
angelo.filaseta@unibo.it
Questo materiale è ampiamente basato su quello realizzato dai Prof. Mirko Viroli e Roberto Casadei, che ringrazio.
Ogni errore riscontratovi è esclusiva responsabilità degli autori di questo documento.
static
main
dal quale parte un programma Javajava.util.Arrays.toString()
(ossia, il metodo toString
nella classe Arrays
dentro al package java.util
)java.lang.System.out
java.lang.System.getProperty()
Classe.metodo(argomenti)
, e Classe.campo
it.unibo.students
), metodi (getName
) e campi (firstName
)Student
)
C
?C
C
C
” (cf. reflection)class Point3D { // dichiarazione classe
double x; // 3 campi
double y;
double z;
void build(double a, double b, double c) {
this.x = a;
this.y = b;
this.z = c;
}
double getModule() {
return this.x * this.x + this.y * this.y + this.z * this.z;
}
static Point3D ZERO = new Point3D(); // 0,0,0
static Point3D max(Point3D[] ps) { // metodo statico
Point3D max = ZERO; // ricerca max
for (Point3D elem : ps) {
if (elem.getModule() > max.getModule()) {
max = elem;
}
}
return max;
}
}
class UsePoint3D {
public static void main(String[] s) {
// creo e inizializzo vari punti
Point3D p1 = new Point3D();
p1.build(10, 20, 30);
Point3D p2 = new Point3D();
p2.build(5, 6, 7);
Point3D p3 = new Point3D();
p3.build(100, 100, 100);
Point3D p4 = Point3D.ZERO; // questo è lo zero
// costruisco l'array
Point3D[] array = new Point3D[] { p1, p2, p3, p4 };
// calcolo il max
Point3D max = Point3D.max(array);
// stampo
System.out.println("Max: " + max.x + "," + max.y + "," + max.z);
}
}
build
è sempre chiamata su un oggetto, ossia su: new Point3D()
zero
e max
sono chiamate sulla classe Point3D
max
è una funzionalità sui Point3D
, quindi è naturale includerla nella classe Point3D
, ma non è inquadrabile come funzionalità di un singolo oggetto (ognuno darebbe la stessa risposta)zero
è trattato come “costante”, quindi non è proprietà di un oggettoclass Point3DBis { // dichiarazione classe
double x; // 3 campi
double y;
double z;
Point3DBis build(double a, double b, double c) { // build con ritorno
this.x = a;
this.y = b;
this.z = c;
return this;
}
double getModule() {
return this.x * this.x + this.y * this.y + this.z * this.z;
}
static Point3DBis ZERO = new Point3DBis().build(0, 0, 0);
static Point3DBis max(Point3DBis[] ps) { // metodo statico
Point3DBis max = ZERO; // ricerca max
for (Point3DBis elem : ps) {
if (elem.getModule() > max.getModule()) {
max = elem;
}
}
return max;
}
}
class UsePoint3DBis {
public static void main(String[] s) {
// creo vari punti
Point3DBis p1 = new Point3DBis().build(10, 20, 30);
Point3DBis p2 = new Point3DBis().build(5, 6, 7);
Point3DBis p3 = new Point3DBis().build(100, 100, 100);
Point3DBis p4 = Point3DBis.ZERO; // questo è lo zero
// costruisco l'array
Point3DBis[] array = new Point3DBis[] { p1, p2, p3, p4 };
// calcolo il max
Point3DBis max = Point3DBis.max(array);
// stampo
System.out.println("Max: " + max.x + "," + max.y + "," + max.z);
}
}
build
this
static
static
dalle altre (poi vedremo “pattern” più sofisticati)C
è una classe usata per generare oggetti, la classe Cs
(plurale) conterrà solo proprietà statiche relativeObject
/Objects
, Array
/Arrays
, Collection
/Collections
Point3D
// Classe Point3D con solo membri d'istanza (non-static)
class Point3D { // dichiarazione classe
double x; // 3 campi
double y;
double z;
Point3D build(double a, double b, double c) {
this.x = a;
this.y = b;
this.z = c;
return this;
}
double getModule() {
return this.x * this.x + this.y * this.y + this.z * this.z;
}
}
Points
class Points { // Modulo con funzionalità per punti
static Point3D zero = new Point3D().build(0, 0, 0);
static Point3D max(Point3D[] ps) { // metodo statico
Point3D max = zero; // ricerca max
for (Point3D elem : ps) {
if (elem.getModule() > max.getModule()) {
max = elem;
}
}
return max;
}
}
Point3D
e Points
class UsePoint3D {
public static void main(String[] s) {
// creo e inizializzo vari punti
Point3D p1 = new Point3D().build(10, 20, 30);
Point3D p2 = new Point3D().build(5, 6, 7);
Point3D p3 = new Point3D().build(100, 100, 100);
Point3D p4 = Points.zero; // questo è lo zero
// costruisco l'array
Point3D[] array = new Point3D[] { p1, p2, p3, p4 };
// calcolo il max
Point3D max = Points.max(array);
// stampo
System.out.println("Max: " + max.x + "," + max.y + "," + max.z);
}
}
new
new T
crea un oggetto di tipo T
inizializzando tutti i suoi campi al loro valore di default (p.e. $0$ per i numeri), e ne restituisce il riferimentoPoint3D p = new Point3D();
Point3D[] ps = new Point3D[2]; // [null, null]
new
si possono quindi passare dei valorinew Point3D()
public class Point3Dcons { // dichiarazione classe
double x;
double y;
double z;
// costruttore
Point3Dcons(double inx,double iny,double inz){ // nota: assenza di tipo di ritorno
this.x = inx; // metto l'argomento inx in this.x
this.y = iny; // ..
this.z = inz; // ..
}
public static void main(String[] args){
// creo l'oggetto usando il costruttore a tre argomenti
Point3Dcons p = new Point3Dcons(10.0, 20.0, 30.0);
// stampo
System.out.println("p: " + p.x + "," + p.y + "," + p.z);
// costruttore di "default" in questo caso non funziona!
// Point3D p2 = new Point3D(); NO!!
}
}
class Point3Dvar { // dichiarazione classe
double x;
double y;
double z;
Point3Dvar(double x, double y, double z){ // costruttore
this.x = x; // metto l'argomento x in this.x
this.y = y; // ..
this.z = z; // ..
}
// ...
public static void main(String[] args){
//creo l'oggetto usando il costruttore a tre argomenti
Point3Dvar p = new Point3Dvar(10.0, 20.0, 30.0);
// stampo
System.out.println("p: " + p.x + "," + p.y + "," + p.z);
}
}
import java.util.Calendar;
public class Person { // dichiarazione classe
String name;
int birthYear;
boolean isMarried;
Person(String nome) {
this.name = nome;
this.birthYear = Person.currentYear;
this.isMarried = false;
}
Person(String nome, int annoNascita) {
this.name = nome;
this.birthYear = annoNascita;
this.isMarried = false;
}
Person(String nome, int annoNascita, boolean sposato) {
this.name = nome;
this.birthYear = annoNascita;
this.isMarried = sposato;
}
static int currentYear = Calendar.getInstance().get(Calendar.YEAR);
}
public class UsePerson {
public static void main(String[] s) {
// Person p1 = new Person(); NO!!
Person p2 = new Person("Mario Rossi");
Person p3 = new Person("Gino Bianchi", 1979);
Person p4 = new Person("Carlo Verdi", 1971, true);
Person[] persone = new Person[]{ p2, p3, p4 };
for(int i=0; i < persone.length; i++){
System.out.println(persone[i].name + ", nato/a nel " + persone[i].birthYear +
(persone[i].isMarried ? "" : ", non") + " è sposato/a.");
}
}
}
new
this
punta all’oggetto creato)new
restituisce il riferimento this
this(..)
import java.util.Calendar;
class Person2 { // dichiarazione classe
String name;
int birthYear;
boolean isMarried;
Person2(String nome, int yearOfBirth, boolean isMarried) { // costruttore completo
this.name = nome;
this.birthYear = yearOfBirth;
this.isMarried = isMarried;
}
Person2(String name, int birthYear) { // richiama costruttore a 3 arg..
this(name, birthYear, false);
}
Person2(String name) {
this(name, Person2.CURRENT_YEAR); // richiama costruttore a 2 arg..
}
static int CURRENT_YEAR = Calendar.getInstance().get(Calendar.YEAR);
}
+
) e overloading costruttoriData una new
, quale costruttore richiamerà? (JLS 15.12)
class ExampleOverloading {
static int m(double a, int b) { return 1; }
static int m(int a, double b) { return 2; }
static int m2(double a, double b) { return 1; }
static int m2(int a, int b) { return 2; }
public static void main(String[] s) {
// System.out.println(""+m(1, 1)); // ERROR: reference to m is AMBIGUOUS
// System.out.println(""+m(1.5, 1.5)); // ERROR: no suitable method found for m(Double,Double)
System.out.println("" + m(1.5, 1));
System.out.println("" + m((float)1, 1));
System.out.println("" + m(1, 1.5));
System.out.println("" + m2(1.5, 1.5)); // 1
System.out.println("" + m2(1, 1)); // 2
}
}
n1.n2....nj
(p.e. java.lang
)n1/n2/../nj
a partire da una delle directory presenti nella variabile d’ambiente CLASSPATH
.java
) deve specificare il suo packagepackage pname;
new
o come tipo) specificando anche il package (p.e. new java.util.Date()
)import java.util.*;
importa tutte le classi di java.util
import java.util.Date;
importa la sola java.util.Date
javac
.java
public
e private
public
– visibile da tutte le classipublic
private
– visibile solo nella classe correnteprivate
public
.java
public
/private
può consentire di gestire a piacimento il concetto di information hiding, come approfondiremo la prossima settimanafinal
final
= non modificabilepublic static final int CONST=10;
public
, si ha la garanzia che nessuno le modifichipublic class MagicExample {
// Put 100 into a constant and give it a name!!
private static final int SIZE = 100;
public static void main(String[] s) {
double[] array = new double[SIZE];
double sum = 0;
for (int i = 0; i < SIZE; i++) {
// Assegno un numero random
array[i] = Math.random();
sum = sum + array[i];
}
System.out.println("Somma " + sum);
}
}
GuessMyNumberApp
revisitedimport java.util.Random;
public class GuessMyNumberApp {
public static final int ATTEMPTS = 10;
public static final int MAX_GUESS = 100;
public static final int MIN_GUESS = 1;
public static void main(String[] args) {
int number = new Random().nextInt(MAX_GUESS - MIN_GUESS) + MIN_GUESS;
for (int i = 1; i <= ATTEMPTS; i++){
System.out.println("Attempt no. "+i);
System.out.println("Insert your guess.. ");
int guess = Integer.parseInt(System.console().readLine());
if (guess == number){
System.out.println("You won!!");
return;
} else if (guess > number){
System.out.println("Your guess is greater..");
} else {
System.out.println("Your guess is lower..");
}
}
System.out.println("Sorry, you lost!");
}
}
new
malloc
del Cnew
chiama il gestore della memoria, che alloca lo spazio necessariofree
del C) senza che il programmatore debba occuparsenepublic class GC {
private static long size = 1000;
public static void main(String[] s) {
// Runtime dà info sull'esecuzione
Runtime r = Runtime.getRuntime();
// Creo oggetti all'infinito
for (long l = 0; true; l++) {
new Object();
// Stampo solo ogni tanto
if (l % size == 0) {
System.out.print("Objs (*10^6): " + l / 1000000);
System.out.println(" Freemem (MB):" + (r.freeMemory() >> 20));
}
// La memoria libera si vedrà calare lentamente
// e poi riprendersi di colpo, ciclicamente
}
}
}
Mandelbrot
Data una semplice classe Picture
che gestisce gli aspetti grafici, realizzare una applicazione che disegna il frattale Mandelbrot.
Picture
– codice non comprensibile ora
void drawPixel(int x,int y,int color)
Complex
modella numeri complessi e operazioni baseMandelbrot
si occupa di calcolare il valore di ogni punto del rettangolo
void advancePosition()
passa al prossimo puntoboolean isCompleted()
dice se ci sono altri punti da calcolareint computeIteratrions()
dice quante iterazioni vengono calcolate per il punto correnteMandelbrotApp
ha il solo main
Complex
public class Complex {
double re;
double im;
Complex(double re, double im) {
this.re = re;
this.im = im;
}
double getScalarProduct(){
return this.re * this.re + this.im * this.im;
}
// Crea un nuovo complesso, sommando this a c
Complex sum(Complex c){
return new Complex(this.re + c.re, this.im + c.im);
}
// Crea un nuovo complesso, moltiplicando this a c
Complex times(Complex c){
return new Complex(this.re * c.re - this.im * c.im,
c.re * this.im + c.im * this.re);
}
}
Mandelbrot
public class Mandelbrot {
static final double MAX_PRODUCT = 4.0;
int width, height, x, y; // uno per linea di norma
double minx, maxx, miny, maxy, maxIter; // uno per linea di norma
Mandelbrot(int width, int height, double minx, double maxx,
double miny, double maxy, int maxIter) {
this.width = width; this.height = height;
this.minx = minx; this.maxx = maxx;
this.miny = miny; this.maxy = maxy; this.maxIter = maxIter;
}
void advancePosition(){
x = (x + 1) % width;
y = y + (x == 0 ? 1 : 0);
}
boolean isCompleted(){ return y == height; }
int computeIterations(){
Complex c0 = new Complex(this.minx + (this.maxx - this.minx) * x / width,
this.miny + (this.maxy - this.miny) * y / height);
Complex c = c0;
int iter;
for (iter = 0; c.getScalarProduct() < MAX_PRODUCT && iter < this.maxIter; iter++) {
c = c.times(c).sum(c0); // c = c*c + c0
}
return iter;
}
}
MandelbrotApp
public class MandelbrotApp {
public static final int WIDTH = 800;
public static final int HEIGHT = 800;
public static final double MINX = -1.5;
public static final double MAXX = 0.5;
public static final double MINY = -1.0;
public static final double MAXY = 1.0;
public static final int MAX_ITER = 32;
public static int greyColorFromIterations(int iter, int maxIter){
if (iter == MAX_ITER) { return 0; } // Out of Mandelbrot set
iter = 255-iter*(256/MAX_ITER); // 255,254,..,0 colors
return iter | iter << 8 | iter << 16; // as grey
}
public static void main(String[] s){
Mandelbrot mb = new Mandelbrot(WIDTH,HEIGHT,MINX,MAXX,MINY,MAXY,MAX_ITER);
Picture p = new Picture(WIDTH,HEIGHT);
while (!mb.isCompleted()){
int iter = mb.computeIterations();
int color = greyColorFromIterations(iter,MAX_ITER);
p.drawPixel(mb.x, mb.y, color);
mb.advancePosition();
} } }