疑问:抽象类NumberTriviaRepository的实例如何调用其方法?
抽象类NumberTriviaRepository的方法调用原理
核心是通过依赖注入+依赖倒置原则实现的,具体流程如下:
抽象类定义功能契约
NumberTriviaRepository作为抽象类,只声明需要实现的方法签名(比如getConcreteNumberTrivia、getRandomNumberTrivia),它的作用是定义一套功能标准,不涉及具体逻辑。具体实现类继承并实现逻辑
独立文件中的具体实现类(比如NumberTriviaRepositoryImpl)会继承这个抽象类,并重写所有抽象方法,完成实际的业务逻辑(比如调用远程API、操作本地缓存)。通过依赖注入注入具体实例
在需要使用抽象类的地方(比如业务用例、Bloc),不会直接创建具体实现类的实例,而是借助依赖注入框架(如GetIt、Provider),将NumberTriviaRepositoryImpl的实例以NumberTriviaRepository的类型注入进去。依赖方只需要依赖抽象类,就能调用到具体实现的方法。
代码示例
// 抽象类文件 abstract class NumberTriviaRepository { Future<NumberTrivia> getConcreteNumberTrivia(int number); Future<NumberTrivia> getRandomNumberTrivia(); } // 具体实现文件 class NumberTriviaRepositoryImpl implements NumberTriviaRepository { final NumberTriviaRemoteDataSource remoteDataSource; final NumberTriviaLocalDataSource localDataSource; NumberTriviaRepositoryImpl({ required this.remoteDataSource, required this.localDataSource, }); @override Future<NumberTrivia> getConcreteNumberTrivia(int number) async { // 具体业务逻辑:优先查本地缓存,无数据则调用远程API,最后更新缓存 // 省略具体实现细节 } @override Future<NumberTrivia> getRandomNumberTrivia() async { // 具体业务逻辑:获取随机数并调用API // 省略具体实现细节 } } // 依赖注入配置(以GetIt为例) final sl = GetIt.instance; void initDependencyInjection() { // 注册具体实现,对外暴露抽象类类型 sl.registerLazySingleton<NumberTriviaRepository>( () => NumberTriviaRepositoryImpl( remoteDataSource: sl(), localDataSource: sl(), ), ); } // 使用场景(比如业务用例) class GetConcreteNumberTrivia { final NumberTriviaRepository repository; GetConcreteNumberTrivia(this.repository); Future<Either<Failure, NumberTrivia>> execute(int number) async { // 此处调用抽象类方法,实际执行的是具体实现类的逻辑 return await repository.getConcreteNumberTrivia(number); } }
这种设计符合Clean Architecture的理念,高层模块(业务用例、Bloc)依赖抽象而非具体实现,既降低了模块间的耦合,也方便后续替换实现逻辑或编写单元测试(用Mock类替代具体实现)。
内容的提问来源于stack exchange,提问作者Arnob
相关产品推荐
相关产品推荐

