这是下一个JavaScript类结构:
// data.service.ts
export class DataService {
public url = environment.url;
constructor(
private uri: string,
private httpClient: HttpClient,
) { }
getAll() {}
getOne(id: number) {}
create(data: any) {}
// etc...
}
接下来是一般数据模型,可以使用DataService的方法来传达服务器:
// Model.model.ts
import './data.service';
export class Model extends DataService {
all() {}
get() {
// parse and make some basic validation on the
// DataService.getOne() JSON result
}
// etc...
}
最后,我基于Model.model.ts创建了一个特定的数据模型:
// User.model.ts
import './Model.model.ts';
export class User extends Model {
id: number;
name: string;
email: string;
init() {
// make specific validation on Model.get() result
}
}
如果我在我的代码中使用User类,我可以直接调用DataService的getAll()函数。但这不是一件好事,因为在这种情况下我会错过内置的验证。
如何在类上阻止方法继承?
我正在寻找像PHP的static
方法。子类可以使用这些方法,但他的孩子不能。
我想要这样的东西:
const dataService = new DataService();
dataService.getAll(); // void
const model = new Model();
model.getAll(); // undefined
model.all(); // void
const user = new User();
user.getAll(); // undefined
user.all(); // void
有没有办法做到这一点?
通过将private
关键字添加到函数private getAll() {}
来调用它时,可以阻止它的构建。但private
是一个TypeScript功能,而不是Javascript,所以如果强制它构建,它仍然是可调用的。这一刻没有办法完全阻止它。
因此,如果您希望在TypeScript
中阻止它,只需在那里添加private
关键字。但它不是可构建的,不会像你期望的那样返回undefined。否则,只需在子类上使用未定义返回的函数替换该函数
使用所示的代码和使用案例,获得所需行为的唯一方法就是不要让Model
扩展DataService
。有一个subsitution principle说,如果Model extends DataService
,那么有人应该能够像对待Model
实例一样对待DataService
实例。事实上,如果Model
是一种特殊类型的DataService
,有人要求DataService
实例,你应该能够给他们一个Model
。你告诉他们他们不能在上面调用getAll()
方法是不公平的。所以继承树不能像你拥有它那样工作。相反,你可以做这样的事情:
// ultimate parent class of both DataService and Model/User
class BaseDataService {
getOne(id: number) { }
create(data: any) { }
// etc...
}
// subclass with getAll()
class DataService extends BaseDataService {
getAll() {}
}
// subclass without getAll()
class Model extends BaseDataService {
all() { }
get() { }
// etc...
}
class User extends Model {
id!: number;
name!: string;
email!: string;
init() { }
}
const dataService = new DataService();
dataService.getAll(); // void
const model = new Model();
model.getAll(); // error
model.all(); // okay
const user = new User();
user.getAll(); // error
user.all(); // okay
这完全按照你的指定工作。完美,对吗?
好吧,我得到了下沉的感觉,你会尝试这个并且不高兴你不能在this.getAll()
或Model
的实施中调用User
...可能在all()
的Model
方法的可疑空体内。而且我已经得到了防御性地指向Minimum, Complete, and Verifiable Example文章的冲动,因为所陈述的问题似乎并不需要这样。
如果你确实需要,你仍然无法打破替代原则。相反,我建议使getAll()
成为protected
方法,并在all()
上公开DataService
方法:
class DataService {
getOne(id: number) { }
create(data: any) { }
protected getAll() { }
all() {
this.getAll();
}
// etc...
}
class Model extends DataService {
all() {
this.getAll();
}
get() { }
// etc...
}
class User extends Model {
id!: number;
name!: string;
email!: string;
init() { }
}
const dataService = new DataService();
dataService.getAll(); // error
dataService.all(); // okay
const model = new Model();
model.getAll(); // error
model.all(); // okay
const user = new User();
user.getAll(); // error
user.all(); // okay
并且生活在这样一个事实,即getAll()
是一种纯粹的内部方法,从来没有意味着看到光明的一天。
好的,希望其中一个有帮助;祝好运!