Java - 从父类动态改变子类

发布于 2024-11-16 16:16:55 字数 1667 浏览 1 评论 0原文

我有一个类,其中包含以下内容:

final class Attributes {

    Attribute agility;
    Attribute endurance;
    Attribute intelligence;
    Attribute intuition;
    Attribute luck;
    Attribute speed;
    Attribute strength;

    private ArrayList<Attribute> attributes;

    private boolean initialized = false;

    public Attributes() throws IllegalAccessException {
        initializeAttributes();
        store();
    }

    public ArrayList<Attribute> getAttributes() {
        return attributes;
    }

    private void initializeAttributes() {
        if (!initialized) {

            agility = new Agility();
            endurance = new Endurance();
            intelligence = new Intelligence();
            intuition = new Intuition();
            luck = new Luck();
            speed = new Speed();
            strength = new Strength();

            initialized = true;
        }
    }

    private void store() throws IllegalAccessException {
        Field[] fields = this.getClass().getDeclaredFields();

        attributes = new ArrayList<Attribute>();

        if (initialized) {

            for (Field f : fields) {
                if (f.getType() == Attribute.class) {
                    attributes.add((Attribute)f.get(this)); 
                }
            }
        }
    }

我的想法是以某种方式使用这样的方法:

public void setAttribute(Class attribute.getClass(), int value) {

    }

在该方法中,调用者将指定要更改的属性类型(例如力量、智力等),并且一个进程将通过识别传递的属性子类是否等于上述向量的子类,遍历充满上面列出的属性的向量数组,以确定要操作的属性。如果是这种情况,向量中的子类将被更改。

这可能吗?我问这个的主要原因是因为我不确定 obj.getClass()/getType() == obj2.getClass()/getType() 是否也会考虑子类。

I have a class, which has the following:

final class Attributes {

    Attribute agility;
    Attribute endurance;
    Attribute intelligence;
    Attribute intuition;
    Attribute luck;
    Attribute speed;
    Attribute strength;

    private ArrayList<Attribute> attributes;

    private boolean initialized = false;

    public Attributes() throws IllegalAccessException {
        initializeAttributes();
        store();
    }

    public ArrayList<Attribute> getAttributes() {
        return attributes;
    }

    private void initializeAttributes() {
        if (!initialized) {

            agility = new Agility();
            endurance = new Endurance();
            intelligence = new Intelligence();
            intuition = new Intuition();
            luck = new Luck();
            speed = new Speed();
            strength = new Strength();

            initialized = true;
        }
    }

    private void store() throws IllegalAccessException {
        Field[] fields = this.getClass().getDeclaredFields();

        attributes = new ArrayList<Attribute>();

        if (initialized) {

            for (Field f : fields) {
                if (f.getType() == Attribute.class) {
                    attributes.add((Attribute)f.get(this)); 
                }
            }
        }
    }

My idea is to somehow use a method like so:

public void setAttribute(Class attribute.getClass(), int value) {

    }

In this method, the caller would specify the type of attribute to alter (such as strength, intelligence, etc.), and a process would go through the vector array full of Attributes listed above to determine which attribute to manipulate, by identifying whether or not the passed attribute subclass was equal to a subclass from the mentioned vector. If this was the case, the subclass within the vector would be altered.

Is this possible? The main reason why I'm asking this because I'm not sure if obj.getClass()/getType() == obj2.getClass()/getType() will take into consideration subclasses as well.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

樱花细雨 2024-11-23 16:16:55

是的,你可以做到。 obj.getClass() 将返回 obj 的确切类,无论您声明哪种类型的 obj。
我建议您尽可能不要使用反射。您可以将属性继承替换为 enum:

enum Attribute {
    STREGTH, AGILITY, SPEED, ...;
}

并具有类似以下内容:

public final class Attributes {
     private Map<Attribute, Integer> attributes = new EnumMap(Attribute.class);

     private void initializeAttributes() {
        if (!initialized) {
            for(Attribute att : Attribute.values()) {
                attributes.put(att, 0);
            }
            initialized = true;
        }
     }


     public void setAttribute(Attribute attribute, int value) {
         attributes.put(attribute, value);
     }
}

Yes, you can do it. obj.getClass() will return exact class of obj, regardless which type obj you declare.
I advice you do not use reflection, where it is possible. You can replace Attribute inheritance with enum:

enum Attribute {
    STREGTH, AGILITY, SPEED, ...;
}

And have something like:

public final class Attributes {
     private Map<Attribute, Integer> attributes = new EnumMap(Attribute.class);

     private void initializeAttributes() {
        if (!initialized) {
            for(Attribute att : Attribute.values()) {
                attributes.put(att, 0);
            }
            initialized = true;
        }
     }


     public void setAttribute(Attribute attribute, int value) {
         attributes.put(attribute, value);
     }
}
梦亿 2024-11-23 16:16:55

您基本上要寻找的是 Class.isAssignableFrom(...)。它将检查当前类是否与参数给定类相同或者是超类。

您只需迭代数组并删除重复的属性并向其中添加新属性即可。

What you are basically looking for is Class.isAssignableFrom(...). It will check if the current class is the same or a superclass of the as parameter given class.

You have simply to iterate through your array and remove the attribute which is duplicate and add the new attribute to it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文