偶承认偶吃饱了没事干才会干这种事,希望此文会帮到一些对tjs语言不熟悉的人。。。。。。
前言:此文是针对那些对多态性的tjs语言不熟悉的人而写的,事实上也是我在通过调试推敲tjs的语法时的记录物,把它整理了一下便放出来。为什么文中要多次提及java呢,因为tjs和java太相像了,并不是因为我个人特别喜欢java。有关java方面的注释能够帮助那些为了学好tjs而去学java的人,java和tjs还是有一些明显的差别,像语法的严格性方面。用我的话说就是java是穿了紧身衣服的loli,tjs则是穿了松松垮垮睡衣的loli,前者的loli,可塑性不大,它的体态在紧身衣服下只能是那样了,不能是另一种模样,后者则不同,因为衣服阔大,loli的体态千姿万化,可以这样,也可以那样,比较自由,此时的loli就能充分地体现她的loli特性了,这就是tjs语言,一门语法要求较开放的语言。
=======================tjs语言的多态性=======================
先在[iscript]和[endscript]打入以下代码
[代码开始]
var mylayer=new Layer(kag,kag.fore.base);
mylayer.setPos(0,0);
mylayer.setSize(800,600);
mylayer.visible=true;
mylayer.font.height=19;
[代码结束]
以下代码请打在上代码之后,并且放在[iscript]和[endscript]之间
---------------------------------------------------------------
tjs语言可重载构造方法,但要注意不能使用this()
[代码开始]
class ThrowOverObject{
var name,type;
function ThrowOverObject(name){
this.name=name;
}
function ThrowOverObject(name,type){
this.name=name; //这里不能使用this(name);java里是可行的,tjs就不行,否则会出现语法错误
this.type=type;
}
}
var obj1=new ThrowOverObject("西园寺世界");
mylayer.drawText(0,0,obj1.name,0xffffff);
[代码结束]
[结果显示]
西园寺世界
[结果显示结束]
---------------------------------------------------------------
tjs语言的地址问题
[代码开始]
class ThrowOverObject{
var name,type;
function ThrowOverObject(name){
this.name=name;
}
function ThrowOverObject(name,type){
this.name=name;
this.type=type;
}
function getName(){
return name;
}
function setName(name){
this.name=name;
return this;
}
function getType(){
return type;
}
function setType(type){
this.type=type;
return this;
}
function toString(){
return "name:"+name+" type:"+type;
}
}
var obj1=new ThrowOverObject("西园寺世界");
obj1.setName("桂言叶").setType("美少女");
mylayer.drawText(0,0,obj1.toString(),0xffffff);
[代码结束]
[结果显示]
name:桂言叶 type:美少女
[结果显示结束]
如果把最后那句改成mylayer.drawText(0,0,obj1.toString,0xffffff);
如在java里会显示错误,在tjs里就不然了,打印出来的结果会是方法toString的地址,如:
(object 0x01AAD840:0x01A9EEC4)
第二个地址明显在第一个地址的前面,估计那是obj1的地址,打入下面语句进行测试:
mylayer.drawText(0,0,obj1,0xffffff);
mylayer.drawText(0,20,obj1.toString,0xffffff);
这次打印出来的结果是:
(object 0x01AA32C0:0x01AA32C0)
(object 0x01AA3714:0x01AA32C0)
估计正确,后面那个确实是obj1的地址,顺便说一下这里前后地址的差和上面前后地址的差不一样,申请空间时用的可能会是链表的方法
Timer的构造方法调用的也是地址,Timer(owner,actionname="action")
owner指的是事件,构造一个函数
function timeEvent(){
}
调用时不能是var TimerObject=new Timer(timeEvent(),"");
因为timeEvent()指向的不是地址,而应该是
var TimerObject=new Timer(timeEvent,"");
---------------------------------------------------------------
tjs语言的变量隐藏一
[代码开始]
class BeforeThrowOver{
var tool;
function BeforeThrowOver(){ //少了这个空构造方法,空构造对象时也不会出错
}
function BeforeThrowOver(tool){
this.tool=tool;
}
function getTool(){
return tool;
}
}
class ThrowOverObject extends BeforeThrowOver{
var name,type;
function ThrowOverObject(tool,name){
super.BeforeThrowOver(tool); //这里不能使用super(tool),虽然不会显示错误,但无法读入tool
this.name=name;
}
function ThrowOverObject(tool,name,type){
super.BeforeThrowOver(tool); //这里不能使用super(tool),虽然不会显示错误,但无法读入tool
this.name=name;
this.type=type;
}
function getName(){
return name;
}
function setName(name){
this.name=name;
return this;
}
function getType(){
return type;
}
function setType(type){
this.type=type;
return this;
}
function toString(){
return "tool:"+tool+" name:"+name+" type:"+type; //tjs调用tool时不能使用super.tool,否则会显示错误语法,java则用tool和super.tool皆可
}
}
var obj1=new ThrowOverObject();
mylayer.drawText(0,0,obj1.toString(),0xffffff);
var obj1=new ThrowOverObject("套套");
mylayer.drawText(0,20,obj1.toString(),0xffffff);
var obj1=new ThrowOverObject("套套","清浦刹那");
mylayer.drawText(0,40,obj1.toString(),0xffffff);
var obj1=new ThrowOverObject("套套","清浦刹那","loli");
mylayer.drawText(0,60,obj1.toString(),0xffffff);
[代码结束]
[结果显示]
tool: name: type:
tool:套套 name: type:
tool:套套 name:清浦刹那 type:
tool:套套 name:清浦刹那 type
i
[结果显示结束]
tjs里的super.BeforeThrowOver(tool)明显不如java里的super(tool)来得简洁,个人觉得有点恶心
----------------------------------------------------------------
tjs语言的方法覆盖一
[代码开始]
class BeforeThrowOver{
var tool;
function BeforeThrowOver(){
}
function BeforeThrowOver(tool){
this.tool=tool;
}
function getTool(){
return tool;
}
function setTool(tool){
this.tool=tool;
return this; //返回的是BeforeThrowOver类型
}
}
class ThrowOverObject extends BeforeThrowOver{
var name,type;
function ThrowOverObject(tool,name){
super.BeforeThrowOver(tool);
this.name=name;
}
function ThrowOverObject(tool,name,type){
super.BeforeThrowOver(tool);
this.name=name;
this.type=type;
}
function setTool(tool){
this.tool=tool;
return this;
}
function getName(){
return name;
}
function setName(name){
this.name=name;
return this; //返回的是ThrowOverObject类型
}
function getType(){
return type;
}
function setType(type){
this.type=type;
return this;
}
function toString(){
return "tool:"+tool+" name:"+name+" type:"+type;
}
}
var obj1=new ThrowOverObject("套套","清浦刹那","loli");
obj1.setTool("套套&棒棒").setName("桂言叶").setType("美少女");
mylayer.drawText(0,0,obj1.toString(),0xffffff);
[代码结束]
[结果显示]
tool:套套&棒棒 name:桂言叶 type:美少女
[结果显示结束]
可见tjs语言无视修改返回的值类型,只取子类的返回类型,java里就严格规定返回的值类型必须和父类的一样,这也和tjs语言广义地使用var定义变量有关
----------------------------------------------------------------------------------------
tjs语言的变量隐藏二和方法覆盖二
[代码开始]
class BeforeThrowOver{
var tool;
function BeforeThrowOver(){
}
function BeforeThrowOver(tool){
this.tool=tool;
}
function getTool(){
return tool;
}
function setTool(tool){
this.tool=tool;
return this;
}
}
class ThrowOverObject extends BeforeThrowOver{
var name,type;
function ThrowOverObject(tool,name){
super.BeforeThrowOver(tool);
this.name=name;
}
function ThrowOverObject(tool,name,type){
super.BeforeThrowOver(tool);
this.name=name;
this.type=type;
}
function setTool(clothes){ //问题出在这里
var clothes;
super.setTool(clothes); //这里返回了一次this
this.clothes=clothes;
return this; //这里返回了第二次this,但对整体没影响
}
function getName(){
return name;
}
function setName(name){
this.name=name;
return this;
}
function getType(){
return type;
}
function setType(type){
this.type=type;
return this;
}
function toString(){
return "tool:"+tool+" name:"+name+" type:"+type;
}
}
var obj1=new ThrowOverObject("套套","清浦刹那","loli");
mylayer.drawText(0,0,obj1.toString(),0xffffff);
obj1.setTool("女仆装");
mylayer.drawText(0,20,obj1.toString(),0xffffff);
mylayer.drawText(0,40,obj1.clothes,0xffffff);
[代码结束]
[结果显示]
tool:套套 name:清浦刹那 type
i
tool: name:清浦刹那 type
i
[结果显示结束]
tool后没有显示任何东西,“女仆装”到哪里去了?是因为把setTool参数表里的tool修改成clothes的原因吗?原因不是这个。
java里规定子类的参数列表必须和父类的保持一致,tjs里没有这个规定,也就是说你可以随心所欲地覆盖方法
请看以下修改过的代码
[代码开始]
class BeforeThrowOver{
var tool;
function BeforeThrowOver(){
}
function BeforeThrowOver(tool){
this.tool=tool;
}
function getTool(){
return tool;
}
function setTool(tool){
this.tool=tool;
return this;
}
}
class ThrowOverObject extends BeforeThrowOver{
var name,type;
function ThrowOverObject(tool,type){
super.BeforeThrowOver(tool);
this.type=type;
}
function ThrowOverObject(tool,name,type){
super.BeforeThrowOver(tool);
this.name=name;
this.type=type;
}
function setTool(clothes){
var clothes="女仆装"; //在此加入女仆装,其它不变
super.setTool(clothes);
this.clothes=clothes;
return this;
}
function getName(){
return name;
}
function setName(name){
this.name=name;
return this;
}
function getType(){
return type;
}
function setType(type){
this.type=type;
return this;
}
function toString(){
return "tool:"+tool+" name:"+name+" type:"+type;
}
}
var obj1=new ThrowOverObject("套套","清浦刹那","loli");
mylayer.drawText(0,0,obj1.toString(),0xffffff);
obj1.setTool("女仆装");
mylayer.drawText(0,20,obj1.toString(),0xffffff);
mylayer.drawText(0,40,obj1.clothes,0xffffff);
[代码结束]
[结果显示]
tool:套套 name:清浦刹那 type:loli
tool:女仆装 name:清浦刹那 type:loli
女仆装
[结果显示结束]
盼望已久的女仆装终于出来了,在java里会显示错误,因为你在setTool(clothes)里定义了clothes,然后又重新定义
在tjs里对变量可以进行重新定义,取得的值是最后定义的,clothes带着“女仆装”返回隐藏起来的父类变量tool,“女仆装”就出来了
还有,this.clothes其实什么都不是,ThrowOverObject里没定义clothes这个变量,在java里会提示找不到变量clothes,tjs没有,可见它不是一种讲究严格的语言
----------------------------------------------------------------------------------------
以下代码能够说明很多事,自己多试验几次就明白为什么会显示那样的结果了
[代码开始]
class BeforeThrowOver{
var tool;
function BeforeThrowOver(){
}
function BeforeThrowOver(tool){
this.tool=tool;
}
function getTool(){
return tool;
}
function setTool(tool){
this.tool=tool;
return this;
}
}
class ThrowOverObject extends BeforeThrowOver{
var name,type,prop;
function ThrowOverObject(tool,name){
super.BeforeThrowOver(tool);
this.name=name;
}
function ThrowOverObject(tool,name,type){
super.BeforeThrowOver(tool);
this.name=name;
this.type=type;
}
function ThrowOverObject(tool,name,type,prop){
super.BeforeThrowOver(tool);
this.name=name;
this.type=type;
this.prop=prop;
}
function setTool(tool){
this.tool=tool;
return this;
}
function getName(){
return name;
}
function setName(name){
this.name=name;
return this;
}
function getType(){
return type;
}
function setType(type){
this.type=type;
return this;
}
function getProp(){
return prop;
}
function setProp(prop){
this.prop=prop;
return this;
}
function toString(){
return "推倒工具:"+tool+" 姓名:"+name+" 类型:"+type+" 性格:"+prop.getCharacter()+" 推倒难度:"+prop.getLeval()+" 反抗武器:"+prop.getWeapon();
}
}
class BasicProp{
var character;
function BasicProp(){
}
function BasicProp(character){
this.character=character;
}
function getCharacter(){
return character;
}
function setCharacter(character){
this.character=character;
return this;
}
}
class Prop extends BasicProp{
var throwoverleval,weapon;
function Prop(character,throwoverleval){
super.BasicProp(character);
this.throwoverleval=throwoverleval;
}
function Prop(character,throwoverleval,weapon){
super.BasicProp(character);
this.throwoverleval=throwoverleval;
this.weapon=weapon;
}
function setCharacter(character){
this.character=character;
return this;
}
function getLeval(){
return throwoverleval;
}
function setLeval(leval){
throwoverleval=leval;
return this;
}
function getWeapon(){
return weapon;
}
function setWeapon(weapon){
this.weapon=weapon;
return this;
}
}
var obj1=new ThrowOverObject("套套","清浦刹那","loli",new Prop("无口","困难"));
mylayer.drawText(0,0,obj1.toString(),0xffffff);
mylayer.drawText(0,30,obj1.setTool("鞭鞭").setName("桂言叶").setType("美少女").setProp((new Prop()).setCharacter("文静").setLeval("一般").setWeapon("锯刀")).toString(),0xffffff); //new Prop()必须要加括号
mylayer.drawText(0,60,obj1.setTool("棒棒").setName("西园寺世界").setType("美少女").setProp(new Prop("活泼","容易","菜刀")).toString(),0xffffff);
obj1.setTool("loli").setName("karry").setType("大叔").getProp().setCharacter("恋童").setLeval("超级容易").setWeapon("胡渣");
mylayer.drawText(0,90,obj1.toString(),0xffffff);
[代码结束]
[结果显示]
推倒工具:套套 姓名:清浦刹那 类型:loli 性格:无口 推倒难度:困难 反抗武器:
推倒工具:鞭鞭 姓名:桂言叶 类型:美少女 性格:文静 推倒难度:一般 反抗武器:锯刀
推倒工具:棒棒 姓名:西园寺世界 类型:美少女 性格:活泼 推倒难度:容易 反抗武器:菜刀
推倒工具:loli 姓名:karry 类型:大叔 性格:恋童 推倒难度:超级容易 反抗武器:胡渣
[结果显示结束]
----------------------------------------------------------------------------------------
内部类的实现
[代码开始]
class GodIsALoli{
var str;
function GodIsALoli(){
}
function getWords(){
str="我们的神其实是一个loli";
return str;
}
function getInnerWords(){
var words=new LoliIsHumansGod();
return words.getWords();
}
class LoliIsHumansGod{
var str;
function LoliIsHumansGod(){
}
function getWords(){
str="loli是全人类的神";
return str;
}
}
}
var obj=new GodIsALoli();
mylayer.drawText(0,0,obj.getWords(),0xffffff);
mylayer.drawText(0,20,obj.getInnerWords(),0xffffff);
var subobj=new obj.LoliIsHumansGod();
mylayer.drawText(0,40,subobj.getWords(),0xffffff);
[代码结束]
[结果显示]
我们的神其实是一个loli
loli是全人类的神
loli是全人类的神
[结果显示结束]
使用内部类时,只能通过创建内部类对象的方法来调用内部类的变量,注意创建内部类的方法var subobj=new obj.LoliIsHumansGod();
在java里则写成subobj=obj.new LoliIsHumansGod(); 注意这种区别
在tjs里还可以这样定义var subobj=new GodIsALoli.LoliIsHumansGod();但是这样会重新申请一个和obj地址不同的新地址
在java里,是绝对不可能这样表示的,小心会把tjs和java的语法混淆
----------------------------------------------------------------------------------------
不知道tjs是不是还可以实现匿名内部类,java是可以的,反正我是未试出来,有可能是因为语法不对或者真的不可能实现
前面的var subobj=new obj.LoliIsHumansGod();也是靠点运气才试出来的,开始时用java的规则
var subobj=obj.new LoliIsHumansGod();发觉不成功,后来阴差阳错地把obj写在LoliIsHumansGod前就居然成功了
更汗颜的是居然还可以var subobj=new GodIsALoli.LoliIsHumansGod();瞬间无语
我把我尝试的代码贴出来,日后哪个人试成功了,麻烦告知一下我
[代码开始]
class Loli{
var front,rear;
function createLoli(){
front="高隆";
rear="巨大";
}
function show(){
mylayer.drawText(0,0,"loli的前面:"+front+" loli的后面:"+rear,0xffffff);
}
}
class NewLoli{
var loli=new Loli(){function createLoli(){createLoli(){front="平坦";rear="幼小";}}; //这里便是匿名内部类,在创建时修改方法,java就是这样实现的
function show(){
loli.createLoli();
mylayer.drawText(0,0,"Loli怎么能大胸大臀呢?",oxffffff);
mylayer.drawText(0,20,"loli的前面:"+front+" loli的后面:"+rear,0xffffff);
}
}
var loli=new NewLoli();
loli.show();
[代码结束]
[错误信息]
语法错误(syntax error, unexpected "{", expecting ";") at conductor.tjs(197)[(function) timerCallback]
[错误信息结束]
----------------------------------------------------------------------------------------
接口方面好像也不行,错误信息同上,估计没有implements这个命令,但还是把代码发一下
[代码开始]
class Attribute{
var THISIS="Loli";
function front();
function rear();
}
class Someone implements Attribute{
var front,rear;
function front(){
front="平坦";
}
function rear(){
rear="幼小";
}
}
var setsuna=new someone();
mylayer.drawText(0,0,setsuna.THISIS,0xffffff); //setsuna=刹那
mylayer.drawText(0,0,setsuna.front(),0xffffff);
mylayer.drawText(0,0,setsuna.rear(),0xffffff);
[代码结束]
[错误信息]
语法错误(syntax error, unexpected ";", expecting "{") at conductor.tjs(197)[(function) timerCallback]
[错误信息结束]
----------------------------------------------------------------------------------------
后记:关于tjs多态性方面在我能力范围内能说的地方都说了,能研究的地方都研究了,希望对tjs入门的人有帮助,看不懂我说的话不要紧,把代码复制过去,通过多番修改代码查看打印结果就能明白代码的意思了。事实上,我也没说多少话,因为我比较懒,不愿意打字。如果发现文中有问题,或有不明白的问题,欢迎提出。日后有空,我再写些多态性以外的东西,毕竟我现在除了语法还过得去外对kr2的类完全不懂,因为我日文太差了,看不懂那个kr2文档的很多地方。
ps:桂言叶,西园寺世界,清浦刹那这三个角色出自体积庞大的邪恶游戏School Days和Summer Days,推荐各位玩一下,那是偶最爱的游戏,我的头像和签名就是出自School Days的,全动画进行的游戏一直以来是偶所追盼的,想不到overflow实现了,而且故事还邪恶得出色,说完了,自殴,飞走......