Lý do đằng sau việc có các đối tượng đồng hành trong Scala là gì?


107

Có trường hợp nào cần một đối tượng đồng hành (singleton) cho một lớp không? Tại sao tôi muốn tạo một lớp, chẳng hạn như Foovà tạo một đối tượng đồng hành cho nó?



Xem thêm stackoverflow.com/a/9806136/736957 là một tổng hợp các câu trả lời hay ở đây
Laughingelic

Câu trả lời:


82

Đối tượng đồng hành về cơ bản cung cấp một nơi mà người ta có thể đặt các phương thức "static-like". Hơn nữa, một đối tượng đồng hành, hoặc mô-đun đồng hành, có toàn quyền truy cập vào các thành viên trong lớp, bao gồm cả những thành viên riêng tư.

Đối tượng đồng hành rất tuyệt vời để đóng gói những thứ như phương thức gốc. Ví dụ, thay vì phải có FooFooFactoryở mọi nơi, bạn có thể có một lớp với một đối tượng đồng hành đảm nhận các trách nhiệm của nhà máy.


61

Các đối tượng đồng hành rất hữu ích để lưu trữ trạng thái và phương thức chung cho tất cả các trường hợp của một lớp nhưng chúng không sử dụng các phương thức hoặc trường tĩnh . Chúng sử dụng các phương thức ảo thông thường có thể được ghi đè thông qua kế thừa. Scala thực sự không có gì động tĩnh. Có rất nhiều cách bạn có thể sử dụng nhưng đây là một ví dụ đơn giản.

abstract class AnimalCounter
{
    var animals = 0

    def name: String

    def count()
    {
        animals += 1
        println("%d %ss created so far".format(animals, name))
    }
}

abstract class Animal
{
    def companion: AnimalCounter
    companion.count()
}

object Dog extends AnimalCounter
{
    val name = "dog"
}

class Dog extends Animal
{
    def companion = Dog
}

object Cat extends AnimalCounter
{
    val name = "cat"
}

class Cat extends Animal
{
    def companion = Cat
}

Cái nào tạo ra đầu ra này:

scala> new Dog
1 dogs created so far

scala> new Cat
1 cats created so far

scala> new Dog
2 dogs created so far

scala> new Cat
2 cats created so far

1
minh họa tương tự cũng có thể được tìm thấy tại đây: daily-scala.blogspot.sk/2009/09/companion-object.html
xhudik 21/12/12

30

... và đó là một nơi tốt để lưu trữ các phương thức static factory (không phải DP đó) cho các lớp đi kèm. Nếu bạn đặt tên các phương thức nhà máy quá tải đó là áp dụng (/ ... /), bạn sẽ có thể tạo / khởi tạo lớp của mình

  1. không có 'mới' (không thực sự quan trọng)

  2. với các bộ tham số có thể có khác nhau (so sánh với những gì Bloch viết trong Java hiệu quả về hàm tạo telescoping)

  3. với khả năng quyết định lớp dẫn xuất nào bạn muốn tạo thay vì lớp trừu tượng (kèm theo)

Mã ví dụ:

abstract class AbstractClass;
class RealThing(s: String) extends AbstractClass;
class AlternativeThing(i: Int) extends AbstractClass;
object AbstractClass {
  def apply(s: String) = {
    new RealThing(s)
  }
  def apply(i: Int) = {
    new AlternativeThing(i)
  }
}

// somewhere else you can
val vs = AbstractClass("asdf")  // gives you the RealThing wrapped over string
val vi = AbstractClass(123)  // gives you AlternativeThing wrapped over int

Tôi sẽ không gọi đối tượng / lớp cơ sở là AbstractXxxxx vì nó trông không tệ: giống như tạo ra một cái gì đó trừu tượng. Cung cấp cho những cái tên một ý nghĩa thực sự. Hãy xem xét sử dụng các lớp không thay đổi, phương thức less, các lớp trường hợp và niêm phong lớp cơ sở trừu tượng.


2
RealThingAlternativeThinglớp nên có một phương thức privatekhởi tạo để buộc người dùng sử dụng AbstractClasshas factory. class AlternativeThing private(i: Int) extends AbstractClass
metch

@ [Szymon Jachim] Lớp trừu tượng Scala không hỗ trợ đa kế thừa. Vậy tại sao trình biên dịch lại cho phép nó trong trường hợp của bạn?
user2441441

19

Ngoài những điều Saem đã nói trong câu trả lời của mình , trình biên dịch Scala cũng tìm kiếm các chuyển đổi ngầm định của các loại trong các đối tượng đồng hành tương ứng (của nguồn hoặc đích), vì vậy các chuyển đổi không cần phải được nhập.

Về lý do cho các đối tượng singleton nói chung Lập trình trong Scala nói:

Như đã đề cập trong Chương 1, một cách mà Scala hướng đối tượng hơn Java là các lớp trong Scala không thể có các thành viên tĩnh. Thay vào đó, Scala có các đối tượng singleton (trang 65).


3

Tôi luôn xem các đối tượng đồng hành là cầu nối để viết cả mã chức năng và hướng đối tượng trong Scala. Nhiều khi chúng ta chỉ cần các hàm thuần túy lấy một số đầu vào và cung cấp kết quả xử lý. Việc đưa các chức năng có liên quan đó vào đối tượng đồng hành sẽ giúp bạn dễ dàng tra cứu và sử dụng, cho bản thân tôi cũng như một số người đang xây dựng trên mã của tôi.

Hơn nữa, nó là một ngôn ngữ được cung cấp tính năng để viết mẫu đơn mà không cần làm gì cả. Điều này đặc biệt hữu ích khi bạn cần một singleton để đóng gói một người ủy quyền cho vòng đời của JVM. Ví dụ: viết một thư viện máy khách HTTP đơn giản trong Scala, nơi bạn có thể đóng gói bộ ủy nhiệm triển khai Java cơ bản và cho phép người tiêu dùng API của bạn sống trong thế giới thuần túy.


0

Nếu bạn xác định lớp và đối tượng trong cùng một tệp có cùng tên, chúng được gọi là lớp và đối tượng đồng hành. Scala không có từ khóa static as JAVA, Bạn có thể thay thế static as static bằng đối tượng và lớp đồng hành trong Scala.

Để biết thêm thông tin chi tiết, vui lòng kiểm tra lớp bài viết và từ khóa đối tượng trong lập trình scala


-1

Lúc đầu, nó cung cấp sự tách biệt rõ ràng giữa các phương thức static và non static method, đồng thời cung cấp một cách đơn giản để tạo lớp singleton.

Nó cũng có thể kế thừa các phương thức từ các lớp và / hoặc đặc điểm khác, điều này không thể thực hiện được với các phương thức tĩnh Java. Và có thể được truyền dưới dạng tham số.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.