------------------------------------------- Classi case ___________________________________________ scala> case class Punto(x:Int,y:Int) defined class Punto scala> Punto(2,5) res0: Punto = Punto(2,5) scala> List(3,9) res1: List[Int] = List(3, 9) scala> val p = Punto(4,9) p: Punto = Punto(4,9) scala> p.x res2: Int = 4 scala> p.y res3: Int = 9 scala> def f(p:Punto) = p match { | case Punto(0,0) => println("0|0") | case Punto(a,b) => println(a+"|"+b) | } f: (p: Punto)Unit scala> f(p) 4|9 scala> f(Punto(0,0)) 0|0 scala> case class Persona(nome:String) defined class Persona scala> val t = Persona("Francesca") t: Persona = Persona(Francesca) scala> t res6: Persona = Persona(Francesca) scala> t.nome res7: String = Francesca scala> println(t) Persona(Francesca) scala> Persona("Paola") == Persona("Pa"+"ola") res9: Boolean = true scala> Persona("Paola") == Persona("Pa"+"olo") res10: Boolean = false scala> t.hashCode res11: Int = 297619854 ___________________________________________ ------------------------------------------- Gerarchie di classi sealed e classi abstract -- Versione Scala -- Albero.scala: (12 LoC - Lines of Code) ___________________________________________ sealed abstract class Albero { def numNodi:Int = this match { case AlberoVuoto() => 0 case AlberoPieno(l,_,r) => 1 + l.numNodi + r.numNodi } override def toString:String = this match { case AlberoVuoto() => "." case AlberoPieno(l,q,r) => "(" + l.toString + " " + q + " " + r.toString + ")" } } case class AlberoVuoto() extends Albero case class AlberoPieno(l:Albero, t:Int, r:Albero) extends Albero ___________________________________________ AlberoMain.scala: ___________________________________________ object AlberoMain extends App { val e = AlberoVuoto() val t1 = AlberoPieno(e, 10, e) val t2 = AlberoPieno(t1, 5, e) val t3 = AlberoPieno(t2, 9, t1) println(t3.numNodi) println(t3) } ___________________________________________ -- Versione Java -- Albero.java: (61 LoC - Lines of Code, contro i 12 LoC della versione Scala) ___________________________________________ abstract class Albero { public abstract boolean isEmpty(); public abstract int numNodi(); } class AlberoVuoto extends Albero { @Override public boolean isEmpty() { return true; } @Override public int numNodi() { return 0; } @Override public boolean equals(Object other) { if (other.getClass() != this.getClass()) return false; return true; } @Override public String toString() { return "."; } } class AlberoPieno extends Albero { public Albero l, r; public int root; public AlberoPieno(Albero l, int root, Albero r) { this.l = l; this.root = root; this.r = r; } @Override public boolean isEmpty() { return false; } @Override public int numNodi() { return 1 + l.numNodi() + r.numNodi(); } @Override public boolean equals(Object other) { if (other.getClass() != this.getClass()) return false; AlberoPieno t = (AlberoPieno)other; // downcasting return t.r.equals(r) && t.root == root && t.l.equals(l); } @Override public String toString() { return "(" + l.toString() + " " + root + " " + r.toString() + ")"; } } ___________________________________________ AlberoMain.java: ___________________________________________ class AlberoMain { public static void main(String[] args) { Albero e = new AlberoVuoto(); Albero t1 = new AlberoPieno(e, 10, e); Albero t2 = new AlberoPieno(t1, 5, e); Albero t3 = new AlberoPieno(t2, 9, t1); System.out.println(t3.numNodi()); System.out.println(t3); } } ___________________________________________ Si noti come nella versione Scala le funzionalità (numNodi, toString) sono implementate nella classe base Albero, mentre in quella Java nelle classi derivate sfruttando il polimorfismo. Il metodo equals è generato automaticamente in Scala, mentre in Java va codificato esplicitamente. Complessivamente, il codice Scala è molto più compatto. ------------------------------------------- Soluzione esercizio 17 (https://season-lab.github.io/PFP/eserc/esercScala) ___________________________________________ object Sqrt extends App { def sqrt(x:Double) = { val eps = 0.0001 def abs(x:Double) = if (x<0) -x else x def itera(y:Double):Double = if (abs(y-x/y) < eps) y else itera((y+x/y)/2) itera(1) } println("Radice quadrata di 2 ~ "+sqrt(2)) println("Radice quadrata di 64 ~ "+sqrt(64)) } ___________________________________________