这是下一个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
有什么办法吗?
答案 0 :(得分:0)
使用所示的代码和所述的用例,获得所需行为的唯一方法是根本不使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()
是纯粹内部方法的事实,而这绝不意味着日日夜夜。
好的,希望其中之一能有所帮助;祝你好运!