Рубрики
Без рубрики

Учебник по Scala для Java-программистов с примерами

Scala – это универсальный программный типобезопасный язык JVM, который обеспечивает поддержку объектов… С тегами scala, java, языки.

Scala – это универсальный язык программирования, типобезопасный язык JVM, который обеспечивает поддержку объектно-ориентированного программирования (ООП) и функционального программирования. Scala был разработан для устранения некоторых ограничений и утомительности Java .

Scala – отличный вариант для разработчиков Java, которые хотят поднять свою карьеру на новый уровень (или для тех, кто просто устал от причуд Java). Scala теперь признан крупными компаниями как мощный язык, а именно Twitter и LinkedIn. На самом деле, согласно опросу StackOverflow за 2020 год, разработчики Scala в США имеют самые высокооплачиваемые зарплаты .

Если вы разработчик Java, который хочет перейти на Scala (или просто посмотреть, что он может предложить), вы находитесь в правильном месте. Сегодня мы познакомим вас со Scala, чтобы совершить переход.

Этот учебник с первого взгляда:

  • Scala против Java
  • Привет, мир с Scala
  • Краткое руководство по синтаксису Scala
  • Объекты и классы в Scala
  • Наследование и переопределение
  • Черты характера в Scala
  • Следующие шаги для вашего путешествия в Scala

Скала против Ява

Java известна своей сложностью и многословием. Для выполнения простых задач требуется много строк кода. Scala была разработана для создания “лучшей Java”, как и другие альтернативы, такие как Котлин и Цейлон. Однако Scala уникальна, поскольку она не пыталась оставаться слишком близкой к синтаксису Java.

Scala уничтожила ограничительные и утомительные аспекты Java в пользу улучшения языка в целом.

Это означает, что между ними существуют некоторые заметные различия и сдвиги парадигмы, поэтому у Scala кривая обучения больше , чем у Котлина. Но это того стоит: он создает чистый, простой, организованный код, который повышает вашу производительность в дальнейшем и требует гораздо меньше строк кода, чем Java.

Между этими языками существует несколько ключевых различий. Давайте разберем их.

  • Scala – это статически типизированный язык
  • Scala использует модель актора для параллелизма (вместо потоковой модели Java)
  • Scala не использует статические члены
  • Скалярные переменные неизменяемы по умолчанию
  • Scala поддерживает множественное наследование классов (не абстрактных классов)
  • Scala поддерживает отложенную оценку в отличие от Java
  • Scala предлагает поддержку перегрузки оператора
  • Scala не обеспечивает обратную совместимость
  • Scala можно использовать для функционального программирования
  • Любой метод или функция Scala обрабатывается как переменная, в то время как Java обрабатывает их как объекты
  • Scala использует черты вместо интерфейсов Java

Одним из главных преимуществ Scala является то, что он может быть выполнен на виртуальной машине Java (JVM) , что очень упрощает взаимодействие с кодом Java. Все классы из пакета java.lang по умолчанию импортируются с помощью Scala.

Однако одним из его недостатков является поддержка сообщества : существует менее подробная документация, сторонние библиотеки и присутствие сообщества, чем Java. Однако это меняется по мере того, как все больше разработчиков Java добавляют Scala в свой набор инструментов.

Для практического примера различий Java и Scala давайте посмотрим, как мы создадим список строк на обоих языках:

// java
List list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
// scala
val list = List("1", "2", "3")

Как вы можете видеть, Scala намного точнее, требуя гораздо меньше строк кода. Scala также легче просматривать, что делает его отличным выбором для команд.

Привет, мир с Scala

Теперь, когда мы знакомы с основными различиями между Java и Scala, давайте подробнее рассмотрим код, чтобы понять, чем отличаются эти два языка. Во-первых, посмотрите на программу Hello World на Java, с которой мы знакомы:

class HelloWorld {
    public static void main( String args[] ) {
        System.out.println( "Hello World!" );
    }
}

Теперь посмотрите на эквивалентную программу в Scala. Вы сразу заметите, что это в чем-то похоже.

object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello, world!")
  }
}

Итак, что здесь происходит? Как и в Java, метод main является точкой входа для нашей программы Scala, которая принимает массив строк в качестве параметра. В теле метода есть один вызов метода println с нашим приветствием в качестве аргумента. Поскольку метод main не возвращает никакого значения, его тип – Единица измерения .

То, что может вам броситься в глаза, – это использование объявления объекта . Это вводит одноэлементный объект , который представляет собой класс с одним экземпляром. Здесь мы определяем класс с именем HelloWorld и экземпляр этого класса с тем же именем.

Возможно, вы также заметили, что метод main не объявлен статическим. Scala не поддерживает статические элементы , поэтому мы определяем их как одноэлементные объекты.

Компиляция кода с помощью Scala

Компиляция нашего кода здесь также немного отличается. Для приведенного выше примера Scala мы бы использовали scalac , который работает как большинство компиляторов. Для Scala объектные файлы, создаваемые его компилятором, являются файлами классов Java.

Итак, допустим, мы сохранили нашу программу Hello World в файле с именем HelloWorld.scala . Мы бы использовали следующую команду. Это приведет к созданию нескольких файлов классов, включая один с именем Это приведет к созданию нескольких файлов классов, включая один с именем

> scalac HelloWorld.scala

Как только мы скомпилируем нашу программу, мы можем запустить ее с помощью команды scala , которая аналогична команде java .

> scala -classpath . HelloWorld

Hello, world!

Краткое руководство по синтаксису Scala

Теперь, когда мы знаем программу Hello World с помощью Scala, давайте быстро рассмотрим некоторые базовые синтаксисы Scala, которые вам необходимо знать. Мы не будем здесь определять термины, так как предполагается, что вы уже знаете их из Java или другой язык.

Переменные

Во-первых, переменные . Вот как мы объявляем переменную в Scala.

Сравните это с синтаксисом Java, который следует этой базовой структуре:

 ; 

В нашем коде Scala мы объявляем переменную с именем моя первая скалярная переменная , в которой хранятся данные типа Инт и присваивается начальное значение 5 . Это неизменяемая переменная , потому что мы выбрали ключевое слово val .

В Скале:

  • Переменные типа val являются неизменяемыми
  • Переменные типа var являются изменяемыми переменными

Типы данных

В Scala есть иерархия типов с типом Любой вверху. Любой – это супертип, который определяет универсальные методы, такие как равно , Хэш-код и Строка/|.

Любой имеет два подкласса: Любой и Любая ссылка . AnyRef предназначен для ссылочных типов, включая типы, определенные пользователями Scala. AnyVal представляет наши типы значений, которых насчитывается девять:

  • Двойной
  • Поплавок
  • Длинный
  • Инт
  • Короткий
  • Байт
  • Обуглить
  • Единица измерения
  • Логический

Ниже у нас есть переменная любое бездействие типа Любой . Мы можем присвоить любому бездействию значение любого типа.

var anyInAction: Any = "A String" //String
println(anyInAction)

anyInAction = 5 //Int
println(anyInAction)

anyInAction = '☺' //Char
println(anyInAction)

anyInAction = 1.985 //Float
println(anyInAction)

anyInAction = true //Boolean
println(anyInAction)

Вывод: Строка 5 ☺ 1.985 истинный

Строки и литералы

Строки не подпадают под AnyVal . Скорее, это литералы . Строковые литералы включают комбинацию символов, которые заключены в двойные кавычки. Синтаксис для объявления строки такой же, как и для объявления переменной любого базового типа значения.

val stringLiteral: String = "Hello"

// Driver Code
println(stringLiteral)

Целочисленные литералы используются с типами значений Длинный , Int , Короткий и Байт . Scala всегда будет печатать целочисленный литерал как десятичный, независимо от того, как он объявлен. Литералы с плавающей запятой используются с Двойной и Плавать .

val floatLiteral: Float = 1.2345F // The F at the end is for Float
val somethingBigger: Double = 1.2345e1
val evenBigger: Double = 1.2345e4

// Driver Code
println(floatLiteral)
println(somethingBigger)
println(evenBigger)

Выход: 1.2345 12.345 12345.0

Структуры управления

Управляющие структуры Scala являются если , в то время как , для , попробуйте , сопоставьте и вызовы функций. В Scala управляющие структуры возвращают значения, такие как функции.

Выражение if имеет следующий синтаксис:

var arrayOfEmotions = Array("happy","sad","angry","excited")
if (!arrayOfEmotions.isEmpty) {
  arrayOfEmotions(0) = "joyful"
}

 // Driver Code   
 arrayOfEmotions.foreach(println) 

Выражение while использует следующий синтаксис:

var count = 1
while (count <= 10) {
  println(count)
  count += 1
}

Общий синтаксис выражения для выглядит следующим образом:

Генератор определяет именованную переменную и присваивает ей набор значений. Мы строим его из трех частей: переменной, <- и выражения генератора.

for (i <- 1 to 5) {
  println(s"iteration $i")
}

Определяемые пользователем функции

Мы можем определять функции в Scala. Взгляните на этот пример, который принимает два целых числа и возвращает их сумму:

def sum(x: Double, y: Double): Double ={
  x+y
}
  • def – ключевое слово для определения функции
  • sum – это заданное имя функции
  • за суммой следует () . Здесь вы определяете параметры функции, разделенные запятыми.
  • (x: Двойной, y: Двойной) говорит нам, что наша функция принимает два параметра: x типа Double и y типа Double.
  • Мы определяем тип возвращаемого значения функции, Удваиваем , вставляя : Двойной после () . Вставка типа возвращаемого значения не требуется.
  • Затем мы вставляем = . Все, что происходит после этого, является телом функции. Тело функции заключено в фигурные скобки {} .

Примечание: Вы можете отказаться от использования фигурных скобок, если тело функции состоит только из одного выражения.

Объекты и классы в Scala

В отличие от Java, которая различает примитивные и ссылочные типы, Scala рассматривает все как объект , поскольку Scala является чистым языком ООП . В Scala числа также рассматриваются как объекты, поэтому у них также есть методы. Возьмем следующее арифметическое выражение:

1 + 2 * 3 / x

Это выражение выполняется с помощью вызовов методов, так как оно совпадает со следующим выражением, поэтому + и * являются допустимыми идентификаторами в Scala.

1.+(2.*(3)./(x))

Занятия

В Scala классы объявляются так же, как в Java, но классы Scala могут иметь параметры . Посмотрите на это базовое определение класса в Scala, используя ключевое слово class и ключевое слово var для определения наших свойств (называемых полями в Scala).

class Person{
  var name: String = "temp"
  var gender: String = "temp"
  var age: Int = 0
}

Чтобы определить методы нашего класса, мы используем этот синтаксис:

class Person{
  var name: String = "temp"
  var gender: String = "temp"
  var age: Int = 0

  def walking = println(s"$name is walking")

  def talking = println(s"$name is talking")

}

И теперь мы можем создавать экземпляры наших классов, используя val .

// Creating an object of the Person class
val firstPerson = new Person 

firstPerson.name = "Mary"
firstPerson.gender = "female"
firstPerson.age = 25


println(firstPerson.name)
println(firstPerson.gender)
println(firstPerson.age)

Вызов функций внутри функций

В Scala функции также обрабатываются как объекты , поэтому мы можем передавать функции в качестве аргументов, хранить их в переменных или возвращать их из других функций. Это одна из ценных функций функционального программирования, которую предоставляет Scala.

Взгляните на этот пример ниже, где мы вызываем функцию square в другой функции squareSum .

def square(x: Double) = {
  x * x
}
def squareSum(x: Double, y: Double) = {
  square(x) + square(y)
}

val result = squareSum(2,5)

// Driver Code
println(result)

Наследование и переопределение

Существует несколько типов наследования , поддерживаемых Scala:

  • Одноуровневое наследование: Один класс наследуется от одного другого класса
  • Многоуровневое наследование: Один класс расширяет другой, который затем расширяет другой
  • Множественное наследование: Один класс наследуется от нескольких базовых классов

В Scala все классы наследуются от суперкласса, и когда суперкласс не объявлен, Scala использует scala. AnyRef . Вы можете переопределять методы, унаследованные от суперкласса, но вы должны явно указать это с помощью модификатора override . Например:

class Complex(real: Double, imaginary: Double) {
  def re = real
  def im = imaginary
  override def toString() =
    "" + re + (if (im >= 0) "+" else "") + im + "i"
}

Черты характера с помощью Scala

Scala использует черты, которые похожи на Интерфейсы Java . Подобно наследованию в Scala, как описано выше, класс также может импортировать код из одного или нескольких признаков. Когда это происходит, класс реализует интерфейс данного признака и весь код в этом признаке.

Думайте об этом как о способе реализации многократного использования в коде Scala.

основными свойствами Признака являются:

  • Признаки определяют сигнатуру методов, которые поддерживает данный объект.
  • Признаки объявляются как классы с ключевым словом признак Взгляните на этот пример:
trait Iterator[A] {
  def hasNext: Boolean
  def next(): A
}

В Scala мы можем использовать расширения ключевое слово для расширения признака. Затем мы реализуем любые абстрактные члены с переопределением ключевое слово:

// from Scala documentation 
trait Iterator[A] {
  def hasNext: Boolean
  def next(): A
}

class IntIterator(to: Int) extends Iterator[Int] {
  private var current = 0
  override def hasNext: Boolean = current < to
  override def next(): Int = {
    if (hasNext) {
      val t = current
      current += 1
      t
    } else 0
  }
}


val iterator = new IntIterator(10)
iterator.next()  // returns 0
iterator.next()  // returns 1

Следующие шаги для вашего путешествия в Scala

Поздравляю с тем, что вы дошли до конца. Теперь вы на верном пути к переходу на роль разработчика Scala. Как вы можете видеть, Scala позволяет вам использовать ваши существующие навыки Java. Еще многое предстоит узнать о Scala, и практическая практика будет необходима для овладения этим языком.

Для следующих шагов мы рекомендуем следующие концепции:

  • Дженерики с Scala
  • Функции более высокого порядка
  • Каррирование
  • Библиотека коллекций Scala

Чтобы начать работу с этими концепциями и начать строить с помощью Scala, ознакомьтесь с учебным курсом Изучайте Scala с нуля. Этот курс поможет вам оставаться на шаг впереди, создавать потрясающие масштабируемые приложения и изучать очень желанный новый язык программирования. К концу вы полностью перейдете с Java на Scala!

Счастливого обучения!

Продолжайте изучать Scala и Java

Оригинал: “https://dev.to/educative/scala-tutorial-for-java-programmers-with-examples-3plc”