2014-09-30 22 views
13

Khi tôi cố gắng ghi đè thuộc tính, tôi nhận được lỗi "không thể ghi đè thuộc tính có thể thay đổi với thuộc tính chỉ đọc"Ghi đè thuộc tính Swift không hoạt động

Tôi đã cung cấp và đặt trong lớp học siêu hạng.

class Card { 
    var contents:String { 
     get { 
      return self.contents 
     } 
     set { 
      self.contents = newValue 
     } 
    } 
    init() { 
     self.contents = "" 
    } 
} 

Đây là lớp con của tôi nơi tôi đang cố gắng ghi đè thuộc tính "nội dung".

class PlayingCard: Card { 
    override var contents:String { //<-- this is where I get the build error 
     get { 
      var rankStrings:Array<String> = PlayingCard.rankStrings() 
      return rankStrings[Int(self.rank)] + self.suit 
     } 
    } 
} 

Chính xác thì tôi đang làm gì sai?

Trả lời

2

Thông báo lỗi biên dịch là khá đơn giản: contents tài sản Card 's là mutable, mà là để nói nó có một phương pháp set ngoài các phương pháp get.

Ghi đè của bạn chỉ thêm phương thức get, bạn cũng cần thêm phương thức set.

Tôi nghĩ rằng đây là những gì bạn muốn:

set(newValue) { 
    rankStrings[Int(self.rank)] = newValue; 
} 
+0

'newValue' là mặc định, phải không? Vì vậy, bạn chỉ có thể sử dụng 'set {', tôi nghĩ –

18

Nếu thuộc tính bạn đang trọng có cả một getter và setter, bạn cần phải cung cấp cả trong lớp con của bạn là tốt. Dưới đây là (tôi nhấn mạnh) relevant part from the Swift language guide:

Bạn có thể trình bày một kế thừa thuộc tính chỉ đọc như đọc-viết bất động sản bằng cách cung cấp cả một getter và setter trong lớp con ghi đè tài sản của bạn. Tuy nhiên, bạn không thể hiển thị thuộc tính được đọc thừa kế là tài sản chỉ đọc.

Nếu bạn không làm bất cứ điều gì đặc biệt với giá trị, sau đó bạn sẽ thường muốn vượt qua giá trị được thiết lập vào lớp cơ sở:

set { 
    super.contents = newValue 
} 

Bạn cũng có thể chỉ là loại bỏ các giá trị với một setter rỗng (mặc dù tôi không thể nghĩ ra một lý do chính đáng để làm ăn nói lấc cấc này):

set { } 

tôi cũng muốn po cho biết bạn có vòng lặp vô hạn trong thuộc tính contents trong lớp Card của bạn. Khi bạn làm điều này:

get { 
    return self.contents 
} 

Bạn đang thực sự chỉ gọi cùng một getter một lần nữa, tạo vòng lặp vô hạn; bạn đang làm tương tự với setter. Swift không tạo ra các thuộc tính cho các thuộc tính của bạn một cách tự động như Objective-C, vì vậy bạn cần tự tạo chúng.Một cách thích hợp hơn để tạo ra tài sản đó sẽ được để làm một cái gì đó như thế này:

class Card { 
    private var _contents: String 
    var contents: String { 
     get { 
      return _contents 
     } 
     set { 
      _contents = newValue 
     } 
    } 
    init() { 
     _contents = "" 
    } 
} 

Tuy nhiên, vì bạn không làm bất cứ điều gì khác hơn là thiết lập và trở về _contents trong setter và getter của bạn, bạn có thể đơn giản hóa nó xuống này:

class Card { 
    var contents: String = "" 
    init() { 

    } 
} 

Lưu ý:contents cũng có thể là một ứng cử viên tốt cho việc sử dụng một tùy chọn (String?) và thiết lập nó để nil chứ không phải khởi tạo nó thành một chuỗi rỗng.

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