我应该如何正确使用 parent class 方法和关键字 extends in typescript?
How should I properly use parent class methods and the keyword extends in typescript?
我有两个 classes,一个是 parent,一个是 child,它们实现类型来定义它们的预期功能。就在下面。
export abstract class BaseLogService implements IBaseLogService
{
static $inject: string[] = ['$http']
constructor(private $http:ng.IHttpService){
}
baseMethod1 = (objToLog): void => {
//do stuff
}
baseMethod2 = (objToLog): void => {
//do stuff
}
}
class LocalLogService extends BaseLogService implements ILocalLogService
{
constructor(private $http:ng.IHttpService){
super(this.$http);
}
localMethod1 = (): void => {
//do stuff
}
}
export interface IBaseLogService {
baseMethod1(objToLog):void;
baseMethod2(objToLog):void;
}
export interface ILocalLogService extends IBaseLogService{
localMethod1(): void;
}
该应用程序使用日志服务,并为不同的公司记录事情。与公司 B 和 C 相比,公司 A 可能会记录一些不同的内容。这就是每个公司都有本地日志服务的原因。但是所有公司都记录了一些通用的东西。所以这就是为什么有一个本地实现扩展的公共日志class。
通过所有这些介绍,我的问题是,我如何适当地利用我的 parent class' 方法?
为了进一步说明这一点,让我解释一下这是如何使用的。这是 angularjs 所以在应用程序其他地方的控制器中有一个 api POST 调用。
根据 .then() 中的调用承诺 return,需要执行 baseMethod1 以记录一些常见内容。所以它会像下面的 pseudo-code
myThingToAdd: any;
static $inject: string[] = ['localLogService']
constructor(private localLogService: ILocalLogService){}
this.myPOSTApi.addAThing(this.myThingToAdd)
.then((POSTResponse) => {
this.localLogService.baseMethod1(POSTResponse);
});
这就是我的困惑发挥作用的地方。我有一些公司特定的东西需要在调用 baseMethod1 时发生。但是因为我的服务调用直接从控制器转到 parent class,所以我跳过了需要执行本地逻辑的本地 child 服务。
我可以设置它,以便我的 .then() 服务调用转到我的本地 child class,它在调用 super.baseMethod1() 之前执行我公司特定的逻辑,但这似乎非常间接,考虑到我可以直接从我在控制器中注入的服务调用 parent class' 方法。
然后我想,我可以进行两个调用,一个用于本地逻辑,一个用于公共逻辑,每个调用各自的服务,但这对我来说似乎没有优化。而且感觉违背了继承的目的。
然后我陷入了困境,想得太多了,才走到现在的位置。
我的 parent class 方法是否应该对应用程序的其余部分不可见并且只能在我的 child class 中使用?如果是这样,混淆应该进行多深?如果我的 child class 有公开公开的方法,那么直接调用 super.baseMethod1() 就像
localMethod1 = () => {
//local logic
super.BaseMethod1();
}
还是说太直接了?我是否应该有一个公开公开的 child 方法,然后调用一个调用我的超级方法的私有内部方法?喜欢
localMethod1 = () => {
//local logic
this.callSuperMethod1();
}
private callSuperMethod1 = () => {
super.baseMethod1();
}
我认为我严重过度思考了继承和封装的想法,希望就如何继续进行并在务实的正确做法和 efficient/optimized 代码之间取得平衡提供一些建议。
继承正是解决这个问题的方式:
I could set it up so my .then() service call goes to my local child class, which does my company specific logic before calling super.baseMethod1(), but that seems very indirect considering I'm able to call the parent class' method straight from my injected service in the controller.
子 class 可以实现自己的 baseMethod1
,也可以通过 super
方法调用应用来自父的行为。正如 中所解释的,继承是不应该使用实例箭头方法的少数几个原因之一。这不会起作用,因为实例方法无法访问 super
:
localMethod1 = () => {
//local logic
super.BaseMethod1();
}
是:
export abstract class BaseLogService {
...
constructor(protected $http:ng.IHttpService) {}
baseMethod1(objToLog): void {
//do stuff
}
...
}
class LocalLogService extends BaseLogService {
// can be omitted
constructor($http:ng.IHttpService){
super($http);
}
baseMethod1(objToLog): void {
super.baseMethod1(objToLog)
//do stuff
}
}
如果ILocalLogService
完全复制public BaseLogService
接口,它是多余的——BaseLogService
可以用作接口。 $http
应该是 protected
而不是 private
,因为它可能在子 class 中使用。可见性修饰符只能在父构造函数中指定一次。如果子构造函数除了调用 super
什么都不做,可以省略。
因为一次只能使用一个记录器 class,这就是 DI 模式的用途。这只能通过 AngularJS DI:
来解决
// company A module
app.service('logger', ALogService);
使用该服务的单位不应该知道他们正在使用哪个实现:
FooController {
constructor(public logger: BaseLogService) {}
}
我有两个 classes,一个是 parent,一个是 child,它们实现类型来定义它们的预期功能。就在下面。
export abstract class BaseLogService implements IBaseLogService
{
static $inject: string[] = ['$http']
constructor(private $http:ng.IHttpService){
}
baseMethod1 = (objToLog): void => {
//do stuff
}
baseMethod2 = (objToLog): void => {
//do stuff
}
}
class LocalLogService extends BaseLogService implements ILocalLogService
{
constructor(private $http:ng.IHttpService){
super(this.$http);
}
localMethod1 = (): void => {
//do stuff
}
}
export interface IBaseLogService {
baseMethod1(objToLog):void;
baseMethod2(objToLog):void;
}
export interface ILocalLogService extends IBaseLogService{
localMethod1(): void;
}
该应用程序使用日志服务,并为不同的公司记录事情。与公司 B 和 C 相比,公司 A 可能会记录一些不同的内容。这就是每个公司都有本地日志服务的原因。但是所有公司都记录了一些通用的东西。所以这就是为什么有一个本地实现扩展的公共日志class。
通过所有这些介绍,我的问题是,我如何适当地利用我的 parent class' 方法?
为了进一步说明这一点,让我解释一下这是如何使用的。这是 angularjs 所以在应用程序其他地方的控制器中有一个 api POST 调用。
根据 .then() 中的调用承诺 return,需要执行 baseMethod1 以记录一些常见内容。所以它会像下面的 pseudo-code
myThingToAdd: any;
static $inject: string[] = ['localLogService']
constructor(private localLogService: ILocalLogService){}
this.myPOSTApi.addAThing(this.myThingToAdd)
.then((POSTResponse) => {
this.localLogService.baseMethod1(POSTResponse);
});
这就是我的困惑发挥作用的地方。我有一些公司特定的东西需要在调用 baseMethod1 时发生。但是因为我的服务调用直接从控制器转到 parent class,所以我跳过了需要执行本地逻辑的本地 child 服务。
我可以设置它,以便我的 .then() 服务调用转到我的本地 child class,它在调用 super.baseMethod1() 之前执行我公司特定的逻辑,但这似乎非常间接,考虑到我可以直接从我在控制器中注入的服务调用 parent class' 方法。
然后我想,我可以进行两个调用,一个用于本地逻辑,一个用于公共逻辑,每个调用各自的服务,但这对我来说似乎没有优化。而且感觉违背了继承的目的。
然后我陷入了困境,想得太多了,才走到现在的位置。
我的 parent class 方法是否应该对应用程序的其余部分不可见并且只能在我的 child class 中使用?如果是这样,混淆应该进行多深?如果我的 child class 有公开公开的方法,那么直接调用 super.baseMethod1() 就像
localMethod1 = () => {
//local logic
super.BaseMethod1();
}
还是说太直接了?我是否应该有一个公开公开的 child 方法,然后调用一个调用我的超级方法的私有内部方法?喜欢
localMethod1 = () => {
//local logic
this.callSuperMethod1();
}
private callSuperMethod1 = () => {
super.baseMethod1();
}
我认为我严重过度思考了继承和封装的想法,希望就如何继续进行并在务实的正确做法和 efficient/optimized 代码之间取得平衡提供一些建议。
继承正是解决这个问题的方式:
I could set it up so my .then() service call goes to my local child class, which does my company specific logic before calling super.baseMethod1(), but that seems very indirect considering I'm able to call the parent class' method straight from my injected service in the controller.
子 class 可以实现自己的 baseMethod1
,也可以通过 super
方法调用应用来自父的行为。正如 super
:
localMethod1 = () => {
//local logic
super.BaseMethod1();
}
是:
export abstract class BaseLogService {
...
constructor(protected $http:ng.IHttpService) {}
baseMethod1(objToLog): void {
//do stuff
}
...
}
class LocalLogService extends BaseLogService {
// can be omitted
constructor($http:ng.IHttpService){
super($http);
}
baseMethod1(objToLog): void {
super.baseMethod1(objToLog)
//do stuff
}
}
如果ILocalLogService
完全复制public BaseLogService
接口,它是多余的——BaseLogService
可以用作接口。 $http
应该是 protected
而不是 private
,因为它可能在子 class 中使用。可见性修饰符只能在父构造函数中指定一次。如果子构造函数除了调用 super
什么都不做,可以省略。
因为一次只能使用一个记录器 class,这就是 DI 模式的用途。这只能通过 AngularJS DI:
来解决// company A module
app.service('logger', ALogService);
使用该服务的单位不应该知道他们正在使用哪个实现:
FooController {
constructor(public logger: BaseLogService) {}
}