简体   繁体   English

访问子类中的私有字段

[英]Accessing private field in a subclass

I'm creating a class that extends PropertyChangeSupport . 我正在创建一个扩展PropertyChangeSupport的类。 What I currently want to do is override firePropertyChange() : 我目前想要做的是覆盖firePropertyChange()

firePropertyChange as it is implemented in PropertyChangeSupport: firePropertyChange,因为它在PropertyChangeSupport中实现:

public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
    if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
        firePropertyChange(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue));
    }
}

my intended override of firePropertyChange : 我打算覆盖firePropertyChange

public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
    if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
        firePropertyChange(new JoystickPropertyChangeEvent(this.source, propertyName, oldValue, newValue)); //compile error: source is not visible
    }
}

JoystickPropertyChangeEvent is a class that I created and that extends ProperyChangeEvent . JoystickPropertyChangeEvent是我创建的一个类,它扩展了ProperyChangeEvent

The problem is that my intended implementation does not compile because source is private and has no getters in PropertyChangeSupport , so subclasses have no access to it. 问题是我的预期实现没有编译,因为source是私有的,并且在PropertyChangeSupport没有getters ,所以子类无法访问它。 I cannot modify PropertyChangeSupport 's code. 我无法修改PropertyChangeSupport的代码。

Is there a more elegant way of solving this than having a private copy of source as a field of my subclass? 是否有一种更优雅的解决方法,而不是将的私有副本作为我的子类的字段?

Related question: How to access the private variables of a class in its subclass? 相关问题: 如何在其子类中访问类的私有变量?

I would question the design of this. 我会质疑这个的设计。

The method that you are trying to override has been made private for a reason, even if you could change its implementation I wouldn't advise it since you don't know what impact this will have elsewhere. 您尝试覆盖的方法由于某种原因而被设置为私有,即使您可以更改其实现,我也不会建议它,因为您不知道这将在其他地方产生什么影响。

If you were really stupid, you might try to solve this problem with reflection. 如果你真的很蠢,你可能会尝试用反射来解决这个问题。 But that's so complicated I won't even mention it again. 但那太复杂了我甚至都不会再提起它了。

It seems like your goal is to have property change listeners be able to tell some events apart from other events. 看起来您的目标是让财产变更听众能够将某些事件与其他事件区分开来。 If the listeners can tell them apart without help, just do that. 如果听众可以在没有帮助的情况下将他们分开,就这样做。 If that's inconvenient, provide a static method to ananlyze a property change event and return whether it should have been a JoystickPropertyChangeEvent . 如果这不方便,请提供一个静态方法来分析属性更改事件并返回它是否应该是JoystickPropertyChangeEvent

Also, why should you use property change events at all? 另外,为什么要使用房产变更事件呢? If you want to fire an event when the state of the joystick updates, you should fire your own custom event for that. 如果要在操纵杆状态更新时触发事件,则应为此触发自己的自定义事件。

Since you extend PropertyChangeSupport you are calling super() in constructor correct? 既然你扩展了PropertyChangeSupport你在构造函数中调用super()是否正确? The original constructor of PropertyChangeSupport takes the source (ie a bean) as an argument. PropertyChangeSupport的原始构造函数将source (即bean)作为参数。

public PropertyChangeSupport(Object sourceBean) . public PropertyChangeSupport(Object sourceBean)

The sourceBean argument is the source you want. sourceBean参数是您想要的source Use your own private member to save that reference. 使用您自己的私有成员来保存该引用。 Then you could use it inside the firePropertyChange() method. 然后你可以在firePropertyChange()方法中使用它。

public static class MyPropertyChangeSupport extends PropertyChangeSupport {
    private Object mySource;

    public MyPropertyChangeSupport(Object sourceBean) {
        super(sourceBean);
        // store the bean reference in your field
        this.mySource = sourceBean;
    }

    @Override
    public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
        if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
            // use mySource here
            firePropertyChange(new JoystickPropertyChangeEvent(mySource, propertyName, oldValue, newValue)); 
        }
    }
}

You can use reflection for this purpose. 您可以使用反射来实现此目的。

If ParentClass private variable is like 如果ParentClass私有变量是这样的

private String private_source_parent = "some_value";

inside your ChildClass which extending parent class 在你的ChildClass里面扩展父类

ParentClass obj = new ParentClasS();
Field f = obj.getClass().getDeclaredField("private_source_parent"); //NoSuchFieldException
f.setAccessible(true);
String source_inchild = (String) f.get(obj);

Here in your ChildClass you will get the value of parent private member. 在您的ChildClass中,您将获得父私有成员的值。

You could use the getter-method of your superclass to get the source property ie 您可以使用超类的getter方法来获取源属性,即

super.firePropertyChange(new JoyStickPropertyChangeEvent(super.getSource, propertyName, oldValue, newValue); 

This should do the trick. 这应该可以解决问题。 As explanation you have to call the firePropertyChange method of the super class explicit. 作为解释,您必须显式调用超类的firePropertyChange方法。 This is done with the keyword super. 这是通过关键字super完成的。

Hope this helps 希望这可以帮助

Cheers 干杯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM