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ư Foo
và tạo một đối tượng đồng hành cho nó?
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ư Foo
và tạo một đối tượng đồng hành cho nó?
Câu trả lời:
Đố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ó Foo
và FooFactory
ở 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.
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
... 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
không có 'mới' (không thực sự quan trọng)
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)
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.
RealThing
và AlternativeThing
lớp nên có một phương thức private
khởi tạo để buộc người dùng sử dụng AbstractClass
has factory. class AlternativeThing private(i: Int) extends AbstractClass
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).
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.
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
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ố.