JS++ 获取器和设置器
在我们之前的例子中,我们定义了一个 “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;
varelement = (
"""
<div class="animal">
<i class="icofont icofont-animal-cat"></i>
</div>
"""
);
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’意味着一个动作。由于我们不能让字段和方法的名称发生冲突,我们可以将我们的私有’name’字段重命名为众多命名规则中的任何一个:mName、_name等。在本教程中,我们将倾向于使用下划线来避免名称冲突,因为在一些动态语言中(包括JavaScript和Python),下划线被用来 “表示 “隐私(即使它们在实践中并不真正 “隐私”)。通过重命名我们的私有 “name “字段,这使我们可以使用标识符 “name “作为setter方法。改变Cat.jspp的代码如下。
external ;
module Animals
{
class Cat
{
string _name;
varelement = (
"""
<div class="animal">
<i class="icofont icofont-animal-cat"></i>
</div>
"""
);
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方法,否则是不允许的。试着像这样 “读取”‘name’字段。
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;
varelement = (
"""
<div class="animal">
<i class="icofont icofont-animal-cat"></i>
</div>
"""
);
property string name() {
return _name;
}
property void name(string name) {
_name = name;
}
void render() {element.attr("title", _name);
("#content").append(element);
}
}
}
现在,如果你尝试编译这个项目,你应该能够成功地进行编译。
正如你所看到的,如果你定义了一个setter而没有getter,你可以阻止所有的 “读 “操作。相反,如果你定义了一个getter而没有setter,你可以阻止所有的 “写 “操作。如果你同时定义两者,你可以同时进行读和写操作。这使你可以根据你的需要进行定制。