是否可以将 class 的实例转换为子 class 的实例?
Is it possible to convert instance of a class to an instance of a subclass?
我最近遇到一个案例,将 class 的实例转换为子 class 的实例非常方便,而实例是在父 [=] 中创建的27=]。但我从未见过这样的事情。那么有没有办法做这样的事情:
class Foo {
var name: String
}
class Bar: Foo {
var friendName: String
}
let foo = Foo(name: "Alice")
foo.toBar(friendName: "Bob")
// foo now of type Bar, as if I'd done
// foo = Bar(name: "Alice", friendName: "Bob")
如果那不可能,从设计的角度来看是否有某些原因是不可能的?
===edit=== 有意义的用例描述
假设有两个视图表示对应于一本书的同一数据库记录的内容,一个是该书的预览,另一个是更复杂的视图。模型可以是:
protocol BookMetaDelegate {
func onReadStatusUpdate()
}
/// describe a book
class BookMeta {
var delegate: BookMetaDelegate?
private var _hasBeenRead: Bool
var hasBeenRead: Bool {
get {
return _hasBeenRead
}
set {
guard newValue != _hasBeenRead else { return }
_hasBeenRead = newValue
delegate?.onReadStatusUpdate()
}
}
var title: String
}
/// contains all the content of a book
class Book: BookMeta {
var content: BookContent
var lastPageRead: Int
/// some logic that only makes sense in a Book instance
func getLastPageRead() {
return content.getPage(lastPageRead)
}
}
视图可能如下所示:
class BookPreview: UIView, BookMetaDelegate {
var book: BookMeta
init(book: BookMeta) {
book.delegate = self
}
func onReadStatusUpdate() {
print("read status has changed! UI should update")
}
}
class BookView: UIView {
var book: Book
init(book: Book) {
book.hasBeenRead = true
}
}
然后事情可能会发生
fetch(bookMetaWithId: 123).then { bookMeta in // bookMeta is of type BookMeta
let preview = BookPreview(book: bookMeta)
...
fetch(contentOf: bookMeta).then { content, lastPageRead in
bookMeta.asBook(content: content, lastPageRead: lastPageRead)
let bookView = BookView(book: bookMeta) // doing so will change the hasBeenRead flag and message the instance's delegate, ie the preview
...
}
}
仔细想想,听起来如果可能的话,它会破坏像这样的东西:
class Foo {
var name: String
}
class Bar: Foo {
var friendName: String
}
class Bla: Foo {
var surname: String
}
func something(foo: Foo) {
foo.toBla(surname: "Will")
}
let bar = Bar(name: "Alice", friendName: "Bob")
something(foo: bar) // what does that do ??? is bar a Bla now ?
所以这就是使这种转换成为不可能的一个很好的理由。
我最近遇到一个案例,将 class 的实例转换为子 class 的实例非常方便,而实例是在父 [=] 中创建的27=]。但我从未见过这样的事情。那么有没有办法做这样的事情:
class Foo {
var name: String
}
class Bar: Foo {
var friendName: String
}
let foo = Foo(name: "Alice")
foo.toBar(friendName: "Bob")
// foo now of type Bar, as if I'd done
// foo = Bar(name: "Alice", friendName: "Bob")
如果那不可能,从设计的角度来看是否有某些原因是不可能的?
===edit=== 有意义的用例描述
假设有两个视图表示对应于一本书的同一数据库记录的内容,一个是该书的预览,另一个是更复杂的视图。模型可以是:
protocol BookMetaDelegate {
func onReadStatusUpdate()
}
/// describe a book
class BookMeta {
var delegate: BookMetaDelegate?
private var _hasBeenRead: Bool
var hasBeenRead: Bool {
get {
return _hasBeenRead
}
set {
guard newValue != _hasBeenRead else { return }
_hasBeenRead = newValue
delegate?.onReadStatusUpdate()
}
}
var title: String
}
/// contains all the content of a book
class Book: BookMeta {
var content: BookContent
var lastPageRead: Int
/// some logic that only makes sense in a Book instance
func getLastPageRead() {
return content.getPage(lastPageRead)
}
}
视图可能如下所示:
class BookPreview: UIView, BookMetaDelegate {
var book: BookMeta
init(book: BookMeta) {
book.delegate = self
}
func onReadStatusUpdate() {
print("read status has changed! UI should update")
}
}
class BookView: UIView {
var book: Book
init(book: Book) {
book.hasBeenRead = true
}
}
然后事情可能会发生
fetch(bookMetaWithId: 123).then { bookMeta in // bookMeta is of type BookMeta
let preview = BookPreview(book: bookMeta)
...
fetch(contentOf: bookMeta).then { content, lastPageRead in
bookMeta.asBook(content: content, lastPageRead: lastPageRead)
let bookView = BookView(book: bookMeta) // doing so will change the hasBeenRead flag and message the instance's delegate, ie the preview
...
}
}
仔细想想,听起来如果可能的话,它会破坏像这样的东西:
class Foo {
var name: String
}
class Bar: Foo {
var friendName: String
}
class Bla: Foo {
var surname: String
}
func something(foo: Foo) {
foo.toBla(surname: "Will")
}
let bar = Bar(name: "Alice", friendName: "Bob")
something(foo: bar) // what does that do ??? is bar a Bla now ?
所以这就是使这种转换成为不可能的一个很好的理由。