1
私は最近、インスタンスが親クラス内で作成されている間に、クラスのインスタンスをサブクラスに変換するのが非常に便利なケースを見つけました。しかし、私はそのようなことを見たことがない。それが不可能な場合クラスのインスタンスをサブクラスのインスタンスに変換することは可能ですか?
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")
、これは設計の観点からは不可能であろういくつかの理由がある:だからのような何かをする方法はありますか?
===編集===それだけのプレビューで上の感覚
レッツは、この本のために同じデータベースレコードに対応するもの表す2つのビューがあると言う作ることができユースケースの説明本と別のものはもっと複雑な視点です。モデルは次のようになります。
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)
}
}
とビューは次のようになります。物事はそれについての詳細を考える
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
...
}
}
いいえ、不可能です。既存の 'Foo'から* new *' Bar'を作成することは可能ですが、既存のオブジェクトのタイプを変更することはできません。そうすることでメリットはありません。 –
そうすることでなぜメリットがないのでしょうか?それはより多くの視点です。ユーザーのプロファイルを表す2つのクラスと、他の多くの情報を持つユーザーがあるとしましょう。最初にプロファイルをロードし、後で他の情報を取得します。私はその後、余分なデータを使って自分のUserProfileインスタンスをダウンキャストしたいかもしれません。 – Guig
"ダウンキャスト"を間違って使用しています - あなたはオブジェクトの実際のタイプにダウンキャストします。あなたの例では、新しいオブジェクトを作成することや、元のクラスの "その他の情報"オプションのプロパティにすることに利点はありません。だからこそ利益はないのです。 「ユーザーのプロファイルを表す2つのクラスと他の多くの情報を持つユーザー」を持つことが実際の問題のようです。より良いデザインを作成することは、タイプシステムを完全に破るよりはるかに賢明です。 –