Внедрение интерфейса
Это новый метод, представленный Loom 0.11 для добавления методов в определенный существующий класс. Более конкретно, вы можете создать интерфейс, а затем внедрить этот интерфейс в класс. В результате целевой класс получит все методы интерфейса, как если бы они у него всегда были. Внедрение интерфейса - это функция только во время компиляции, это означает, что для реализации интерфейса в целевом классе также следует использовать Миксин.
Это особенно полезно для библиотек, с помощью этого вы можете добавлять новые методы в существующие классы и использовать их без необходимости каждый раз приводить или переопределять интерфейс.
Давайте лучше объясним на примере:
Область применения этого примера состоит в том, чтобы добавить следующий метод в net.minecraft.fluid.FlowableFluid
, чтобы получить звук ведра при опустошении.
Обычно это невозможно, потому что net.minecraft.fluid.FlowableFluid
не имеет аналогичного метода.
Optional<SoundEvent> getBucketEmptySound()
Чтобы добавить метод в класс, прежде всего вам нужно создать с ним интерфейс:
package net.fabricmc.example; public interface BucketEmptySoundGetter { // Методы во внедренном интерфейсе ДОЛЖНЫ быть по умолчанию, // в противном случае код, ссылающийся на них, не будет компилироваться! default Optional<SoundEvent> getBucketEmptySound() { return Optional.empty(); } }
Теперь вам нужно реализовать этот интерфейс в net.minecraft.fluid.FlowableFluid
с помощью миксина, реализующего интерфейс:
@Mixin(FlowableFluid.class) public class MixinFlowableFluid implements BucketEmptySoundGetter { @Override public Optional<SoundEvent> getBucketEmptySound() { //Вот как получить звук по умолчанию, скопированный из класса BucketItem. return Optional.of(((FlowableFluid) (Object) this).isIn(FluidTags.LAVA) ? SoundEvents.ITEM_BUCKET_EMPTY_LAVA : SoundEvents.ITEM_BUCKET_EMPTY); } }
Наконец, вам нужно ввести интерфейс в net.minecraft.fluid.FlowableFluid
.
Следующий фрагмент можно добавить в ваш файл fabric.mod.json, чтобы добавить один или несколько интерфейсов к классу net.minecraft.fluid.FlowableFluid
.
Обратите внимание, что все имена классов здесь должны использовать “внутренние имена”, которые используют косые черты вместо точек (example/path/to/Class
).
{ "custom": { "loom:injected_interfaces": { "net/minecraft/class_3609": ["net/fabricmc/example/BucketEmptySoundGetter"] } } }
Теперь вы можете использовать новый метод:
Optional<SoundEvent> sound = mytestfluid.getBucketEmptySound();
Вы также можете переопределить этот метод в классах, расширяющих FlowableFluid, для реализации пользовательского поведения.