Учебник по Скала
Обзор
Класс, объявленный с помощью ключевого слова abstract, называется классом abstract.
abstract class Pet(name: String) { var age: Int = 0 // concrete field def printName: Unit // abstract method def printAge: Unit = { // concrete method println(age) } }
Абстрактный класс может иметь какабстрактные, так и неабстрактные (реализованные) методы. Как уже упоминалось, абстрактный класс также может иметь свои собственные реализованные поля и методы, которые не требуют реализации в подклассах. Обратите внимание, что мы не можем создать экземпляр абстрактного класса напрямую с помощью оператора new
— если мы это сделаем, компилятор выдаст ошибку! Абстрактный класс может использоваться как базовый класс другого класса, который реализует отложенные/нереализованные члены. Абстрактные классы могут иметь параметры конструктора, а также параметры типа.
Назначение абстрактного класса
Цель класса abstract — функционировать как базовый класс с абстракциями, которые могут быть расширены подклассами для создания полных реализаций. В Scala мы можем добиться абстракции, используя либо абстрактный класс, либо trait.
Реализация/использование абстрактного класса
Используйте ключевое слово «extends», чтобы расширить абстрактный класс. Ожидается, что класс, который расширяет абстрактный класс, реализует все методы, определенные в этом абстрактном классе. Если расширяющий класс не реализует все методы и поля, определенные в абстрактном классе, расширяющий класс должен быть объявлен abstract . Обратите внимание, что класс может расширять только один абстрактный класс.
class Dog(name: String) extends Pet(name) { // Implementation of abstract method def printName: Unit = println("Hi there, I am " + name) }
Переопределение реализованного метода
class Dog(name: String) extends Pet(name) { // Implementation of abstract method def printName: Unit = println("Hi there, I am " + name) // Overrides the implemented method to add more details override def printAge: Unit = { println(name + "'s age is " + age) } }
Полный пример
abstract class Pet(name: String) { var age: Int = 0 // concrete field def printName: Unit // abstract method def printAge: Unit = { // concrete method println(age) } } class Dog(name: String) extends Pet(name) { // Implementation of abstract method def printName: Unit = println("Hi there, I am " + name) } object AbstractClassDemo extends App { val dogObj = new Dog("Jimmy") dogObj.printName dogObj.age = 2 dogObj.printAge }
Абстрактные поля «val» и «var»
Мы можем объявить абстрактные поля в абстрактном классе либо как val
, либо как var
, в зависимости от наших потребностей.
abstract class Pet (name: String) { val greeting: String // abstract "val" field var age: Int // abstract "var" field }
Абстрактные поля работают в абстрактных классах (также и в трейтах) следующим образом:
- Абстрактное поле
var
приводит к созданию методов getter и setter для поля. - Абстрактное поле
val
приводит к тому, что для поля генерируется метод получения, но не метод установки.
Абстрактные поля создаваться не будут!
Когда мы определяем абстрактное поле в абстрактном классе или trait, компилятор Scala не создает поле в результирующем коде; он генерирует только те методы, которые соответствуют полю val
или var
. Поскольку абстрактные поля не генерируются, когда мы предоставляем конкретные значения для абстрактных полей в наших конкретных классах, мы должны снова определить поля как val
или var
. Поскольку абстрактные поля фактически не существуют в абстрактном базовом классе или свойстве, ключевое слово override
не требуется.
Взаимодействие с Java
- Абстрактные классы полностью совместимы с Java.
- Мы можем вызывать их из кода Java без каких-либо оболочек.
Когда использовать абстрактный класс вместо трейта?
trait более гибкий, чем абстрактный класс. Однако можно выбрать абстрактный класс вместо типажа по следующим причинам:
- Хотите создать базовый класс, для которого требуются аргументы конструктора.
- Хотите, чтобы код вызывался из кода Java.
Что нельзя сделать с абстрактным классом
Абстрактные классы не могут быть созданы, но они могут быть только подклассами (создание подклассов из абстрактного класса).
Различия и сходства с Java
Отличия
- Никаких различий!
Сходства
- Абстрактные классы не могут быть созданы, но они могут быть только подклассами.
- Абстрактные классы могут иметь конструкторы.
- Класс может расширять только один абстрактный класс.