Na opnião de vocês qual a diferença entre sealed class e sealed trait?

32 views
Skip to first unread message

Paulo Sales

unread,
Apr 5, 2016, 12:58:04 AM4/5/16
to scaladores
Eae galera,

Gostaria de saber a opnião de vocês sobre a diferença entre:

sealed class Sealing


sealed trait Sealing

Eu li um pouco a respeito e tem umas opniões dizendo ser a mesma coisa e outras que possuem suas particularidades. Queria saber q cês axa?

Além claro da diferença entre um class e um trait, claro! :)

Abs.

Maurício Szabo

unread,
Apr 5, 2016, 11:42:21 AM4/5/16
to scala...@googlegroups.com
Antes de mais nada rs:

Disclaimer - eu sou um programador Ruby e Clojure. Não sou de Scala nem de linguagens estáticamente tipadas.

Sabendo disso, essa é minha opinião que, por não ser de (não programar, nem me identificar muito com) linguagens estáticas, talvez eu esteja perdendo algum ponto crucial na forma de abstração, ou algum ponto importante nesses conceitos. Mas vamos lá:

Eu, particularmente não gosto muito do conceito do sealed. Eu acho que limita coisas que o programador final pode fazer. Eu prefiro deixar as coisas sempre possíveis de serem extensíveis ao extremo, mesmo que isso possa quebrar minha abstração - acho que esse tipo de decisão não é do desenvolvedor de APIs, e sim do programador final. Eu também sei que os programadores normalmente não tomam decisões corretas - inclusive, estou meio que saindo do mundo de Ruby por esse motivo - muitos dos códigos que eu peguei pra dar manutenção estão simplesmente ilegíveis e funcionam provavelmente porque a fé do programador original é muito boa (sério, nada me fez acreditar tanto em poder da fé como certos códigos Ruby que eu peguei hahahaha). Mas, chega de alfinetadas rs.

Sealed traits só podem ser extendidas no arquivo que foram definidas. Sealed classes, não podem ser extendidas nunca. Isso significa que se você tem uma classe selada, você pode garantir que ninguém vai extendê-la. Isso garante, por exemplo, que ninguém vai passar uma subclasse da sua classe pra algum método bizarro, que vai fazer sua classe se comportar de forma inesperada:

sealed class Ratio(val num: Int, val den: Int) {
 require( den != 0)
}  

// Em algum lugar no espaço...
def resolve(r: Ratio) = r.num / BigDecimal(r.den)


Por exemplo:

scala> class Foo extends BigDecimal
<console>:7: error: illegal inheritance from final class BigDecimal
      class Foo extends BigDecimal


Agora, se não fosse selada, olha o que pode acontecer:
class Ratio(val num: int, val den: int) {
 require( den != 0)
}

// Em algum lugar no espaço...
def resolve(r: Ratio) = r.num / BigDecimal(r.den)

// Em outro lugar...
class WrongRatio(num: Int, _den: Int) extends Ratio(num, -1) {
 override val den = _den  
}  

resolve(new WrongRatio(10, 0)) // !BANG!


Dahora a vida, consegui montar um código inseguro, falho, e com uma feature que eu não concordo hahahaha. Mas enfim :D 

E Sealed Traits é mais quando você quer fazer um pattern match, e não quer que ele falhe nunca. Por exemplo, quero escrever uma árvore binária (que só tem duas possibilidade: Empty e Node) e não quero que ninguém venha com idéia de colocar um "AlmostEmpty", ou "OnlyOneChild" hahahhaa. Aí você cria sua trait e suas classes assim:

sealed trait Tree
case object Empty extends Tree
case class Node(value: Int, left: Tree, right: Tree) extends Tree

def insert(tree: Tree, value: Int): Tree = tree match {
 case Empty => Node(value, Empty, Empty)
 case Node(oldValue, left, right) if(value < oldValue) => Node(oldValue, insert(left, value), right)
 case Node(oldValue, left, right) => Node(oldValue, left, insert(right, value))
}

def toList(tree: Tree): List[Int] = tree match {
 case Empty => Nil
 case Node(value, left, right) => toList(left) ++ List(value) ++ toList(right)
}

val tree = List(10, 2, 5, 60, 4, 9, 7).foldLeft(Empty: Tree)(insert)
toList(tree) // => List[Int] = List(2, 4, 5, 7, 9, 10, 60)


Assim, você garante que só tem duas implementações da trait "Tree". 

(nota mental: espero que você não precise entregar um trabalho pra semana que vem sobre "árvores binárias", senão acabei de ter dar a resposta sem nem pensar rs)

---
A question that sometimes drives me hazy: am I or are the others crazy?
(Albert Einstein)

Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction. 
(E. F. Schumacher)

It seems to me that measuring maturity is a very immature thing to do. Teens talk about their maturity, adults don't.
(Robert Martin)

Apenas peixes mortos nadam a favor da maré 
(Malcolm Muggeridge)

--
You received this message because you are subscribed to the Google Groups "scaladores" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scaladores+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Pedro Matiello

unread,
Apr 5, 2016, 11:05:39 PM4/5/16
to scaladores
Complementando a resposta do Mauricio: um efeito interessante da keyword sealed é que o compilador vai te avisar quando você fizer um pattern matching que não contemple todos os casos da classe ou trait sealed. Por exemplo:

trait OpenTrait
sealed trait SealedTrait

class Open1 extends OpenTrait
class Open2 extends OpenTrait

class Sealed1 extends SealedTrait
class Sealed2 extends SealedTrait

def matchOpen(x: OpenTrait) = x match { // Nenhum warning aqui.
  case _:Open1 => "Open1"
}

def matchSealed(x: SealedTrait) = x match {   // Warning: match may not be exhaustive.
  case _:Sealed1 => "Sealed1"
}

O mesmo warning é produzido quando você faz pattern matching em um objeto do tipo Option (sealed class) sem considerar um dos casos possíveis: Some ou None.

Acho sensato que o default do Scala para classes e traits seja não-sealed, mas é um recurso válido para conseguir um código mais seguro em alguns casos.

Paulo Sales

unread,
Apr 6, 2016, 12:55:29 AM4/6/16
to scaladores
Sacaladores, boa noite!!!

Sensacional a resposta de vocês!! Demais!! :D

Maurício!!!

Boa, eu também participei de um projeto Ruby com(on) Rails e me sei do que você está falando e dei uma fuçada no Clojure, me fascinou muito, vou continuar os estudos, gratidão pela bela resposta!! Ahhh, demais o exemplo da árvore binária!! rs

Pedro!!!

Excelente explicação, muito útil essa funcionalidade se usada com sabedoria, gratidão por compartilhar!! Ahhh, ouvi dizer que existe um warnnig para implicit que não está importada no arquivo, ougo assim, mas não entendi direito. Bom, isso é conversa pra outro post... valew

Abs a todos excelente noite à todos.

Rodolfo Ferreira

unread,
Apr 6, 2016, 5:33:20 AM4/6/16
to scala...@googlegroups.com
Para posteridade, tem um artigo bem útil que costumo recomendar sobre sealed.


Bons estudos!

Rodolfo Ferreira

Paulo Sales

unread,
Apr 13, 2016, 7:07:29 PM4/13/16
to scaladores
Obrigado Rodolfo!!

Logo mais vou ler esse post!!

Valewww!!
Reply all
Reply to author
Forward
0 new messages