You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Dart中结合真实场景实现里氏替换原则(LSP)

里氏替换原则(LSP)指出,父类对象应当能够被子类对象替换,且不会影响程序的正确性。换句话说,子类应当可以替换其父类而不破坏代码运行。

我正在探索如何在真实场景中实现这一原则,要求代码中处处使用父类类型,仅在实例化时使用子类。以下是我的实现思路:

初步实现

class User {
  const User({
    required this.id,
    required this.avatar,
  });

  final String id;
  final String avatar;
}

class UserWithName extends User {
  const UserWithName(
      {required super.id, required super.avatar, required this.name});

  final String name;

}

void main() {
  User userWithName = new UserWithName(id: '0', avatar: 'avatar', name: 'User Name');
  
  print('hello ${(userWithName as UserWithName).name}');
}

这种实现方式不够优雅,必须用as UserWithName做类型转换才能访问子类特有的属性。

如果新增的是功能而非参数,为了符合LSP我尝试了另一种实现,但这又违反了开闭原则:

违反开闭原则的实现

class User {
  const User({
    required this.id,
    required this.avatar,
  });

  final String id;
  final String avatar;

  String? getName() => null;
}

class UserWithName extends User {
  const UserWithName(
      {required super.id, required super.avatar, required this.name});

  final String name;

  String getName() => this.name;
}

void main() {
  User user = new User(id: '0', avatar: 'avatar');
  User userWithName = new UserWithName(id: '0', avatar: 'avatar', name: 'User Name');

  print('hello ${user.getName()}');
  print('hello ${userWithName.getName()}');
}

运行结果

hello null
hello User Name

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 13:12:46