Різниця між об'єктом і класом у Scala


635

Я просто переглядаю кілька навчальних посібників Scala в Інтернеті і помітив у деяких прикладах об’єкт, оголошений на початку прикладу.

Яка різниця між classі objectу Scala?

Відповіді:


578

тл; д-р

  • class C визначає клас, як і в Java або C ++.
  • object Oстворює одиночний об'єкт Oяк екземпляр якогось анонімного класу; його можна використовувати для зберігання статичних членів, не пов'язаних із екземплярами якогось класу.
  • object O extends Tробить об'єкт Oпримірником trait T; Ви можете пройти Oкуди завгодно, Tочікується.
  • якщо є a class C, то object Cє супутнім об'єктом класу C; зауважте, що супутній об’єкт не є автоматично примірником C.

Також дивіться документацію Scala для об'єкта та класу .

object як хост статичних членів

Найчастіше вам потрібно objectутримувати методи та значення / змінні, які мають бути доступними без необхідності спочатку інстанціювати екземпляр якогось класу. Це використання тісно пов'язане з staticучасниками Java.

object A {
  def twice(i: Int): Int = 2*i
}

Потім можна зателефонувати вище за допомогою методу A.twice(2).

Якщо ви twiceбули членом якогось класу A, то вам потрібно спочатку зробити екземпляр:

class A() {
  def twice(i: Int): Int = 2 * i
}

val a = new A()
a.twice(2)

Ви можете бачити, наскільки це зайве, оскільки twiceне вимагає даних, що стосуються конкретних примірників.

object як спеціальний названий екземпляр

Ви також можете використовувати objectсебе як якийсь спеціальний екземпляр класу чи ознаки. Коли ви робите це, ваш об'єкт повинен розширити деякі trait, щоб стати екземпляром його підкласу.

Розглянемо наступний код:

object A extends B with C {
  ...
}

Ця декларація спочатку оголошує анонімний (недоступний) клас, який розширює Bі C, і інстанціює один екземпляр цього класу з назвою A.

Це Aможе передаватися функціям, що очікують об'єктів типу Bабо C, або B with C.

Додаткові особливості object

Також у Scala існують деякі особливості об’єктів. Рекомендую ознайомитися з офіційною документацією .

  • def apply(...) дозволяє звичайний метод без імен синтаксис A(...)
  • def unapply(...)дозволяє створювати спеціальні екстрактори для відповідних шаблонів
  • якщо супроводжує однойменний клас, об'єкт бере на себе особливу роль при вирішенні неявних параметрів

38
Він також визначить клас A та створить усі методи в об'єкті A як статичні методи класу A (для взаємодії з Java). (Модуло помилка в Scala 2.7, що було виправлено в Scala 2.8)
Кен Блум

2
@KenBloom справді? Я намагався і не працює: scala> Commerce res8: Commerce.type = Commerce $ @ 6eb2756 scala> classOf [Commerce] <console>: 23: помилка: не знайдено: введіть Commerce classOf [Commerce] ^ scala> new Commerce < console>: 23: error: not found: введіть Commerce new Commerce ^
Hendy Irawan

3
@Hendy: Scala не розпізнає Commerceклас, але JVM та мова Java будуть. (Ось як ви можете це зробити object Foo{ def main(args:Seq[String]) }та очікуйте запуску програми.)
Кен Блум

3
Я думаю, що відповідь ziggystar є більш точною, клас - це анонімний клас, якщо тільки явно не визначений відповідний клас з назвою Commerce (тоді об'єкт Commerce буде супутнім об’єктом класу Commerce)
Хенді Іраван

3
@DavidApltauer Я гадаю, що є достатньо тонкощів, які не охоплені моєю відповіддю. Але це, мабуть, не має значення для більшості людей, які читають це. І я ніколи не мав проблем із передачею об'єкта як екземпляра якоїсь ознаки, це не означає, що їх не існує; але це має працювати.
ziggystar

249

А class- це визначення, опис. Він визначає тип з точки зору методів та складу інших типів.

Один objectсингл - екземпляр класу, який гарантовано є унікальним. Для кожного objectв коді створюється анонімний клас, який успадковується від усіх класів, які ви заявили objectпро реалізацію. Цей клас не можна побачити з вихідного коду Scala - хоча ви можете отримати його за допомогою відображення.

Існує зв’язок між objectі class. Об'єкт, як кажуть, є об'єктом-супутником класу, якщо вони мають однакове ім'я. Коли це відбувається, кожен має доступ до методів privateвидимості в іншому. Однак ці методи не імпортуються автоматично. Вам або потрібно імпортувати їх явно, або префіксувати їх іменем класу / об'єкта.

Наприклад:

class X {
  // class X can see private members of object X
  // Prefix to call
  def m(x: Int) = X.f(x)

  // Import and use
  import X._
  def n(x: Int) = f(x)

  private def o = 2
}

object X {
  private def f(x: Int) = x * x

  // object X can see private members of class X
  def g(x: X) = {
    import x._
    x.o * o // fully specified and imported
   }
}

1
Вибачте, що вас турбує, але чи не могли б ви вказати на приклад про те, як імпортувати методи до супутнього об’єкта чи як їх префіксувати?
ithkuil

4
@ithkuil Готово. Вибачте за дурний приклад, я не міг придумати хорошого і короткого.
Даніель Ч. Собрал

Що робити, якщо я хочу використовувати метод класу в Object? Це було б можливо? Якщо у мене є метод класу і я хочу його використовувати в Object, то, якщо ви спробуєте імпортувати клас, ви не зможете. Врешті-решт, вам доведеться створити конструктор і викликати метод. Отже, зробивши супутні об’єкти, ви можете отримати доступ до методів Object за допомогою імпорту, але не навпаки. Чи може хтось, будь ласка, підтвердити?
piyushGoyal

@piyushGoyal Неправда. Скажімо, в об'єкті є метод def f(x: X) = ???, тоді він буде в змозі викликати приватні методи xкласу-супутника X.
Даніель К. Собрал

Тут переданий у функції X примірник класу XI здогадується? Якщо так, то врешті ви використовуєте об'єкт x для виклику методу класу X у def f .. Так?
piyushGoyal

76

Об'єкт має рівно один екземпляр (дзвонити не можна new MyObject). Ви можете мати кілька примірників класу.

Об'єкт виконує ті ж (і деякі додаткові) цілі , що і статичні методи та поля в Java.


19

Як було пояснено багатьма, objectвизначає однотонний екземпляр. Єдине, що у відповідях тут є, що я вважаю, що це осторонь, це те, що objectслужить декільком цілям.

  • Він може бути супутниковим об'єктом до class/ trait, що містить статичні або зручні методи.

  • Він може діяти так само, як модуль, містить пов'язані / допоміжні типи та визначення тощо.

  • Він може реалізувати інтерфейс, розширивши a classабо одну або кілька traits.

  • Він може представляти випадок, sealed traitщо не містить даних. У цьому відношенні його часто вважають правильнішим, ніж case classпараметри без параметра. Особливий випадок sealed traitіз лише case objectреалізаторами - це більш-менш версія Scala enum.

  • Це може слугувати доказом для implicitлогіки -провідної.

  • Він вводить однотонний тип.

Це дуже потужна і загальна конструкція. Що може дуже бентежити початківців Scala, це те, що одна і та ж конструкція може мати дуже різні види використання. І objectможе служити багатьом із цих різних цілей використання відразу, що може бути ще більше заплутати.


18

Визначення об'єкта в Scala - це як визначення класу на Java, який має лише статичні методи. Однак у Scala об’єкт може розширювати інший надклас, реалізовувати інтерфейси та передаватись так, ніби це був екземпляр класу. (Так це як статичні методи на класі, але краще).


17

Формальна різниця -

  1. не можна надати параметри конструктора для об’єктів
  2. Об'єкт не типу - ви не можете створювати екземпляр з новим оператором. Але він може мати поля, методи, розширювати надклас і змішувати в ознаках.

Різниця у використанні:

  • У Scala немає статичних методів чи полів. Натомість слід використовувати object. Ви можете використовувати його з відповідним класом або без нього. У 1-му випадку це називається супутнім об'єктом. Ти мусиш:
    1. використовувати те саме ім’я як для класу, так і для об'єкта
    2. помістити їх у той самий вихідний файл.
  • Для створення програми слід використовувати основний метод в object, а не в class.

    object Hello {
      def main(args: Array[String]) {
        println("Hello, World!")
      }
    }
  • Ви також можете використовувати його, коли ви використовуєте одиночний об'єкт у Java.

      
        
      


"Ви не можете надати параметри конструктора для Об'єктів" Об'єкти мають метод застосовувати (...), який функціонує дуже, як конструктор. Це залишає мене трохи розгубленим.
Даніель

7

Об'єкт ключове слово створює новий тип одноплодной, який , як клас , який має тільки один іменований екземпляр. Якщо ви знайомі з Java, оголошення об’єкта в Scala дуже схоже на створення нового екземпляра анонімного класу.

Scala не має еквівалента статичному ключовому слову Java , і об'єкт часто використовується в Scala, де ви можете використовувати клас зі статичними членами на Java.


6

Об'єкт - це клас, але він вже має (є) екземпляр, тому ви не можете телефонувати new ObjectName. З іншого боку, Class просто тип, і він може бути екземпляром, зателефонувавши new ClassName().


4

У масштабі staticпоняття немає . Таким чином, scala створює одиночний об'єкт, щоб забезпечити точку входу для виконання вашої програми. Якщо ви не створите одиночний об’єкт, ваш код буде складено успішно, але не видасть жодного результату. Методи, оголошені всередині Singleton Object, доступні у всьому світі. Один об'єкт може розширювати класи та ознаки.

Приклад об'єкта Scala Singleton

object Singleton{  
    def main(args:Array[String]){  
        SingletonObject.hello()         // No need to create object.  
    }  
}  


object SingletonObject{  
    def hello(){  
        println("Hello, This is Singleton Object")  
    }  
}  

Вихід:

Hello, This is Singleton Object

У масштабі, коли у вас є клас з тим самим іменем, що й об'єкт Singleton, він називається класом-супутником, а одиночний об'єкт називається об'єктом-супутником.

Клас-супутник та його супутний об'єкт повинні бути визначені в одному вихідному файлі.

Приклад об'єкта Scala Companion

class ComapanionClass{  
    def hello(){  
        println("Hello, this is Companion Class.")  
    }  
}  
object CompanoinObject{  
    def main(args:Array[String]){  
        new ComapanionClass().hello()  
        println("And this is Companion Object.")  
    }  
}  

Вихід:

Hello, this is Companion Class.
And this is Companion Object.

У системі Scala клас може містити:

1. Член даних

2. Метод члена

3. Блок конструктора

4. Вкладений клас

5. Інформація про суперкласи тощо.

Ви повинні ініціалізувати всі змінні екземпляра в класі. Не існує типової області застосування. Якщо не вказати область доступу, вона є загальнодоступною. Повинно бути об'єкт, у якому визначено основний метод. Це дає вихідну точку для вашої програми. Тут ми створили приклад класу.

Приклад шкали Скала класу

class Student{  
    var id:Int = 0;                         // All fields must be initialized  
    var name:String = null;  
}  
object MainObject{  
    def main(args:Array[String]){  
        var s = new Student()               // Creating an object  
        println(s.id+" "+s.name);  
    }  
} 

Мені шкода, я запізнився, але сподіваюся, що це допоможе тобі.


2

Клас Scala такий же, як Java Class, але scala не дає вам жодного методу введення в клас, як основний метод у java. Основний метод, пов'язаний з ключовим словом об'єкта. Ви можете вважати ключове слово об'єкта як створення однотонного об'єкта класу, який визначається неявно.

Додаткову інформацію перевірити цей клас статті та ключове слово в програмі Scala


2

Об'єкт певним чином схожий на статичний клас у Java, статична характеристика означає, що статичному класу не потрібно створювати об’єкт при надходженні в JVM, він може використовуватись безпосередньо ім'ям класу та тим самим екземпляром (той самий стан даних ) ділиться скрізь, де він не використовується.


1

Клас так само, як і будь-який інший клас іншими мовами. Ви визначаєте клас так само, як і будь-яку іншу мову з певною різницею синтаксису.

class Person(val name: String)
val me = new Person("My name")

Однак об'єкт - це клас лише з одним об'єктом. Це робить його цікавим, оскільки його можна використовувати для створення статичних членів класу за допомогою супутнього об’єкта . Цей супутний об’єкт має доступ до приватних членів визначення класу і має те саме ім’я, що і клас, який ви визначаєте.

class Person(var name: String) {

  import Person._

  def hi(): String = sayHello(name)
}

object Person {
  private def sayHello(name: String): String = "Hello " + name
}

val me = new Person("My name")
me.hi()

Також слід зазначити, що клас об'єктів ліниво створюється, що є ще одним важливим моментом. Таким чином, вони не є екземплярами, якщо вони не потрібні в нашому коді.

Якщо ви визначаєте створення з'єднання для JDBC, ви можете створити їх всередині об'єкта, щоб уникнути дублювання так само, як ми робимо в Java з одиночними об'єктами.


0

Якщо ви надходите з java background, поняття class in scala схоже на Java, але клас у scala cant містить статичні члени.

Об'єкти в scala - це однотонний тип, який ви називаєте методами всередині нього, використовуючи ім'я об'єкта, у scala object - це ключове слово, а в java - об'єкт класу

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.