LivingEntity和接口
AttributePlus没有导入了 LivingEntity
这个接口,也不需要。因为 LivingEntity
中所有的方法都不是静态方法。
LivingEntity
顾名思义,活的实体。在服务器中,所有生物都继承自 LivingEntity
,所有生物都是一个 LivingEntity
对象。所以所有生物都可以使用 LivingEntity
中的方法。并且可以拥有AttributePlsu属性的实体一定是 LivingEntity
。
老规矩,我们依旧查看javadoc
https://bukkit.windit.net/javadoc/org/bukkit/entity/LivingEntity.html
打开后我们可以看到,它是一个经过汉化的文档
首先映入眼帘的是 这次我们看到了更多东西
现在我们可以谈谈 超级接口 和 已知子接口 了。
超级接口
在 Java 的面向对象编程中,当一个接口(如 LivingEntity
)继承了其他多个接口时,这些被继承的接口就被称为它的超级接口。
LivingEntity
继承了所有超极接口的所有方法和行为。
换句话说,一个 LivingEntity
对象不仅可以做 LivingEntity
能做的事,还可以做 CommandSender
(可以发送/接收命令)、Damageable
(可以受伤)、Nameable
(有名字)等所有超级接口规定的事情。
子接口
理解了超级接口,那么子接口就是它的反向概念。 图中所有超极子接口中,涵盖了所有类型的 LivingEntity
,也就是所有的生物,比如我们常见的 Zombie
Husk
Player
等。
也就是说,无论是任何生物,它们都具有 LivingEntity
和 所有超极接口 的特性。同时他们自己还有用自己独有的特性,比如僵尸可以是村民僵尸、玩家可以被踢出服务器等。
继承关系
比如 Zombie
,它并不是直接继承自 LivingEntity
,而是继承自 Monster
,而 Monster
继承自 Creature
,Creature
才继承自 LivingEntity
。
也就是说,Zombie
既是一个 Monster
也是一个 Creature
还是一个 LivingEntity
。
顺嘴一提:多态
说到继承,不得不提一嘴多态。
承链是实现多态的基础。仅仅有继承链,多态的“可能性”就存在了。而当你在代码中利用这个继承链,用父类型引用去操作子类型对象时,多态就“发生”了。
实例方法
我们看到,不同与Bukkit和基础中说的那样,有一个“静态方法”的按钮,而是一个一个“实例方法”的按钮。
这就是所谓的 非静态方法
应该使用 LivingEntity
这个实现类的实例(对象)来调用其对应方法。比如直接通过这个实现类使用 LivingEntity.addPotionEffect(....)
是错误的。
如何使用
具体在脚本属性中的表现是这样的
function runAttack(attr, attacker, entity, handle) {
attacker.addPotionEffect(....)
return true
}
这里的 attacker
entity
就是 LivingEntity
的实例(对象)。AttributePlus的任何属性的触发者都是 LivingEntity
。
注意
根据不同服务器的设定,所使用的生物也会有区别。假设你服务器里是 Zombie
触发了攻击,此时 attacker
还是一个 Zombie
,正如在继承关系中所说的,attacker
具有所有 Zombie
Monster
Creature
LivingEntity
的特性。
isBaby()
就是 Zombie
中的一个方法,判断是否为小僵尸。
function runAttack(attr, attacker, entity, handle) {
if (attacker.isBaby()) {
....
}
return true
}
此时一个 Zombie
触发了此属性,属性可以正常运行。
此时一个 Player
触发了此属性,属性就会报错,因为 Player
中没有 isBaby()
这个方法。所以我们需要对属性稍加修改。
function runAttack(attr, attacker, entity, handle) {
if (attacker.getType() == EntityType.ZOMBIE && attacker.isBaby()) {
....
}
return true
}
此时就不会报错了。为什么呢?复习一下。 && 是 并且。EntityType.ZOMBIE
是 EntityType
枚举,僵尸。Zombie
中的 getType()
方法返回的是 EntityType.ZOMBIE
。attacker.getType() == EntityType.ZOMBIE && attacker.isBaby()
的意思就是攻击者的类型是僵尸并且是小僵尸。