Scala-zelfstudie: Scala-programmeertaalvoorbeeld en code

Samenvatting van de Scala-zelfstudie

Deze scala-tutorial behandelt alle aspecten en onderwerpen van scala. Je leert alle basisbeginselen helemaal opnieuw, zoals Wat is scala, het installatieproces van scala, Scala-programma's, Scala-functies, Lazy-evaluatie, Type-interface, klassen en objecten, Overerving, Abstracties, Java- en scala-verschillen, enz.

Wat is Scala?

Scala is een statisch getypeerde programmeertaal die zowel functioneel als objectgeoriënteerd programmeren omvat om de schaalbaarheid van applicaties te vergroten. Scala draait voornamelijk op het JVM-platform en kan ook worden gebruikt om software te schrijven voor native platforms met behulp van Scala-Native en JavaScript runtimes via ScalaJs.

Scala is een schaalbare taal die wordt gebruikt om software voor meerdere platforms te schrijven. Daarom kreeg het de naam “Scala”. Deze taal is bedoeld om de problemen van Java tegelijkertijd op te lossenneomeestal beknopter. Oorspronkelijk ontworpen door Martin Odersky, werd het uitgebracht in 2003.

Waarom Scala leren

Dit zijn de belangrijkste redenen om Scala-programmeertaal te leren:

  • Scala is eenvoudig te leren voor objectgeoriënteerde programmeurs en Java-ontwikkelaars. Het is de afgelopen jaren een van de populaire talen aan het worden.
  • Scala biedt eersteklas functies voor gebruikers
  • Scala kan worden uitgevoerd op JVM, waardoor de weg wordt vrijgemaakt voor interoperabiliteit met andere talen.
  • Het is ontworpen voor toepassingen die gelijktijdig, gedistribueerd en veerkrachtig berichtgestuurd zijn. Het is een van de meest veeleisende talen van dit decennium.
  • Het is beknopte, krachtige taal en kan snel groeien afhankelijk van de vraag van zijn gebruikers.
  • Het is objectgeoriënteerd en heeft veel functionele programmeerfuncties die de ontwikkelaars veel flexibiliteit bieden om te coderen op de manier die zij willen.
  • Scala biedt vele soorten eendjes aan
  • Het heeft minder standaard als je er vandaan komt Java
  • De raamwerken Lift and Play geschreven in Scala bevinden zich in de groeicurve.

Hoe Scala te installeren

Om Scala-programma's te kunnen schrijven, moet het op uw computer zijn geïnstalleerd. Om dit te doen, moet je hun site bezoeken https://www.scala-lang.org/download/ om de nieuwste versie van Scala te downloaden.

Following Via de link worden we naar twee opties geleid waaruit we kunnen kiezen om Scala op onze machines te installeren. Voor deze Scala-tutorial downloaden we de IntelliJ IDEA.

Hoe Scala te installeren

Zodra u de downloadlink bezoekt, vindt u twee versies van de IntelliJ IDE.

Voor deze Scala-tutorial downloaden we de Community Edition, die gratis is en wordt geleverd met alles wat je nodig hebt om Scala-programma's te schrijven.

Hoe Scala te installeren

Stap 1) Selecteer Community-editie
Klik op de pagina op de vervolgkeuzelijst voor de Community-editie.

Het biedt ons een optie om de IntelliJ IDE samen met JBR te downloaden, die een JDK-implementatie (Java Development Kit) OpenJDK bevat die Scala nodig heeft om de code te compileren en uit te voeren.

Hoe Scala te installeren

Stap 2) Voer de installatie uit
Nadat u IntelliJ hebt gedownload, double klik erop om de installatiewizard uit te voeren en het dialoogvenster te volgen.

Hoe Scala te installeren

Stap 3) Selecteer een locatie
Kies een locatie om de IDE te installeren.

Hoe Scala te installeren

Als je toevallig die met de JDK niet hebt gedownload, krijgen we nog steeds een prompt waar we kunnen controleren of we deze kunnen downloaden door het selectievakje te selecterenbox.

Hoe Scala te installeren

Stap 4) Klik op volgende
Laat de overige standaardinstellingen ongewijzigd en klik op Volgende.

Hoe Scala te installeren

Stap 5) Klik op het opstartpictogram
Zodra de installatie is voltooid, voert u de IntelliJ IDE uit door op het opstartpictogram in het opstartmenu te klikken, net als bij een gewone toepassing.

Hoe Scala te installeren

U moet nog een extra stap doorlopen om de Scala-plug-in aan IntelliJ toe te voegen; u doet dit door op de vervolgkeuzelijst in het configuratiemenu rechtsonder in het scherm te klikken en de plug-inoptie te selecteren.

Hoe Scala te installeren

Hoe Scala te installeren

Op het tabblad Marktplaats zal een zoekopdracht naar Scala de plug-in als eerste resultaat onder de tag Talen presenteren.

Stap 6) Installeer plugin
Klik op Installeren, waardoor de plug-in begint met downloaden.

Hoe Scala te installeren

Stap 7) Start de IDE opnieuw
Nadat het downloaden is voltooid, wordt u gevraagd de IDE opnieuw te starten, zodat de geïnstalleerde plug-in kan gaan werken.

Hoe Scala te installeren

Na het opnieuw opstarten bevindt u zich op dezelfde pagina als voorheen toen we de IDE uitvoerden, maar deze keer hebben we de Scala-plug-in al geïnstalleerd.

Scala Hello World-programma

Stap 1) Selecteer de optie Project maken, die ons naar een pagina zal leiden waar we het soort taal kunnen selecteren dat ons project zal gebruiken.

Scala Hello World-programma

Stap 2) kies Scala door het Scala-vinkje te selecterenbox en klik op volgende.

Scala Hello World-programma

Stap 3) Selecteer een locatie om ons projectbestand op te slaan en geef ons project een naam.

Scala Hello World-programma

Als de map niet bestaat, zal IntelliJ ons vragen om toestemming om de map te maken. Accepteer en klik op Voltooien. U wordt naar uw Scala-project geleid, dat momenteel geen Scala-code heeft.

Het zal enige tijd duren om sommige indexen te laden, dus maak u geen zorgen als u niet onmiddellijk iets kunt doen terwijl er onderaan uw IDE een voortgangsbalk staat. Dit betekent eenvoudigweg dat uw IDE een aantal bestanden aan het laden is die nodig zijn om Scala uit te voeren en hulp bij het automatisch aanvullen van IDE.

Stap 4) Vervolgens klikken we op het tabblad Projecten aan de linkerkant van de IDE en vouwen we uit zodat we de inhoud van ons project kunnen zien.

Scala Hello World-programma

Op dit moment is het project leeg en bevat het alleen een .idea-map en hello-world.iml-bestand gegenereerd door de IDE. Ons aandachtspunt is de src-map. Src is waar we de broncode voor ons project opslaan. Hier zullen we ons eerste Scala-bestand maken.

Stap 5) Klik met de rechtermuisknop op src om een ​​menu te openen waarin u een nieuw Scala-bestand kunt maken.

Maak een nieuw Scala-bestand

We zullen dan een naam voor het bestand maken, in deze Scala-tutorial gebruiken we hallo en kiezen vervolgens uit een vervolgkeuzelijst wat we als inhoud van het Scala-bestand willen plaatsen. Selecteer “Object”

Scala Hello World-programma

Zodra we dit doen, hebben we een Scala-bestand met een Singleton-object dat we zullen gebruiken om onze code uit te voeren.

Scala Hello World-programma

Nu je een Scala-bestand hebt met een Hello-object. U schrijft uw eerste programma door het object dat u hebt gemaakt uit te breiden met het trefwoord App.

Door ons object uit te breiden met een app, vertelt u de compiler welke code moet worden uitgevoerd wanneer uw programma wordt gestart. Onmiddellijk na het uitbreiden van de app verschijnt er aan de linkerkant een groene pijl, die aangeeft dat u nu uw programma kunt uitvoeren.

Scala Hello World-programma

Scala Hello World-programma

Binnen het Hello-object schrijven we één functie println() die wordt gebruikt om de tekst erin naar de console af te drukken. We voeren onze code uit door op de groene pijl te klikken.

Als u op de pijl klikt, krijgt u de optie Uitvoeren, hallo. Als u erop klikt, begint onze code met het compileren en na enkele seconden zien we de resultaten van ons programma afgedrukt vanaf de console die is ingebouwd in de IntelliJ IDE.

Scala Hello World-programma

En daar gaan we, we hebben Scala met succes geïnstalleerd en ons eerste programma uitgevoerd.

Wat je met Scala kunt doen

  • Frontend webontwikkeling met ScalaJS
  • Mobiele ontwikkeling, zowel Android Development als IOS – met Scala Native
  • Bibliotheken aan de serverzijde zoals HTTP4S, Akka-Http, Play Framework
  • Internet der dingen gebruikt
  • Game ontwikkeling
  • NLP – Natuurlijke taalverwerking met behulp van een reeks bibliotheken ScalaNLP
  • Het testen van geavanceerde programmeertechnieken zoals Functioneel Programmeren en Objectgeoriënteerd Programmeren
  • Bouw een zeer gelijktijdige communicatietoepassing met behulp van een bibliotheek voor de JVM, geïnspireerd door Erlang
  • Gebruik het voor machinaal leren met behulp van bibliotheken zoals Figaro, dat probabilistisch programmeren uitvoert, en Apache Spark dat

Anonieme functies

De Scala-taal heeft anonieme functies, die ook wel worden genoemd functie letterlijke. Omdat Scala een functionele taal is, betekent dit vaak dat ontwikkelaars grote problemen opsplitsen in veel kleine taken en veel functies creëren om deze problemen op te lossen. Om het maken van functies eenvoudig te maken, bevat Scala deze functies die kunnen worden gemaakt geïnstantieerd zonder naam. We kunnen ze rechtstreeks toewijzen aan variabelen of definities 'def', zoals weergegeven in het onderstaande Scala-voorbeeld:

val multiplyByTwo = (n:Int) => n * 2
def multiplyByThree = (n:Int) => n *3

We kunnen dan de normale manier gebruiken waarop we functies gebruiken door er parameters aan door te geven.

multiplyByTwo(3)

//6

multiplyByThree(4)

//12

Deze methoden zijn handig als we een schone en beknopte code willen hebben. We kunnen anonieme functies gebruiken bij het definiëren van methoden die niet groot zijn en niet veel code in de hoofdtekst vereisen. Ze zijn heel eenvoudig en vereisen geen ceremonie om te maken.

Deze methoden zijn niet beperkt tot functies met argumenten en kunnen worden gebruikt om methoden te instantiëren die geen argumenten bevatten.

val sayHello = ()=>{ println("hello") }

De meeste van deze anonieme functies worden gebruikt in andere delen van onze code waar we een snelle functie moeten creëren.

Nog een reden waarom deze functies ook wel worden genoemd inline-functies. Het gebruik van anonieme functies is een gebruikelijk patroon dat alomtegenwoordig wordt gebruikt in de collectiebibliotheek om snelle acties uit te voeren op een collectie.

We hebben bijvoorbeeld de filtermethode die een inline-functie/anonieme functie gebruikt om een ​​andere verzameling te maken met alleen elementen die voldoen aan de criteria die we definiëren in de anonieme functie.

val myList = List(1,2,3,4,5,6,7)

val myEvenList = myList.filter((n: Int) => n % 2 == 0)
//List(2,4,6)

val myOddList = myList.filter((n:Int) => n % 2 != 0)
//List(1,3,5,7)

Hier zijn de methoden die we hebben als anonieme functies degene die controleren of de waarde die we uit de lijst halen oneven en even is en het item retourneren.

//the one checking that the value is even
(n: Int) => n % 2 == 0

//the one checking that the value is odd
(n:Int) => n % 2 != 0

In Scala is het ook mogelijk om jokertekens te gebruiken als de parameter van onze anonieme functie geen naam heeft. Bijvoorbeeld

var timesTwo = (_:Int)*2

timesTwo(5)
//10

In dit scenario geven we de parameter die we doorgeven geen naam. Het enige dat we gebruiken is een onderstrepingsteken om deze weer te geven.

Luie evaluatie

De meeste talen evalueren variabelen en functieparameters opeenvolgend, de een na de ander. In Scala hebben we een trefwoord met de naam lui, dat helpt bij het omgaan met waarden waarvan we niet willen dat ze worden geëvalueerd totdat er naar wordt verwezen.

Een variabele die als lui is gemarkeerd, wordt niet geëvalueerd waar deze is gedefinieerd, dat staat algemeen bekend als enthousiaste evaluatie. Deze wordt alleen geëvalueerd als er op een bepaald moment naar wordt verwezen. later in de code.

Dit kan handig zijn als het evalueren van een waarde een dure berekening kan zijn. Als het niet zo is dat de waarde altijd nodig is, kunnen we onszelf behoeden voor het uitvoeren van een dure berekening die onze software kan vertragen door onze variabele lui te maken.

lazy val myExpensiveValue = expensiveComputation

def runMethod()={
    if(settings == true){
        use(myExpensiveValue)
    }else{
        use(otherValue)
    }
}

Dit is niet het enige gebruiksscenario voor luie variabelen. Ze helpen ook bij het omgaan met kwesties van circulaire afhankelijkheid in code.

Als de instellingen onjuist zijn, hoeven we myExpensiveValue mogelijk niet te gebruiken, wat ertoe kan leiden dat we geen dure berekeningen hoeven uit te voeren, waardoor gebruikers een leuke tijd hebben bij het gebruik van onze applicatie, omdat onze andere behoeften correct kunnen worden berekend zonder overweldigend te zijn. de ram.

Als de instellingen onjuist zijn, hoeven we myExpensiveValue mogelijk niet te gebruiken, wat ertoe kan leiden dat we geen dure berekeningen hoeven uit te voeren, waardoor gebruikers een leuke tijd hebben bij het gebruik van onze applicatie, omdat onze andere behoeften op de juiste manier kunnen worden berekend zonder overweldigend te zijn. de ram.

De luiheid helpt ook bij functieargumenten, waarbij de argumenten alleen worden gebruikt als er binnen de functie naar wordt verwezen. Dit concept wordt Call-by-name-parameters genoemd.

def sometimesUsedString(someValue:String, defaultValue:=> String)={
 if(someValue != null){
   use(defaultValue)
 }else{
   use(someValue)
   }
 }

Veel talen gebruiken de call-by-value-manier om argumenten te evalueren. De parameter die via call-by-name wordt doorgegeven, wordt alleen geëvalueerd wanneer dat nodig is in de hoofdtekst van de functie en wordt daarvoor niet geëvalueerd. Zodra de waarde is geëvalueerd, wordt deze opgeslagen en kan deze opnieuw worden gebruikt later zonder dat het opnieuw beoordeeld hoeft te worden. Een concept dat bekend staat als memoriseren.

Typ gevolgtrekking

In Scala hoeft u geen typen te declareren voor elke variabele die u maakt. Dit komt omdat de Scala-compiler type-inferentie kan uitvoeren op typen op basis van evaluatie van de rechterkant. Hierdoor kan uw code beknopter zijn – het bevrijdt ons van het schrijven van standaardteksten waarbij het verwachte type duidelijk is

var first:String = "Hello, "
var second:String = "World"
var third = first + second
//the compile infers that third is of type String

Functie van hogere orde

Een functie van hogere orde is een functie die functies als argumenten kan aannemen en een functie als retourtype kan retourneren. In Scala worden functies beschouwd als eersteklas burgers. Door deze functies op deze manier te gebruiken, kunnen we zeer flexibel zijn in het soort programma's dat we kunnen maken. We kunnen functies dynamisch creëren en functionaliteit dynamisch aan andere functies toevoegen.

def doMathToInt(n:Int, myMathFunction:Int=>Int): Int ={
    myMathFunction(n)
}

In de bovenstaande functie geven we een int door en een functie die een int nodig heeft en een int retourneert. We kunnen elke functie van die handtekening doorgeven. Met handtekening bedoelen we de invoer en uitvoer van een functie. Een handtekening van Int=>Int betekent dat een functie een Int als invoer neemt en een Int als uitvoer retourneert.

Een handtekening van ()=>Int betekent dat een functie niets als invoer neemt en een Int als uitvoer retourneert. Een voorbeeld van zo'n functie is er een die een willekeurige int voor ons genereert.

def generateRandomInt()={
 return scala.util.Random.nextInt()
}

De bovenstaande functie heeft een handtekening ()=>Int

We kunnen een functie hebben met de handtekening scala ()=>Unit. Dit betekent dat de functies niets opnemen en geen type retourneren. De functie zou een soort berekening kunnen uitvoeren door iets te veranderen in iets dat vooraf is bepaald.

Dit soort methoden worden echter niet aangemoedigd, omdat ze zwart lijken te zijn box die een systeem op onbekende manieren kunnen beïnvloeden. Ze zijn ook niet te testen. Het hebben van expliciete invoer- en uitvoertypen stelt ons in staat te redeneren over wat onze functie doet.

Een functie van hogere orde kan ook een functie retourneren.

We zouden bijvoorbeeld een methode kunnen creëren die een machtsfunctie creëert, dat wil zeggen: we nemen een getal en passen er macht op toe.

def powerByFunction(n:Int):Int=>Int = {
  return (x:Int)=> scala.math.pow(x,n).toInt
}

De bovenstaande functie heeft een int nodig. Ons retourtype is een anonieme functie waaraan een Int x moet doorgegeven worden, * we gebruiken de int x als argument voor de machtsfunctie.

Curry

In Scala kunnen we een functie die twee argumenten meeneemt, omzetten in één die één argument tegelijk accepteert. Wanneer we één argument doorgeven, passen we het gedeeltelijk toe en eindigen we met een functie die één argument nodig heeft om de functie te voltooien. Currying stelt ons in staat functies te creëren door enkele argumenten gedeeltelijk toe te voegen.

Dit kan handig zijn voor het dynamisch maken van functies voordat we een volledige set argumenten hebben

def multiply two numbers(n:Int)(m:Int): Unit ={
  return n * m
}

Als we een functie moeten maken die vermenigvuldigt met een bepaald getal, hoeven we geen andere vermenigvuldigingsmethode te maken.

We kunnen eenvoudigweg de .curried op onze bovenstaande functie aanroepen en een functie krijgen die eerst één argument nodig heeft en een gedeeltelijk toegepaste functie retourneert

def multiplyTwoNumbers(n:Int)(m:Int): Unit ={
  return n * m
}

var multiplyByFive = multiplyTwoNumbers(5) 

multiplyByFive(4)

//returns 20

Patroonaanpassing

Scala heeft een krachtig ingebouwd mechanisme om ons te helpen controleren of een variabele aan bepaalde criteria voldoet, net zoals we zouden doen bij een switch-instructie in Java of in een reeks if/else-instructies. De taal beschikt over patroonmatching die we kunnen gebruiken om te controleren of een variabele van een bepaald type is. Patroonmatching in Scala is krachtig en kan worden gebruikt om de componenten met een unapply-methode te destructureren om velden waarin we geïnteresseerd zijn rechtstreeks uit de variabele te halen die we matchen.

Scala's patroonafstemming biedt ook een aangenamere syntaxis vergeleken met de switch-instructie.

myItem match {
  case true => //do something
  case false => //do something else
  case  _ => //if none of the above do this by default
}

We vergelijken onze variabele met een reeks opties, en wanneer de variabele die we matchen aan de criteria voldoet, wordt de uitdrukking aan de rechterkant van de dikke pijl (=>) geëvalueerd en geretourneerd als het resultaat van de match.

We gebruiken een onderstrepingsteken om gevallen te vangen die ongeëvenaard zijn in onze code. Het weerspiegelt het gedrag van de standaardcase bij het omgaan met switch-instructies.

class Animal(var legs:Int,var sound:String)
class Furniture(var legs:Int, var color:Int, var woodType:String)

myItem match {
case myItem:Animal => //do something
case myItem:Furniture => //do something else
case _ => //case we have a type we don't recognize do sth else
}

In de bovenstaande code kun je het type van de myItem-variabele achterhalen en op basis daarvan naar een specifieke code aftakken.

Patroonmatching controleert of de variabele overeenkomt

Het onderstrepingsteken werkt als een tijdelijke aanduiding die overeenkomt met elke andere voorwaarde die niet overeenkomt met de andere items in de bovenstaande case-instructies. We nemen een variabele myItem en roepen de matchmethode aan.

  • we controleren of myItem waar is en gebruiken wat logica aan de rechterkant van de dikke pijl “=>.”
  • we gebruiken het onderstrepingsteken om iets te matchen dat niet overeenkomt met een van de case-statements die we in de code hebben gedefinieerd.

Met Case-klassen kunnen we zelfs verder gaan en de klasse destructureren om velden in het object te krijgen.

Door het verzegelde trefwoord te gebruiken om onze klassen te definiëren, hebben we het voordeel dat de compiler de gevallen waarmee we proberen te matchen uitvoerig controleert en ons waarschuwt als we vergeten een bepaald geval af te handelen.

Onveranderlijkheid

Het is mogelijk om waarden te creëren die niet kunnen worden gewijzigd door andere functies in Scala met behulp van het sleutelwoord val. Dit wordt in Java bereikt door het laatste trefwoord te gebruiken. In Scala doen we dit door een val-trefwoord te gebruiken bij het maken van een variabele in plaats van var te gebruiken, wat het alternatief is dat we zouden gebruiken om een ​​veranderlijke variabele te maken.

Een variabele die is gedefinieerd met het sleutelwoord val is alleen-lezen, terwijl een variabele die is gedefinieerd met var kan worden gelezen en gewijzigd door andere functies of willekeurig door de gebruiker in de code.

var changeableVariable = 8

changeableVariable =10
//the compiler doesn't complain, and the code compiles successfully

println(changeableVariable)
//10

val myNumber = 7

myNumber = 4

//if we try this the code won't compile

Als we proberen een waarde toe te wijzen aan myNumber nadat we deze als val hebben gedeclareerd, ontstaat er een compileerfout of een “hertoewijzing naar val.”

Waarom onveranderlijkheid gebruiken?

Onveranderlijkheid helpt ons te voorkomen dat code en andere programmeurs onze waarden onverwachts wijzigen, wat tot onverwachte resultaten zou leiden. Als het de bedoeling is dat ze de waarde gebruiken die we opslaan, kunnen ze er in plaats daarvan een kopie van maken. Op deze manier worden bugs voorkomen die kunnen worden veroorzaakt doordat meerdere actoren dezelfde variabele wijzigen.

Klassen en objecten

We weten allemaal dat objecten de echte entiteiten zijn, en dat klasse een sjabloon is dat objecten definieert. Klassen hebben zowel staat als gedrag. De toestanden zijn waarden of variabelen. Het gedrag is de methode in Scala.

Laten we eens kijken hoe u een klasse kunt definiëren, instantiëren en gebruiken met Scala.

Hier heet de klasse Rectangle, die twee variabelen en twee functies heeft. U kunt de parameters l en b ook rechtstreeks als velden in het programma gebruiken. Je hebt een object dat een hoofdmethode heeft en de klasse met twee waarden heeft geïnstantieerd.

Voorbeeld:

class Rectangle( l: Int,  b: Int) {
  val length: Int = l
  val breadth: Int = b
  def getArea: Int = l * b
  override def toString = s"This is rectangle with length as $length and breadth as  $breadth"
  }
object RectObject {
  def main(args: Array[String]) {
    val rect = new Rectangle(4, 5)
    println(rect.toString)
    println(rect.getArea)    
  }
}

Alle velden en methoden zijn standaard openbaar in Scala. Het is essentieel om override te gebruiken, omdat de toString-methode is gedefinieerd voor Object in Scala.

Erfenis

Scala heeft meerdere soorten overerving (zoals single, multi-level, multiple, hierarchical, hybride,) die veel gemeen hebben met traditionele vormen die op Java voorkomen. Je kunt zowel van klassen als van eigenschappen erven. U kunt de leden van de ene klasse overerven naar een andere klasse met behulp van het trefwoord “extends”. Dit maakt herbruikbaarheid mogelijk.

Het is mogelijk om van één klasse of meerdere klassen te erven. Het is ook mogelijk om te erven van subklassen die zelf hun superklassen hebben, waardoor er een hiërarchie van overerving ontstaat.

In het onderstaande Scala-voorbeeld is de Base-klasse Circle en de afgeleide klasse Sphere. Een cirkel heeft een waarde die straal wordt genoemd en die wordt overgenomen in de klasse Sphere. De methode calcArea wordt overschreven met behulp van het trefwoord overschrijven.

Voorbeeld:

class Circle {
  val radius = 5;
  def calcArea = {
    println(radius * radius )
  }
}
class Sphere extends Circle{
 override def calcArea = {
    println(radius * radius * radius )
  }
}
  object SphereObject{
    def main(args : Array[String]){
      new Sphere().calcArea 
    }
  }

Abstractie

In Scala kunnen we abstracte methoden en lidvelden maken met behulp van abstracte klassen en eigenschappen. Binnen abstracte klassen en eigenschappen kunnen we abstracte velden definiëren zonder ze noodzakelijkerwijs te implementeren.

Voorbeeld:

trait MakesSound{
    var nameOfSound:String
    def sound():String
}
abstract class HasLegs(var legs:Int){
    val creatureName:String

    def printLegs():String={
        return s"$creatureName has this number of legs: $legs"
    }
}

Deze velden worden geïmplementeerd door de klassen die de eigenschap of abstracte klasse uitbreiden. U kunt eigenschappen gebruiken om contracten te maken over wat onze applicatie zou moeten kunnen doen en deze methoden vervolgens implementeren later.

trait DatabaseService{
    def addItemName(itemName:String)
    def removeItem(itemId:Int)
    def updateItem(itemId:Int, newItemName:String)
}

Op deze manier kunnen we plannen hoe onze applicatie eruit zal zien zonder de methoden te implementeren die ons kunnen helpen ons voor te stellen hoe verschillende methoden eruit zullen zien. Het volgt een patroon dat bekend staat als programmeren voor abstracties en niet voor de daadwerkelijke implementatie.

De klasse die wordt voorafgegaan door het trefwoord abstract kan zowel abstracte als niet-abstracte methoden bevatten. Maar meerdere overervingen worden niet ondersteund in abstracte klasse. U kunt dus maximaal één abstracte klasse uitbreiden.

Singleton-objecten

Een Singleton is een klasse die slechts één keer in een programma wordt geïnstantieerd. Het komt uit een populair en nuttig programmeerpatroon dat bekend staat als het “singleton-patroon”. Het is handig bij het maken van instances die bedoeld zijn om een ​​lange levensduur te hebben en die algemeen toegankelijk zijn in uw programma, waarvan de status een integraal onderdeel is van het coördineren van de gebeurtenissen van een systeem. Het maken van een dergelijke klasse in Scala is eenvoudig, omdat Scala ons een eenvoudige manier biedt om singletons te maken met behulp van het object-trefwoord.

object UserProfile{
    var userName=""
    var isLoggedIn:Boolean = false
}

We kunnen dan in ons hele programma naar dit object verwijzen met de garantie dat alle delen van ons programma dezelfde gegevens zullen zien, aangezien er maar één exemplaar van is.

def getLoggedInStatus():Boolean={
   return UserProfile.isLoggedIn
}

def changeLoggedInStatus():Boolean={
    UserProfile.isLoggedIn = !UserProfile.isLoggedIn
    return  UserProfile.isLoggedIn
}

Het concept van statische leden is er niet in Scala, dat is de reden dat je singleton-objecten moet gebruiken, die zich gedragen als statische leden van een klasse.

Impliciete klassen

Impliciete klassen zijn de nieuwe functionaliteit die is toegevoegd na versie 2.1. Het is vooral bedoeld om nieuwe functionaliteit toe te voegen aan de gesloten klassen.

Het impliciete trefwoord moet worden gedefinieerd in een klasse, object of eigenschap. De primaire constructor van een impliciete klasse moet precies één argument in de eerste parameterlijst hebben. Het kan ook een aanvullende impliciete parameterlijst bevatten.

In het onderstaande Scala-voorbeeld is nieuwe functionaliteit toegevoegd om klinkers van een String te vervangen door *.

object StringUtil {
  implicit class StringEnhancer(str: String) {
    
    def replaceVowelWithStar: String = str.replaceAll("[aeiou]", "*")
  }
}

U moet importeren in de klas waarin u het gebruikt.

import StringUtil.StringEnhancer

object ImplicitEx extends App {
  val msg = "This is Guru99!"
  println(msg.replaceVowelWithStar)
}

Objectgeoriënteerd programmeren (OOP) versus functioneel programmeren (FP)

In OOP worden programma's geconstrueerd door gegevens en de functies die op die gegevens werken te groeperen in sterk verbonden eenheden. Objecten dragen hun gegevens over in de velden en methoden die erop werken. Bij deze programmeerstijl zijn de belangrijkste abstractie de gegevens, aangezien de gecreëerde methoden bedoeld zijn om op de gegevens te werken.

Functioneel programmerenscheidt daarentegen gegevens en de functies die op de gegevens werken. Hierdoor kunnen ontwikkelaars functies beschouwen als de abstractie en drijvende kracht bij het modelleren van programma's.

Scala maakt functioneel programmeren mogelijk door te functioneren als eersteklas burgers, allowing ze moeten als waarden aan andere functies worden doorgegeven en ook als waarden worden geretourneerd. De combinatie van deze twee paradigma's heeft Scala tot een uitstekende keuze gemaakt in het bouwen van complex software in verschillende industrieën, zoals Data Science.

Belangrijke raamwerken over Scala

Hier zijn enkele belangrijke raamwerken van Scala

  • Spelen is een open-source webapplicatieframework dat gebruik maakt van MVC architectuur. Uitgebracht in 2007 en nu gelicentieerd onder Apache, werd het in 2013 het populairste raamwerk op GitHub. Bedrijven zoals LinkedIn, Walmart, Samsung en Eero gebruiken dit raamwerk.
  • lift is een ander gratis webframework geschreven in Scala, gelanceerd in 2007. Foursquare gebruikt het Lift-framework. Het presteert goed en is sneller om een ​​raamwerk te bouwen.
  • Akka
  • Katten
  • Spark

Ondersteuning voor gelijktijdigheid

  • De waarden in Scala zijn standaard onveranderlijk. Dit maakt het zeer adaptief aan de gelijktijdige omgeving.
  • Er zijn veel functies in Scala die het het beste maken voor gelijktijdige toepassingen.
  • Futures en Promises maken het gemakkelijker om gegevens te verwerkensyncronisch, waardoor parallellisme wordt ondersteund.
  • Akka – toolkit die het gelijktijdigheidsmodel van Actor gebruikt. Er zijn een aantal Actoren die in actie komen als ze berichten ontvangen.
  • Gelijktijdigheid met behulp van threads uit Java kan ook worden ondersteund in Scala.
  • Streamverwerking is een andere geweldige functie die continue, realtime verwerking van gegevens mogelijk maakt.

Scala heeft enkele van de beste gelijktijdigheidsbibliotheken op Java ecossysteem.

  • Native Java-threads
  • Vezels uit bibliotheken zoals Vertex
  • ZIO – een bibliotheek met primitieven om ons te helpen omgaan met gelijktijdigheid en asyncroneuze berekening
  • STM – Transactie
  • Toekomst – ingebouwd in de Scala-taal

Java versus Scala

Hier zijn de belangrijkste verschil tussen Java en Scala.

Scala Java
Compacter en beknopter Relatief grotere stukken code
Ontworpen en ontwikkeld om zowel object- als functioneel georiënteerde taal te zijn.
Ondersteunt een breed scala aan functionele programmeerfuncties, zoals gelijktijdigheid en onveranderlijkheid.
Oorspronkelijk ontwikkeld als een objectgeoriënteerde taal en de afgelopen dagen begonnen met het ondersteunen van functionele programmeerfuncties. Is nog steeds niet sterk als functionele programmeertaal.
Maakt gebruik van een actormodel ter ondersteuning van gelijktijdigheid, wat modern is Maakt gebruik van het conventionele op threads gebaseerde model voor gelijktijdigheid.
Ondersteunt raamwerken – Spelen, Liften Ondersteunt Lente, Grails en nog veel meer
Ondersteunt luie evaluatie Ondersteunt geen luie evaluatie
Geen statische leden Bevat statische leden
Ondersteunt overbelasting van de operator Ondersteunt geen overbelasting door de operator
Het compileren van de broncode is relatief traag Het compileren van de broncode is sneller dan Scala
Eigenschappen – fungeren als Java 8-interfaces Java 8-interfaces proberen de kloof tussen klassen en interfaces te overbruggen
Herschrijven is nodig Herschrijven is niet nodig
Geen zekerheid over de bugvrije codes Volledige zekerheid van kleinere gebreken
Ondersteunt achterwaartse compatibiliteit. Scala ondersteunt geen achterwaartse compatibiliteit.
Operators worden in Java anders behandeld en zijn geen methodeaanroepen. Alle operatoren voor vermeldingen worden uitgevoerd via een methode die in Scala wordt genoemd.
Ondersteunt meerdere overervingen met behulp van klassen, maar niet door abstracte klassen Ondersteunt geen meerdere overervingen met behulp van klassen, maar via interfaces
Code is in compacte vorm geschreven. Code is in lange vorm geschreven.
Scala bevat niet het statische zoekwoord. Java bevat het statische trefwoord.

Samengevat

In deze tutorial heb je geleerd hoe je aan de slag kunt gaan met Scala. Ook heb je de functionele en objectgeoriënteerde eigenschappen geleerd. Je hebt ook de overeenkomsten en verschillen tussen Java en Scala ontdekt. Deze tutorial had je moeten helpen met een grote verscheidenheid aan voorbeelden die goed worden gedemonstreerd.