JS++ | Getter 和 Setter
在我们之前的示例中,我们定义了一个“setName”方法来设置我们声明的类“name”字段。唯一负责写入或修改类字段的方法称为“setter”或“setter 方法”。相反,唯一负责返回类字段的当前数据的方法称为“getter”或“getter 方法”。
像数组这样的容器有像 'length' 这样的 getter 方法:
int[] arr = [ 1, 2, 3 ];
arr.length; // 3
数组的 'length' 方法返回数组的大小,由数组元素的数量决定。但是,您可能已经注意到一个特殊性:我们不必使用括号来调用 'length' 方法。这是因为数组的“长度”属性是以特殊方式定义的。事实证明,我们可以定义自己的类来拥有这样的特殊方法。
让我们首先将我们的 'setName' 方法重新定义为 setter 方法。打开 Cat.jspp 并简单地在 'setName' 前面添加 'property' 关键字,如下所示:
external $;
module Animals
{
class Cat
{
string name;
var $element = $(
"""
"""
);
property void setName(string name) {
this.name = name;
}
void render() {
$("#content").append($element);
$element.attr("title", name);
}
}
}
此时,如果你尝试编译,你会得到一个错误(JSPPE0150)。我们需要编辑我们的 main.jspp 文件以反映我们对 setter 的更改。由于我们将 'setName' 定义为 setter,我们不能再使用括号来调用它,而是必须使用赋值 (=)运算符:
import Animals;
Cat cat1 = new Cat();
// cat1.setName("Kitty");
cat1.setName = "Kitty";
cat1.render();
Cat cat2 = new Cat();
// cat2.setName("Kat");
cat2.setName = "Kat";
cat2.render();
现在,如果您尝试编译该项目,它应该是成功的。
那很容易!此时我们可能要考虑的唯一细节是名称是猫的属性。 'setName' 意味着一个动作。由于我们不能有名称冲突的字段和方法,我们可以将私有“名称”字段重命名为众多命名约定中的任何一种:mName、_name 等。在本教程中,我们将更喜欢下划线以避免名称冲突因为,在某些动态语言(包括 JavaScript 和Python)中,下划线用于“表示”隐私(即使在实践中它们并不是真正的“隐私”)。通过重命名我们的私有 'name' 字段,这让我们可以使用标识符 'name' 作为 setter 方法。更改 Cat.jspp 代码如下:
external $;
module Animals
{
class Cat
{
string _name;
var $element = $(
"""
"""
);
property void name(string name) {
_name = name;
}
void render() {
$element.attr("title", _name);
$("#content").append($element);
}
}
}
此外,更改 main.jspp 以反映此更改:
import Animals;
Cat cat1 = new Cat();
cat1.name = "Kitty";
cat1.render();
Cat cat2 = new Cat();
cat2.name = "Kat";
cat2.render();
Setter 方法允许我们分配一个值(写操作)。但是,如果我们想要获取值(读取操作),除非我们定义一个附带的 getter 方法,否则它是不允许的。尝试像这样“读取”“名称”字段:
import Animals;
Cat cat1 = new Cat();
cat1.name = "Kitty";
cat1.render();
Cat cat2 = new Cat();
cat2.name = "Kat";
cat2.name;
cat2.render();
如果你尝试编译,你会得到一个错误:
JSPPE0203: No getter defined for `Animals.Cat.name' at line 8 char 0 at main.jspp
正如您现在可能已经推断出的,setter 方法的参数是分配给属性的值(右侧的值)。在我们上面的 main.jspp 中,值是“Kitty”和“Kat”字符串。自然地,setter 方法只允许接受一个参数。由于 getter 是“读取”操作,因此不需要接受任何值;因此,getter 方法直观地不需要参数。使用这种直觉,我们可以定义一个附带的 getter 方法:
external $;
module Animals
{
class Cat
{
string _name;
var $element = $(
"""
"""
);
property string name() {
return _name;
}
property void name(string name) {
_name = name;
}
void render() {
$element.attr("title", _name);
$("#content").append($element);
}
}
}
现在,如果您尝试编译项目,您应该能够成功编译。
如您所见,如果您定义一个没有getter 的setter,您可以阻止所有“读取”操作。相反,如果你定义一个没有 setter 的 getter,你可以阻止所有的“写”操作。如果两者都定义,则可以同时进行读取和写入操作。这使您可以根据自己的需要进行定制。