2015-02-26 13 views
12

Tôi có một lớp trừu tượng mà tôi mở rộng và tạo ra nhiều lớp chữ hoa chữ thường. Bây giờ tôi muốn sao chép các cá thể của các trường hợp này chỉ thay đổi tham số đầu tiên, vì vậy tôi sử dụng phương thức 'copy' của lớp vỏ.Trường hợp thừa kế trường hợp trong Scala

Vì tôi phải làm điều này cho tất cả các trường hợp đã được mở rộng từ lớp trừu tượng phổ biến, thay vì làm nó cho tất cả, tôi đã cố gắng làm cho nó chung và tạo lớp trừu tượng thành một lớp chữ.

Sau đó Scala mang lại cho tôi thế này: class

trường hợp Octopus có trường hợp tổ tiên Sinh vật, nhưng trường hợp-to-trường hợp thừa kế đều bị cấm. Để khắc phục hạn chế này, hãy sử dụng các trình giải nén để khớp mẫu trên các nút không phải lá.

Code:

abstract class Organism(legs: Int) 
case class Octopus(override val legs: Int, weight: Double, ...) 
case class Frog(override val legs: Int, ...) 
def clone(o: Organism) = o.copy(legs = -1) 

Đây là những gì tôi muốn làm. Nhưng nếu tôi không thể thực hiện phương pháp clone, thì tôi sẽ phải sao chép cho cả hai Octopus & Frog.

Bất kỳ đề xuất nào, để giảm độ dài này?

Trả lời

10

Bạn không thể trừu tượng hóa các phương thức tổng quát về lớp học 'copy. Tôi muốn đề nghị sử dụng Ống kính từ hình thù hoặc Monocle:

trait Organism { def legs: Int } 
// monocle @Lenses uses a macro to generate lenses 
@Lenses case class Octopus(override val legs: Int, weight: Double, ...) 
    extends Organism 
@Lenses case class Frog(val legs: Int, ...) extends Organism 

def clone[O <: Organism](o: O, legsLens: Lens[O, Int]): O = 
    legsLens.set(-1)(o) 

val myOctopus = Octopus(8, 2.4, ...) 
val myFrog = Frog(2, ...) 

// use the generated Lenses 
val cloneOctopus: Octopus = clone(myOctopus, Octopus.legs) 
clone(myFrog, Frog.legs) 
0

Chỉ sử dụng scala tiêu chuẩn không có phương pháp sao chép chung chung như vậy về trừu tượng (siêu) lớp: làm thế nào nó sẽ biết làm thế nào tất cả các lớp con có thể được nhân bản/sao chép? Đặc biệt là các lớp con mới có thể được thêm vào trong tương lai.

Theo hiểu biết của tôi, hai phương pháp chính để thực hiện phương pháp trừu tượng như là:

1) thực hiện một chức năng phù hợp với hợp cụ thể trên tất cả các lớp con:

def clone(o: Organism) = o match { 
    case o: Octopus => o.copy(legs = -1) 
    case f: Frog => f.copy(legs = -1) 
} 

Sau đó, mỗi lần một lớp con mới là thêm vào, nó cần phải được thêm vào trong các chức năng này. Điều này là thích hợp nhất để sử dụng với sealed abstract class.

2) thêm một phương pháp makeClone API trừu tượng (tên clone được dành riêng):

abstract class Organism(legs: Int){ 
    def makeClone(legNumber: Int): Organism 
} 
case class Octopus(legs: Int, weight: Double) extends Organism(legs) { 
    def makeClone(legNumber: Int) = this.copy(legs = legNumber) 
} 

Lưu ý rằng trong khi các chức năng trong (1) luôn trả về một Organism, đây là phương pháp Octopus.makeClone trả về một Octopus .

Các vấn đề liên quan