从 class 访问 class 即 属性
Access to class from class which is property
我正在 canvas 使用 Typescript 玩多人游戏。我有一个玩家 class,属性 是一个 class,拥有玩家统计数据和装备 class。
class Player {
statistics = new Stats()
eq = new Equipment()
}
class Stats {
strength = 3
...
}
class Equipment {
'items which have parameters like +3 strength etc.'
}
所以我有来自 Stats 的基本统计数据和来自 Equipment 的附加统计数据,我需要将它们结合起来,但是 Player class 主要描述有关 2d 世界中玩家位置的信息,他在哪张地图上,图像等。我应该把结合统计数据的方法放在 Player class 中吗?是否允许通过 ES6 导入将 class 实例导出到另一个 class 并在那里使用它?如果我需要在数据或装备上获得一名玩家 属性 怎么办?我应该将播放器传递给构造函数吗?
将 class 的实例作为另一个 class 的 属性 的实例是完全正常的。
What if I need to get one of player property in stats or equipment? Should I pass player to constructor?
将另一个 class 的实例传递给 class 构造函数也是完全正常的。但是我建议不要建立 bi-directional 关系。 Player
有 Equipment
或 Equipment
有 Player
,但我不会两者都做。如果您需要获取一些依赖于两个 class 实例的信息,您可以从 has
另一个实例中获取。根据您上面的代码,那将是 Player
.
例如,如果您想获得特定的统计数据 defense
,我们将玩家的基础防御从装备中添加一些提升,可能如下所示:
getDefense(): number {
return this.statistics.defense + this.equipment.stats.defense;
}
也许我们不想为每个单独的统计数据创建一个方法,所以我们可以创建一个通用方法来按名称获取统计数据。我们使用 keyof Stats
来确保所有名称字符串都有效。
class Player {
private statistics: Stats;
private eq: Equipment;
constructor( baseStats: Stats, equipment: Equipment ) {
this.statistics = baseStats;
this.eq = equipment;
}
public changeEquipment( equipment: Equipment ): void {
this.eq = equipment;
}
public getStat( name: keyof Stats ): number {
return this.statistics[name] + this.eq.stats[name];
}
}
我们可以做的另一件事是将统计数据公开为 public readonly
属性。这就是我在 Equipment
中所做的。我们不希望从 class 外部编辑统计数据,但我们不能只创建 属性 readonly
因为我们希望能够在调用时编辑统计数据levelUp()
.
您可以同时拥有变量的 public 和私有版本,使用 _
作为私有版本的前缀,这样数据就可以 public 可读,但只能在内部编辑class。从外部编辑它的唯一方法是调用 class 方法。
class Equipment {
private _stats: Stats;
public readonly name: string;
constructor( name: string, baseStats: Stats ) {
this.name = name;
this._stats = baseStats;
}
/**
* readonly public accessor
*/
get stats(): Stats {
return this._stats;
}
/**
* increase all stats by 1
*/
levelUp(): void {
Object.keys(this._stats).forEach( key => {
this._stats[key as keyof Stats] += 1;
})
}
}
根据您描述的方式 Stats
,我认为它应该只是一个 interface
而不是 class
,因为它只是一堆数字。当您想要拥有方法或拥有相互依赖的属性时,请使用 classes。
interface Stats {
strength: number;
defense: number;
hp: number;
}
但是如果你想要一个实现该接口的 class,那么可以将那个 class 的实例传递给 Player
或 Equipment
的构造函数不会有问题的。这种灵活性造就了良好的设计。
我正在 canvas 使用 Typescript 玩多人游戏。我有一个玩家 class,属性 是一个 class,拥有玩家统计数据和装备 class。
class Player {
statistics = new Stats()
eq = new Equipment()
}
class Stats {
strength = 3
...
}
class Equipment {
'items which have parameters like +3 strength etc.'
}
所以我有来自 Stats 的基本统计数据和来自 Equipment 的附加统计数据,我需要将它们结合起来,但是 Player class 主要描述有关 2d 世界中玩家位置的信息,他在哪张地图上,图像等。我应该把结合统计数据的方法放在 Player class 中吗?是否允许通过 ES6 导入将 class 实例导出到另一个 class 并在那里使用它?如果我需要在数据或装备上获得一名玩家 属性 怎么办?我应该将播放器传递给构造函数吗?
将 class 的实例作为另一个 class 的 属性 的实例是完全正常的。
What if I need to get one of player property in stats or equipment? Should I pass player to constructor?
将另一个 class 的实例传递给 class 构造函数也是完全正常的。但是我建议不要建立 bi-directional 关系。 Player
有 Equipment
或 Equipment
有 Player
,但我不会两者都做。如果您需要获取一些依赖于两个 class 实例的信息,您可以从 has
另一个实例中获取。根据您上面的代码,那将是 Player
.
例如,如果您想获得特定的统计数据 defense
,我们将玩家的基础防御从装备中添加一些提升,可能如下所示:
getDefense(): number {
return this.statistics.defense + this.equipment.stats.defense;
}
也许我们不想为每个单独的统计数据创建一个方法,所以我们可以创建一个通用方法来按名称获取统计数据。我们使用 keyof Stats
来确保所有名称字符串都有效。
class Player {
private statistics: Stats;
private eq: Equipment;
constructor( baseStats: Stats, equipment: Equipment ) {
this.statistics = baseStats;
this.eq = equipment;
}
public changeEquipment( equipment: Equipment ): void {
this.eq = equipment;
}
public getStat( name: keyof Stats ): number {
return this.statistics[name] + this.eq.stats[name];
}
}
我们可以做的另一件事是将统计数据公开为 public readonly
属性。这就是我在 Equipment
中所做的。我们不希望从 class 外部编辑统计数据,但我们不能只创建 属性 readonly
因为我们希望能够在调用时编辑统计数据levelUp()
.
您可以同时拥有变量的 public 和私有版本,使用 _
作为私有版本的前缀,这样数据就可以 public 可读,但只能在内部编辑class。从外部编辑它的唯一方法是调用 class 方法。
class Equipment {
private _stats: Stats;
public readonly name: string;
constructor( name: string, baseStats: Stats ) {
this.name = name;
this._stats = baseStats;
}
/**
* readonly public accessor
*/
get stats(): Stats {
return this._stats;
}
/**
* increase all stats by 1
*/
levelUp(): void {
Object.keys(this._stats).forEach( key => {
this._stats[key as keyof Stats] += 1;
})
}
}
根据您描述的方式 Stats
,我认为它应该只是一个 interface
而不是 class
,因为它只是一堆数字。当您想要拥有方法或拥有相互依赖的属性时,请使用 classes。
interface Stats {
strength: number;
defense: number;
hp: number;
}
但是如果你想要一个实现该接口的 class,那么可以将那个 class 的实例传递给 Player
或 Equipment
的构造函数不会有问题的。这种灵活性造就了良好的设计。