From 353d81fe1840dad3966bf244f5737f02eb90f338 Mon Sep 17 00:00:00 2001 From: EliasAAradsson Date: Sun, 17 Nov 2024 13:51:30 +0100 Subject: [PATCH 1/9] Fix typo --- compendium/modules/w10-inheritance-lab.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compendium/modules/w10-inheritance-lab.tex b/compendium/modules/w10-inheritance-lab.tex index e6241ad2..7879e76d 100644 --- a/compendium/modules/w10-inheritance-lab.tex +++ b/compendium/modules/w10-inheritance-lab.tex @@ -336,7 +336,7 @@ \subsection{Tips och förslag}\label{lab:snake:tips} \item Diskutera i gruppen om alla har kunskaper nog för att köra git och github, samt för- och nackdelar med det. \item Om inte alla är bekväma med git och github så överväg om ni vill göra manuell versionshantering med kopiering av nya filer via USB-minne, ssh eller upp- och nedladdning via molnlagring. Efter en konkret upplevelse av manuell versionshantering så får du en djupare förståelse för behovet av verktygsstöd för versionshantering och det blir extra motiverande att lära sig git. \item Diskutera arbetssätt. Hur ska ni använda github issues, git branch, etc? Eller ska alla pusha till main branch? Ska ni använda github pull requests, github reviews, etc.? - \item Kolla så att du har en \texttt{.gitignore} innan du gör push, så att inte t.ex. maskinkodsfiler hamnar i ert repo, vilket kan medföra kenpigt städjobb och onödiga merge-konflikter. Exempel på en lämplig \code{.gitignore} finns här: \\\url{https://github.com/lunduniversity/introprog/blob/master/workspace/w10_snake/.gitignore} + \item Kolla så att du har en \texttt{.gitignore} innan du gör push, så att inte t.ex. maskinkodsfiler hamnar i ert repo, vilket kan medföra knepigt städjobb och onödiga merge-konflikter. Exempel på en lämplig \code{.gitignore} finns här: \\\url{https://github.com/lunduniversity/introprog/blob/master/workspace/w10_snake/.gitignore} \item \textbf{Var noga med att göra ert github-repo privat!} Det är inte tillåtet att dela labblösningar på internet -- då kan du efter disciplinärende dömas som skyldig till medhjälp till fusk och du kan bli avstängd från dina studier. \end{itemize} From 5418614172699d40956b06a00ba4663d45f513c5 Mon Sep 17 00:00:00 2001 From: bjornregnell Date: Mon, 18 Nov 2024 10:54:35 +0100 Subject: [PATCH 2/9] update slides w10, use case class, remove new, etc --- slides/body/lect-w10-extends.tex | 44 ++++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/slides/body/lect-w10-extends.tex b/slides/body/lect-w10-extends.tex index 368d2af6..fc2a82c7 100644 --- a/slides/body/lect-w10-extends.tex +++ b/slides/body/lect-w10-extends.tex @@ -190,18 +190,18 @@ \begin{Slide}{Behovet av gemensam bastyp}\SlideFontSmall \begin{REPLsmall} -scala> class Gurka(val vikt: Int) +scala> case class Gurka(vikt: Int) -scala> class Tomat(val vikt: Int) +scala> case class Tomat(vikt: Int) -scala> val gurkor = Vector(new Gurka(200), new Gurka(300)) -gurkor: Vector[Gurka] = Vector(Gurka@60856961, Gurka@2fd953a6) +scala> val gurkor = Vector(Gurka(200), Gurka(300)) +val gurkor: Vector[Gurka] = Vector(Gurka(200), Gurka(300)) scala> gurkor.map(_.vikt) res0: Vector[Int] = Vector(200, 300) -scala> val grönsaker = Vector(new Gurka(200), new Tomat(42)) -val grönsaker: Vector[Gurka | Tomat] = Vector(Gurka@15f11bfb,Tomat@16a499d1) +scala> val grönsaker = Vector(Gurka(200), Tomat(42)) +val grönsaker: Vector[Gurka | Tomat] = Vector(Gurka(200), Tomat(42)) scala> grönsaker.map(_.vikt) -- [E008] Not Found Error: -------------------------- @@ -214,7 +214,7 @@ \begin{Slide}{Varför syns inte gemensam medlem i en typunion?} \begin{REPLsmall} -scala> val grönsaker = Vector(new Gurka(200), new Tomat(42)) +scala> val grönsaker = Vector(Gurka(200), Tomat(42)) val grönsaker: Vector[Gurka | Tomat] = Vector(Gurka@15f11bfb,Tomat@16a499d1) scala> grönsaker.map(_.vikt) @@ -288,23 +288,23 @@ \begin{REPL} scala> trait Grönsak -scala> class Gurka(val vikt: Int) extends Grönsak +scala> case class Gurka(vikt: Int) extends Grönsak -scala> class Tomat(val vikt: Int) extends Grönsak +scala> case class Tomat(vikt: Int) extends Grönsak -scala> val grönsaker = Vector(new Gurka(200), new Tomat(42)) -grönsaker: Vector[Grönsak] = Vector(Gurka@3dc4ed6f, Tomat@2823b7c5) +scala> val grönsaker = Vector(Gurka(200), Tomat(42)) +val grönsaker: Vector[Grönsak] = Vector(Gurka(200), Tomat(42)) \end{REPL} \pause Men det är ännu \Alert{inte} som vi vill ha det: \begin{REPLnonum} - scala> grönsaker.map(_.vikt) - -- [E008] Not Found Error: -------------------------- - 1 |grönsaker.map(_.vikt) - | ^^^^^^ - | value vikt is not a member of Grönsak +scala> grönsaker.map(_.vikt) +-- [E008] Not Found Error: -------------------------- +1 |grönsaker.map(_.vikt) + | ^^^^^^ + | value vikt is not a member of Grönsak \end{REPLnonum} \end{Slide} @@ -356,14 +356,14 @@ trait Grönsak: val vikt: Int // implementation saknas, inget = -class Gurka(val vikt: Int) extends Grönsak +case class Gurka(vikt: Int) extends Grönsak -class Tomat(val vikt: Int) extends Grönsak +case class Tomat(vikt: Int) extends Grönsak \end{Code} Nu har du explicit sagt till kompilatorn att du vill att alla grönsaker har en vikt: \begin{REPLsmall} -scala> val grönsaker = Vector(new Gurka(200), new Tomat(42)) //funkar även utan new -val grönsaker: Vector[Grönsak] = Vector(Gurka@3dc4ed6f, Tomat@2823b7c5) +scala> val grönsaker = Vector(Gurka(200), Tomat(42)) +val grönsaker: Vector[Grönsak] = Vector(Gurka(200), Tomat(42)) scala> grönsaker.map(_.vikt) val res0: Vector[Int] = Vector(200, 42) @@ -838,13 +838,12 @@ \end{Slide} -\begin{Slide}{Förseglade typer med \texttt{sealed}}\SlideFontSmall +\begin{Slide}{Förseglade typer med \texttt{sealed}}\SlideFontTiny Med en \code{sealed} kan du skapa en \Emph{förseglad} uppräkning: \begin{Code} sealed trait Färg(val toInt: Int) object Färg: val values = Vector(Spader, Hjärter, Ruter, Klöver) - case object Spader extends Färg(0) case object Hjärter extends Färg(1) case object Ruter extends Färg(2) @@ -862,6 +861,7 @@ |It would fail on pattern case: Hjärter, Ruter, Klöver val res0: String = hej \end{REPLsmall} +Använd hellre \code{enum} så får du både \code{sealed} och mer godis på köpet! \end{Slide} From 4cb081d3ea0967e0516006404f4fc25cfa34506b Mon Sep 17 00:00:00 2001 From: bjornregnell Date: Mon, 18 Nov 2024 12:07:34 +0100 Subject: [PATCH 3/9] update structure of slides, tweak subsections w10 --- slides/body/lect-w10-extends.tex | 66 ++++++++++++++++--------------- slides/body/lect-w10-override.tex | 42 ++++++++++---------- 2 files changed, 55 insertions(+), 53 deletions(-) diff --git a/slides/body/lect-w10-extends.tex b/slides/body/lect-w10-extends.tex index fc2a82c7..b5339c5a 100644 --- a/slides/body/lect-w10-extends.tex +++ b/slides/body/lect-w10-extends.tex @@ -279,7 +279,7 @@ - +\Subsection{Bastyp, \texttt{trait}, \texttt{extends}} @@ -616,13 +616,43 @@ \end{Slide} +\Subsection{Subtypspolymorfism och dynamisk bindning} + + +\begin{Slide}{Subtypspolymorfism och dynamisk bindning}\SlideFontTiny +\begin{Code}[basicstyle=\SlideFontSize{6.2}{7.5}\ttfamily\selectfont] +trait Robot { def work(): Unit } + +case class CleaningBot(name: String) extends Robot: + def work(): Unit = println(" Städa Städa") + +case class TalkingBot(name: String) extends Robot: + def work(): Unit = println(" Prata Prata") +\end{Code} +\Emph{Polymorfism} betyder ''många former''. Referenserna r och bot nedan kan ha olika ''former'', d.v.s de kan referera till olika sorters robotar. \\ \Emph{Dynamisk bindning} innebär att körtidstypen avgör vilken metod som körs. +\begin{REPL}[numbers=left, basicstyle=\color{white}\SlideFontSize{6.2}{7.5}\ttfamily\selectfont] +scala> def robotDoWork(bot: Robot) = { print(bot); bot.work() } + +scala> var r: Robot = CleaningBot("Wall-E") + +scala> robotDoWork(r) +CleaningBot(Wall-E) Städa Städa + +scala> r = TalkingBot("C3PO") + +scala> robotDoWork(r) +TalkingBot(C3PO) Prata Prata +\end{REPL} +\end{Slide} + + \ifkompendium -\begin{Slide}{Överskuggning} +\begin{Slide}{Exempel: Överskuggning och \texttt{override}} \vspace{-0.5em}\scalainputlisting[numbers=left,numberstyle=,basicstyle=\fontsize{11}{13}\ttfamily\selectfont]{../compendium/examples/workspace/w07-inherit/src/vego3.scala} \end{Slide} \else -\begin{Slide}{Överskuggning} +\begin{Slide}{Exempel: Överskuggning och \texttt{override}} \SlideFontSmall \vspace{-0.5em}\scalainputlisting[numbers=left,numberstyle=,basicstyle=\fontsize{6}{7.3}\ttfamily\selectfont]{../compendium/examples/workspace/w07-inherit/src/vego3.scala} \end{Slide} \fi @@ -752,32 +782,6 @@ -\begin{Slide}{Terminologi: Polymorfism och dynamisk bindning}\SlideFontTiny -\begin{Code}[basicstyle=\SlideFontSize{6.2}{7.5}\ttfamily\selectfont] -trait Robot { def work(): Unit } - -case class CleaningBot(name: String) extends Robot: - override def work(): Unit = println(" Städa Städa") - -case class TalkingBot(name: String) extends Robot: - override def work(): Unit = println(" Prata Prata") -\end{Code} -\Emph{Polymorfism} betyder ''många former''. Referenserna r och bot nedan kan ha olika ''former'', d.v.s de kan referera till olika sorters robotar. \\ \Emph{Dynamisk bindning} innebär att körtidstypen avgör vilken metod som körs. -\begin{REPL}[numbers=left, basicstyle=\color{white}\SlideFontSize{6.2}{7.5}\ttfamily\selectfont] -scala> def robotDoWork(bot: Robot) = { print(bot); bot.work() } - -scala> var r: Robot = CleaningBot("Wall-E") - -scala> robotDoWork(r) -CleaningBot(Wall-E) Städa Städa - -scala> r = TalkingBot("C3PO") - -scala> robotDoWork(r) -TalkingBot(C3PO) Prata Prata -\end{REPL} -\end{Slide} - \begin{Slide}{Anonym klass}\SlideFontSmall Om man har en abstrakt typ med saknade implementationer kan man fylla i det som fattas i dessa i ett extra block som ''hängs på'' vid instansiering: @@ -881,7 +885,7 @@ scala> object StorGurkan extends Gurka(1000, 1_000_000): // ärv på bäst du vill! override def alternativ = "kan kanske också funka med en betongpelare" \end{REPLsmall} -\item \code{open} krävs om du vill tysta varning vid arv från en annan kodfil. +\item \code{open} krävs om du vill tysta varning vid \Alert{arv från en annan kodfil}. \item Du kan även komma undan varningen med \code{import scala.language.adhocExtensions} \end{itemize} @@ -889,8 +893,6 @@ \end{Slide} -\Subsection{Trait eller abstrakt klass?} - \begin{Slide}{Trait eller abstrakt klass?}\SlideFontSmall Nyckelordet \code{abstract} behövs framför \code{class} om abstrakta medlemmar: \begin{REPLsmall} diff --git a/slides/body/lect-w10-override.tex b/slides/body/lect-w10-override.tex index 9618ac92..2dbb3757 100644 --- a/slides/body/lect-w10-override.tex +++ b/slides/body/lect-w10-override.tex @@ -4,7 +4,7 @@ %%% -\Subsection{Överskuggingsregler, \texttt{override}} +\Subsection{Överskuggningsregler} \begin{Slide}{Medlemmar, arv och överskuggning}\SlideFontTiny \begin{multicols}{2} @@ -117,8 +117,6 @@ \end{Slide} -\Subsection{\texttt{super}} - \begin{Slide}{Att skilja på mitt och ditt med \texttt{super}} \begin{REPL} scala> class X { def gurka = "super pepino" } @@ -180,6 +178,25 @@ \end{Slide} +\begin{Slide}{Fördjupning: Transparent trait}\SlideFontSmall +Du kan göra din trait \Emph{genomskinlig} vid typhärledning av supertypen för inmixningen med nyckelordet \code{transparent}: +\begin{Code} +trait Grönsak(val vikt: Int) +transparent trait HarSmak(val smak: String) + +object Gurka extends Grönsak(42), HarSmak("vattning") +object Tomat extends Grönsak(43), HarSmak("syrlig") +\end{Code} +\begin{REPLnonum} +scala> Vector(Gurka, Tomat) +val res0: Vector[Grönsak] = + Vector(Gurka@560742f7, Tomat@3cc82e23) +\end{REPLnonum} +Vilken typ hade visats utan \code{transparent}? \pause \\ \code{Vector[Grönsak & HarSmak]} +\end{Slide} + + + \begin{Slide}{Fördjupning: Typunioner med eller-operator}\SlideFontSmall Typunioner skapas typ-operatorn \code{|} mellan typer: \begin{REPLsmall} @@ -193,7 +210,7 @@ // defined alias type IntOrErr = Int | String scala> def div(nom: Int, denom: Int): IntOrErr = - if denom != 0 then nom / denom else "div. by zero" + if denom != 0 then nom / denom else "div. by zero" \end{REPLsmall} Fördel jämfört med klass: rudimentärt enkelt.\\ Nackdelar: kan inte deklarera parametrar, medlemmar och allt annat som en klass kan; i viss mån kan detta kompensera med \code{extension} och \code{match}.\\ {\SlideFontTiny Läs mer här: @@ -201,23 +218,6 @@ } \end{Slide} -\begin{Slide}{Fördjupning: Transparent trait}\SlideFontSmall -Du kan göra din trait \Emph{genomskinlig} vid typhärledning av supertypen för inmixningen med nyckelordet \code{transparent}: -\begin{Code} -trait Grönsak(val vikt: Int) -transparent trait HarSmak(val smak: String) - -object Gurka extends Grönsak(42), HarSmak("vattning") -object Tomat extends Grönsak(43), HarSmak("syrlig") -\end{Code} -\begin{REPLnonum} -scala> Vector(Gurka, Tomat) -val res0: Vector[Grönsak] = - Vector(Gurka@560742f7, Tomat@3cc82e23) -\end{REPLnonum} -Vilken typ hade visats utan \code{transparent}? \pause \\ \code{Vector[Grönsak & HarSmak]} -\end{Slide} - \begin{Slide}{Terminologi och nyckelord vid arv} From 8822842ca4affca8ed7b6de43df6f6d61ddb59e5 Mon Sep 17 00:00:00 2001 From: bjornregnell Date: Mon, 18 Nov 2024 12:32:46 +0100 Subject: [PATCH 4/9] more tweaks to slides w10 --- slides/body/lect-w10-extends.tex | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/slides/body/lect-w10-extends.tex b/slides/body/lect-w10-extends.tex index b5339c5a..b5fda19e 100644 --- a/slides/body/lect-w10-extends.tex +++ b/slides/body/lect-w10-extends.tex @@ -40,9 +40,10 @@ \item Klientkod kan \Emph{utvidga} \Eng{extend} ett givet API med egna specifika tillägg. \end{itemize} -\item Man kan använda arv för att deklarera en gemensam \Emph{bastyp} så att generiska samlingar kan ges en mer specifik elementtyp. +\item Man kan använda arv för att deklarera en gemensam \Emph{bastyp} så att variabler och generiska samlingar kan ges en lagom specifik elementtyp. \begin{itemize} -\item Det räcker att man vet bastypen för att kunna anropa gemensamma metoder på alla element i samlingen. +\item Det räcker att man vet bastypen för att kunna nå gemensamma medlemmar för alla element i samlingen. +\item Exempel: Alla grönsaker har en vikt. \end{itemize} \end{itemize} \end{Slide} @@ -74,7 +75,7 @@ \end{tikzpicture} \end{center} -Mer om UML-diagram i senare kurser: pfk, omd.\\ +Mer om UML-diagram i senare kurser.\\ \href{https://en.wikipedia.org/wiki/Class_diagram}{\SlideFontTiny en.wikipedia.org/wiki/Class\_diagram} \end{Slide} @@ -474,11 +475,11 @@ \item den \Emph{kan} innehålla delar som \Emph{saknar implementation} -\item den \Emph{kan mixas} med flera andra traits så att olika koddelar kan återanvändas på flexibla sätt. +\item den \Emph{kan mixas} med flera andra traits så att olika koddelar kan kombineras på flexibla sätt. -\item den \Alert{kan inte} instansieras direkt eftersom den är abstrakt. +\item den \Alert{kan inte} instansieras direkt. -\item Från Scala 3 \Emph{kan} den ha \Emph{parametrar} (precis som klasser). +\item den \Emph{kan} ha \Emph{parametrar}\footnote{I gamla Scala 2 kan traits ej ha parametrar} på samma sätt som klasser. \end{itemize} \end{itemize} @@ -592,6 +593,7 @@ \begin{Slide}{Varför kan kodduplicering orsaka problem?} +\pause \begin{itemize} \item Mer att skriva (inte jättestort problem) \pause From ff67bdd778c1618a8b689e3f2398860b30f744cd Mon Sep 17 00:00:00 2001 From: bjornregnell Date: Mon, 18 Nov 2024 12:43:23 +0100 Subject: [PATCH 5/9] add pointer to open classes, slides w10 --- slides/body/lect-w10-extends.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/slides/body/lect-w10-extends.tex b/slides/body/lect-w10-extends.tex index b5fda19e..a2368e20 100644 --- a/slides/body/lect-w10-extends.tex +++ b/slides/body/lect-w10-extends.tex @@ -716,6 +716,7 @@ \item Om en kodfil bara innehåller \Emph{en enda} klass/trait/singelobjekt ge filen samma namn som innehållet, t.ex. \code{KlassensNamn.scala} \item Om en kodfil innehåller \Emph{flera} saker, döp filen till något som återspeglar hela innehållet och använd \Emph{liten begynnelsebokstav}, t.ex. \code{drawing-utils.scala} eller \code{bastypensNamn.scala} \end{itemize} +\item Scala 3 varnar vid arv utanför samma kodfil (se öppna klasser senare). \end{itemize} \end{Slide} From 77cd791c4bdc166bc343095829f95174a6acd844 Mon Sep 17 00:00:00 2001 From: bjornregnell Date: Tue, 19 Nov 2024 11:06:51 +0100 Subject: [PATCH 6/9] move inspection instructions earlier before guest lecture --- slides/body/lect-w10-assignments.tex | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/slides/body/lect-w10-assignments.tex b/slides/body/lect-w10-assignments.tex index 9425ba18..2fd60985 100644 --- a/slides/body/lect-w10-assignments.tex +++ b/slides/body/lect-w10-assignments.tex @@ -6,6 +6,9 @@ \ifkompendium\else \Subsection{Gäst: Gustaf Lundh, Axis} + +\input{body/lect-w09-inspections-snake.tex} + \begin{Slide}{Gästföreläsning: "Kodgranskningar i praktiken"} Hjärtligt välkommen: \\ \Emph{Gustaf Lundh}, Senior Developer, Axis \end{Slide} @@ -24,6 +27,8 @@ \end{minipage}% \end{Slide} + + \begin{Slide}{Arvshierarki i \texttt{snake}: Olika typer av varelser} \begin{center} \newcommand{\TextBox}[1]{\raisebox{0pt}[1em][0.5em]{#1}} @@ -141,8 +146,6 @@ \end{itemize} \end{Slide} -\input{body/lect-w09-inspections-snake.tex} - \begin{Slide}{Redovisning på obligatorisk schemalagd labbtid} Första \code{snake}-veckan (w10): \begin{itemize}\SlideFontTiny From c3a886a885749c30d7de57616bec6cc2ba5d8c74 Mon Sep 17 00:00:00 2001 From: bjornregnell Date: Tue, 19 Nov 2024 11:14:25 +0100 Subject: [PATCH 7/9] use colon --- slides/body/lect-w10-override.tex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/slides/body/lect-w10-override.tex b/slides/body/lect-w10-override.tex index 2dbb3757..91ad0088 100644 --- a/slides/body/lect-w10-override.tex +++ b/slides/body/lect-w10-override.tex @@ -121,10 +121,9 @@ \begin{REPL} scala> class X { def gurka = "super pepino" } -scala> class Y extends X { +scala> class Y extends X: override val gurka = ":(" val sg = super.gurka - } scala> val y = new Y y: Y = Y@26ba2a48 From e555b979c79adab50f9a950301d69464e0442e66 Mon Sep 17 00:00:00 2001 From: bjornregnell Date: Tue, 19 Nov 2024 13:14:02 +0100 Subject: [PATCH 8/9] add anonymous class to terminology list, w10 --- slides/body/lect-w10-override.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/slides/body/lect-w10-override.tex b/slides/body/lect-w10-override.tex index 91ad0088..487674f3 100644 --- a/slides/body/lect-w10-override.tex +++ b/slides/body/lect-w10-override.tex @@ -229,6 +229,7 @@ \Emph{konkret medlem} & en medlem som ej saknar implementation\\ \Emph{abstrakt typ} & en typ som kan ha abstrakta medlemmar; kan ej instansieras\\ \Emph{konkret typ} & en typ som ej har abstrakta medlemmar; kan instansieras\\ +\Emph{anonym klass} & en namnlös klass som skapas direkt vid instansiering \\ \code|class| & en konkret typ som \Alert{kan ej ha abstrakta medlemmar}\\ \code|abstract class| & en abstrakt typ som \Emph{kan ha abstrakta medlemmar}\\ \code|trait| & är en abstrakt typ som \Emph{kan mixas in} \\ From 820c54315e1e79197c00558c3944ef6f7f802eb8 Mon Sep 17 00:00:00 2001 From: bjornregnell Date: Wed, 20 Nov 2024 14:50:21 +0100 Subject: [PATCH 9/9] fix #850 wrong name of super trait --- slides/body/lect-w10-override.tex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/slides/body/lect-w10-override.tex b/slides/body/lect-w10-override.tex index 487674f3..c984603d 100644 --- a/slides/body/lect-w10-override.tex +++ b/slides/body/lect-w10-override.tex @@ -95,19 +95,19 @@ \begin{itemize} \item En abstrakt \code{def}-medlem får bytas ut mot en \code{var} om du \Alert{inte} skriver \code{override}: \begin{REPLsmall} -scala> trait AbstractDef { def x: Int } -scala> trait Sub extends AbstractDef { override var x = 43 } +scala> trait Super { def x: Int } +scala> trait Sub extends Super { override var x = 43 } -- Error: -1 |trait Sub extends AbstractDef { override var x = 43 } +1 |trait Sub extends Super { override var x = 43 } | ^ | setter x_= overrides nothing -scala> trait Sub extends AbstractVar { var x = 43 } // funkar om ej override +scala> trait Sub extends Super { var x = 43 } // funkar om ej override \end{REPLsmall} Den abstrakta \code{def}-medlemmen blir då implementerad av en konkret getter. \item Egentligen är en publik \code{var}-medlem en kombination av en getter och en setter. Du kan skapa konkret getter+setter och överskugga gettern explicit med \code{override} (notera att settern inte kan göra \code{override}, eftersom superklassen inte har någon motsvarande metod att byta ut -- jämför felmeddelande ovan): \begin{REPLsmall} -scala> trait Sub2 extends AbstractDef: +scala> trait Sub2 extends Super: private var myPrivateValue = 42 override def x: Int = myPrivateValue def x_(newValue: Int): Unit = myPrivateValue = newValue