Skip to content

LivingEntity和接口

AttributePlus没有导入了 LivingEntity 这个接口,也不需要。因为 LivingEntity 中所有的方法都不是静态方法。

LivingEntity 顾名思义,活的实体。在服务器中,所有生物都继承自 LivingEntity,所有生物都是一个 LivingEntity 对象。所以所有生物都可以使用 LivingEntity 中的方法。并且可以拥有AttributePlsu属性的实体一定是 LivingEntity

老规矩,我们依旧查看javadoc
https://bukkit.windit.net/javadoc/org/bukkit/entity/LivingEntity.html
打开后我们可以看到,它是一个经过汉化的文档
首先映入眼帘的是 LivingEntityDoc 这次我们看到了更多东西
现在我们可以谈谈 超级接口 和 已知子接口 了。

超级接口

在 Java 的面向对象编程中,当一个接口(如 LivingEntity)继承了其他多个接口时,这些被继承的接口就被称为它的超级接口。

LivingEntity 继承了所有超极接口的所有方法和行为。

换句话说,一个 LivingEntity 对象不仅可以做 LivingEntity 能做的事,还可以做 CommandSender(可以发送/接收命令)、Damageable(可以受伤)、Nameable(有名字)等所有超级接口规定的事情。

子接口

理解了超级接口,那么子接口就是它的反向概念。 图中所有超极子接口中,涵盖了所有类型的 LivingEntity,也就是所有的生物,比如我们常见的 Zombie Husk Player 等。

也就是说,无论是任何生物,它们都具有 LivingEntity 和 所有超极接口 的特性。同时他们自己还有用自己独有的特性,比如僵尸可以是村民僵尸、玩家可以被踢出服务器等。

继承关系

比如 Zombie,它并不是直接继承自 LivingEntity,而是继承自 Monster,而 Monster 继承自 CreatureCreature 才继承自 LivingEntity

也就是说,Zombie 既是一个 Monster 也是一个 Creature 还是一个 LivingEntity

顺嘴一提:多态

说到继承,不得不提一嘴多态。
承链是实现多态的基础。仅仅有继承链,多态的“可能性”就存在了。而当你在代码中利用这个继承链,用父类型引用去操作子类型对象时,多态就“发生”了。

实例方法

我们看到,不同与Bukkit和基础中说的那样,有一个“静态方法”的按钮,而是一个一个“实例方法”的按钮。
这就是所谓的 非静态方法

应该使用 LivingEntity 这个实现类的实例(对象)来调用其对应方法。比如直接通过这个实现类使用 LivingEntity.addPotionEffect(....) 是错误的。

如何使用

具体在脚本属性中的表现是这样的

JavaScript
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 中的一个方法,判断是否为小僵尸。

JavaScript
function runAttack(attr, attacker, entity, handle) {
    if (attacker.isBaby()) {
        ....
    }
    return true
}

此时一个 Zombie 触发了此属性,属性可以正常运行。
此时一个 Player 触发了此属性,属性就会报错,因为 Player 中没有 isBaby() 这个方法。所以我们需要对属性稍加修改。

JavaScript
function runAttack(attr, attacker, entity, handle) {
    if (attacker.getType() == EntityType.ZOMBIE && attacker.isBaby()) {
        ....
    }
    return true
}

此时就不会报错了。为什么呢?复习一下。 &&并且EntityType.ZOMBIEEntityType 枚举,僵尸。Zombie 中的 getType() 方法返回的是 EntityType.ZOMBIE
attacker.getType() == EntityType.ZOMBIE && attacker.isBaby() 的意思就是攻击者的类型是僵尸并且是小僵尸。