当前位置: 首页 > 知识库问答 >
问题:

使用枚举作为方法引用持有者的Java?

锺离旻
2023-03-14

我将尽最大努力用一个场景来解释我的问题:

我有一个ClassA,它只包含一个ClassB的非静态实例,许多影响ClassB实例的非静态方法(我们可以调用EFFECTS)和最后一个返回ClassB实例的非静态getter方法。

我有ClassC,它包含ClassB实例的非静态数组。在ClassC中,我有两个非静态方法,一个从数组中获取ClassB的单个实例,另一个通过给定的索引值设置ClassB的单个实例。

我想做的是:我想要一个ClassD,您可以创建它的实例,它的行为类似于一个效果列表,ClassD将有一个非静态方法,将ClassC作为参数。然后,该方法将存储在ClassD实例中的所有这些效果应用于存储在该方法中提供的ClassC参数数组中的ClassB的每个实例。最后,该方法返回其数组中更改了ClassB值的ClassC。

我目前的解决方案,但我不知道如何让它工作是创建一个枚举与方法引用作为常量?然后能够把这些存放在教室里?然后给他们打电话?但是我不太熟悉枚举,我在网上搜索过这个,但是找不到如何使它工作。

场景示例:

public class ClassA {
    ClassB classB;
    public ClassB get() { return classB; }

    public void effectA() {
        //affects classB instance
    }

    public void effectB() {
        //affects classB instance
    }

    public void effectC() {
        //affects classB instance
    }
}

public class ClassB {
    //Code for ClassB
}

public class ClassC {
    ClassB[] classBs;

    public ClassC(int size) {
        classBs = new ClassB[size];
    }

    public ClassB getB(int index) {
        return classBs[index];
    }

    public void setB(int index, ClassB classB) {
        classBs[index] = classB;
    }

    public int getSize() {
        return classBs.length;
    }
}

public class ClassD {
    ArrayList<Effects> effects;

    public ClassD() {
        effects = new ArrayList<Effects>();
    }

    public void addEffect(Effects effect, int effectIntensity) {
        //???
    }

    public void removeEffect(int index) {
        effects.remove(index);
    }

    public ClassC applyEffects(ClassC classC) {
        for (int i = 0; i < classC.getSize(); i++) {
            ClassB classB = classC.getB(i);
            //Apply all effects from effects ArrayList to classB
            classC.setB(i, classB);
        }
        return classC;
    }
}

public enum Effects {
    //??? Code related to effect methods from ClassA
}

问号在哪里,这就是我不知道如何做到这一点,以实现我的努力。

共有2个答案

申屠宏胜
2023-03-14

也许您可以使用命令模式的变体?

类D将是调用程序,并将所有要在数组/列表中执行的效果(命令)保存。如果你不想在运行时添加效果,你可以在构造函数中添加它们。

ClassD将有一个方法执行AllOn(ClassC),该方法执行ClassC数组中ClassB对象的所有效果。

参考:命令模式[维基百科]

在我看到你的例子后编辑,看起来像这样:

public class ClassD {
    ArrayList<Effect> effects;
    HashMap<Effect, Integer> intensity;

    public ClassD() {
        effects = new ArrayList<Effects>();
    }

    public void addEffect(Effects effect, int effectIntensity) {
        effects.add(effect)
        intensity.put(effect, effectIntensity)
    }

    public void removeEffect(int index) {
        effects.remove(index);
        intensity.remove(effects.get(index))
    }

    public ClassC applyEffects(ClassC classC) {
        for (int i = 0; i < classC.getSize(); i++) {
            ClassB classB = classC.getB(i);
            for (Effect effect : effects) {
               effect.execute(classB, intensity.get(effect))
            }
            classC.setB(i, classB);
        }
        return classC;
    }
}    
琴琪
2023-03-14

我要缩短你的例子,因为你有很多事情正在进行,我认为这些事情并不适用于你问的问题。

枚举常量基本上只是枚举类的公共静态最终实例。因此,您可以声明抽象方法,并在每个常量上重写它们。

enum ClassAEffect {
    A { @Override void apply(ClassA theA) { theA.effectA(); } },
    B { @Override void apply(ClassA theA) { theA.effectB(); } },
    C {
        @Override
        void apply(ClassA theA) {
            theA.effectC();
        }
    };

    abstract void apply(ClassA theA);
}

class ClassD {
    List<ClassAEffect> effects = new ArrayList<>();

    void add(ClassAEffect effect) { effects.add(effect); }

    void apply(List<ClassA> list) {
        for(ClassA theA : list)
            for(ClassAEffect effect : effects)
                effect.apply(theA);
    }
}
ClassD theD = new ClassD();
theD.add(ClassAEffect.B);
theD.apply(Arrays.asList(new ClassA()));

枚举可能合适,也可能不合适。例如,如果您的设计需要多个类的效果,那么使用常规接口可能会好得多。

interface Effect<T> {
    void apply(T theT);
}

Effect<ClassA> classAEffectA = new Effect<>() {
    @Override
    public void apply(ClassA theA) {
        theA.effectA();
    }
};

正如另一个答案所指出的,这基本上就像命令模式,维基百科包含了一个与你自己惊人相似的Java例子。

此外,在Java8中,您可以直接使用方法引用。

class ClassD implements Consumer<List<ClassA>> {
    List<Consumer<ClassA>> effects = new ArrayList<>();

    void add(Consumer<ClassA> effect) { effects.add(effect); }

    @Override
    public void accept(List<ClassA> theList) {
        for(ClassA theA : theList)
            for(Consumer<ClassA> effect : effects)
                effect.accept(theA);
    }
}
ClassD theD = new ClassD();
// ClassA::effectB implicitly creates a Consumer<ClassA>
// that calls effectB on the ClassA that is passed to it
theD.add(ClassA::effectB);
theD.accept(Arrays.asList(new ClassA()));
 类似资料:
  • 问题内容: 在我的MySQL数据库中,有“ gender enum(’male’,’female’)”列 我创建了枚举“ com.mydomain.myapp.enums.Gender”,并在我的实体中定义了“性别”。 现在,我想将枚举类型保留在我的MySQL数据库中,但是当我启动应用程序时,我得到: 性别列在MyApp.Person中的列类型错误。找到:枚举,预期:整数 为什么是这样?这就像我用

  • 问题内容: 在我的MySQL数据库中,有“ gender enum(’male’,’female’)”列 我创建了枚举“ com.mydomain.myapp.enums.Gender”,并在我的实体中定义了“性别”。 现在,我想将枚举类型保留在我的MySQL数据库中,但是当我启动应用程序时,我得到: 性别列在MyApp.Person中的列类型错误。找到:枚举,预期:整数 为什么是这样?就像我用“

  • 枚举(enum)是定义一组命名常量的机制,用这种方式定义的常量被称作枚举常量 注:枚举常量的数据类型是整数 使用方法: 下面我们以文本语音转换为例子,说明一下枚举常量的使用方法。 首先我们在窗体上放入语音识别控件,按钮,通用对话框这些基本控件,来制作一个简单的语音文本朗读程序。 1 如果您使用过语音识别控件,就应该知道,使用这个控件的第一步就是先创建它,而创建命令的两个参数就是枚举常量,我们可以看

  • 问题内容: 帮我了解泛型。说我有两个枚举作为内部类,如下所示: 我不想让两个枚举都实现一个接口,而不得不两次实现相同的方法,而是希望在外部类中有一个方法可以执行以下操作: 但是,此方法无法编译。我要尝试做的是找出字符串值是否为枚举值的名称(在任何枚举中),无论是蔬菜,水果,还是其他。不管这实际上是否是冗余方法,我尝试(重新)编写的方法有什么问题? 基本上我想这样做: 问题答案: 原来有几个问题:

  • 我目前正在将Jersey 1. x项目迁移到2.4.1,并在使用枚举作为参数(PathParam、QueryParam等)时遇到错误。基本上,此枚举应该是有效的,基于泽西对方法参数的第三个要求 有一个名为valueOf或fromString的静态方法,它接受一个String参数(例如,请参见Integer.valueOf(String)和java.util.UUID.fromStriing(Str

  • 本文向大家介绍Java的枚举类型使用方法详解,包括了Java的枚举类型使用方法详解的使用技巧和注意事项,需要的朋友参考一下 1.背景 在java语言中还没有引入枚举类型之前,表示枚举类型的常用模式是声明一组具有int常量。之前我们通常利用public final static 方法定义的代码如下,分别用1 表示春天,2表示夏天,3表示秋天,4表示冬天。 这种方法称作int枚举模式。可这种模式有什么