Giao thức Swift có thể cung cấp việc triển khai mặc định cho các hàm và thuộc tính được tính bằng cách thêm tiện ích vào chúng. Tôi đã làm rất nhiều lần. Đó là sự hiểu biết của tôi rằng việc triển khai mặc định chỉ được sử dụng làm "dự phòng": Nó được thực thi khi một loại phù hợp với giao thức nhưng không cung cấp việc triển khai riêng của nó.Thực hiện một hàm có tham số mặc định được xác định trong giao thức
Ít nhất đó là cách tôi đọc The Swift Programming Language dẫn:
Nếu một loại Tuân cung cấp thực hiện riêng của mình một phương pháp cần thiết hoặc tài sản, thực hiện sẽ được sử dụng thay cho một cung cấp bởi phần mở rộng.
Bây giờ tôi chạy vào một tình huống mà kiểu tùy chỉnh của tôi mà thực hiện một giao thức nhất định không cung cấp một thực hiện một chức năng cụ thể nhưng nó không thực hiện - thực hiện theo quy định tại phần mở rộng giao thức được thực hiện để thay thế.
Như một ví dụ, tôi xác định một giao thức Movable
mà có một chức năng move(to:)
và một phần mở rộng cung cấp một cài đặt mặc định cho chức năng này:
protocol Movable {
func move(to point: CGPoint)
}
extension Movable {
func move(to point: CGPoint = CGPoint(x: 0, y: 0)) {
print("Moving to origin: \(point)")
}
}
Tiếp theo, tôi định nghĩa một lớp Car
rằng phù hợp với Movable
nhưng cung cấp triển khai riêng cho chức năng move(to:)
:
class Car: Movable {
func move(to point: CGPoint = CGPoint(x: 0, y: 0)) {
print("Moving to point: \(point)")
}
}
Bây giờ tôi tạo ra một mới Car
và downCast nó như là một Movable
:
let castedCar = Car() as Movable
Tùy thuộc vào việc tôi vượt qua một giá trị cho tham số tùy chọn point
tôi quan sát hai hành vi khác nhau:
Khi chuyển một điểm cho thông số tùy chọn
→ việc thực hiện 's
Car
được gọi:castedCar.move(to: CGPoint(x: 20, y: 10))
Output:
Di chuyển đến thời điểm: (20.0, 10.0)
Khi tôi gọi
move()
chức năng mà không cung cấp giá trị cho các tham số tùy chọn việc thực hiện 'sCar
bị bỏ qua và→ triển khai mặc định của giao thức
Movable
được gọi thay vì:castedCar.move()
Output:
Di chuyển đến xuất xứ: (0,0, 0,0)
tôi tin rằng các giá trị mặc định được thêm vào lúc biên dịch do đó loại tĩnh của biến phải được sử dụng. – Sulthan
Bạn đang truyền ô tô sang Movable để nó sẽ gọi phương thức Movable. Nếu bạn không cast Car to Movable, nó sẽ gọi phương thức di chuyển của ô tô của bạn –
@LeoDabus: Bạn đúng rằng nếu tôi không đưa 'Car' sang' Movable' thì tôi không gặp vấn đề này. Tuy nhiên, lý do tại sao vấn đề xảy ra khi tôi _do_ thực hiện dàn diễn viên là toàn bộ vấn đề của câu hỏi của tôi. Trong một thực hiện theo định hướng giao thức thực tế, tôi sẽ không biết lớp thực sự của đối tượng mà tôi đang xử lý - tôi chỉ biết rằng nó tuân theo giao thức 'Movable'. Dòng 'let castedCar = Car() là Movable' chỉ đơn giản là phương tiện để bắt chước tình huống này để giữ mã ví dụ rõ ràng. – Mischa