LSP(Liskov替代原理)指出: 该原理定义了超类的对象可以用其子类的对象替换,而不会破坏应用程序。
例如:
func didJoinGroupConvo(groupConvoId: String) {
guard !joinedGroupConvoIds.contains(groupConvoId) else { return }
joinedGroupConvoIds.append(groupConvoId)
guard
let row = suggestedGroups.firstIndex(where: { $0.id == groupConvoId }),
let cell = tableView.cellForRow(at: IndexPath(row: row, section: 0)) as? GroupMessageSettingsUserCell,
let currentUser = PFUser.current(),
let currentUserId = currentUser.objectId,
let currentUsername = currentUser.username
else { return }
// If I comment out starting here, it won't block. Otherwise, as long as it's doing this call, it will block the UI
DispatchQueue.global(qos: .background).async {
Firestore.Collections.groupConvos.path
.document(groupConvoId)
.updateData([
kMemberIds: FieldValue.arrayUnion([currentUserId]),
kUpdatedAt: FieldValue.serverTimestamp()
]) { [weak self] error in
guard let self = self else { return }
if error == nil {
guard row < self.suggestedGroups.count else { return }
let groupConvo = self.suggestedGroups[row]
NotificationCenter.default.post(name: NSNotification.Name("Joined"), object: groupConvo)
DispatchQueue.main.async {
cell.nameLabel?.text = "\(groupConvo.memberCount + 1) members"
}
let message = GroupMessage.createJoinLeftSystemMessage(joined: true, groupName: groupConvo.groupName, username: currentUsername)
message.saveMessage(to: groupConvo, withMessageType: .system) { _ in
self.delegate?.didJoinGroup(withGroupId: groupConvoId)
}
}
}
}
}
以上语句在内存级别如何工作(如何工作)? 创建“汽车”类是为了实现汽车具有但普通车辆缺乏的特定行为。
如何将“ BMW”对象称为车辆类别?
答案 0 :(得分:0)
LSP与您使用的变量和引用的可替换性有关。一个常见的示例是使用collections api:
ArrayList<String> someList = new ArrayList<>();
可以,但是假设我们有一个list方法:
public void printList(LinkedList<String> printedList) { ... }
现在,我们无法将ArrayList<String>
传递给LinkedList<String>
参数,因为它们是不同的类型!但是,我们所需的唯一实际功能不是LinkedList
或ArrayList
的特定功能,而是List
本身的特定功能。因此,我们以可替代的方式
List<String> someList = new ArrayList<>(); //still an arraylist!
public void printList(List<String> printedList) { ... } //any list type
现在我们可以传递参数了,因为我们不必不必要地绑定到不需要其功能的子类型。
就内存级别而言,这些对象在堆内存中仍然是相同的对象,您只需将它们称为它们的超类型即可(实际上,如果知道类型,则可以对其进行下转换)。
因此,以您的示例为例,您可能会遇到一种情况,即存在的任何车辆都有颜色。所以我们有方法:
public class Vehicle {
public Color getColor() { ... }
public void setColor(Color color) { ... }
}
在此过程中,Vehicle
的 any 子类将具有颜色方法,但与BMW
或{{1} }。但是,这与继承比LSP更相关。
答案 1 :(得分:0)
LSP 说,当我们扩展一个类时,子类和超类之间的关系必须是 IS A 。在您的示例中,汽车 IS A 车辆。因此,当Car类扩展Vehicle时,不会违反LSP。
在内存级别中,创建了一个由Vehicle引用的Car对象。并且BMW参考将能够访问Vehicle的所有公共和受保护的方法,实例变量。