Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 编辑引用的类_Java_Oop_Maven_Inheritance - Fatal编程技术网

Java 编辑引用的类

Java 编辑引用的类,java,oop,maven,inheritance,Java,Oop,Maven,Inheritance,我正在从事一个Maven项目。在引用的JAR中有一个包,其中包含一个类文件。我需要向这个类添加一些代码行,但不幸的是这个类不可编辑。 我的想法是创建一个新类,从这个引用的类扩展它,并将我的代码行添加到新创建的类中。这里的问题是,代码有点复杂,并且类彼此扩展 // existing class public class ReferencedClass extends AnotherClass{ // ... } // my idea public class MyClass extends R

我正在从事一个Maven项目。在引用的JAR中有一个包,其中包含一个类文件。我需要向这个类添加一些代码行,但不幸的是这个类不可编辑。 我的想法是创建一个新类,从这个引用的类扩展它,并将我的代码行添加到新创建的类中。这里的问题是,代码有点复杂,并且类彼此扩展

// existing class
public class ReferencedClass extends AnotherClass{
  // ...
}
// my idea
public class MyClass extends ReferencedClass{
  // add my code here
}

// where those classes are needed
public class SomeClass{
  anObject o = new anObject(); // creates new object, whose class also extends from ReferencedClass
}
// this class also extends from ReferencedClass
public class anObject extends ReferencedClass{
  // ...
}
我不确定如何实例化我自己创建的类MyClass。我应该在所有也使用ReferenceClass的类中这样做吗? 在根本不创建新类的情况下,我的问题还有其他解决方案吗


谢谢大家!

如果要在不使用setter的情况下修改字段,则包装器没有用处。下一个解决方案是否有用取决于您试图修改的字段是私有字段还是受保护字段。如果访问修饰符是私有的,则只有类本身的实例可以修改字段。如果受保护,子类还可以访问和修改字段

//this is our class within the library. We cant edit its source
class APIClass {
    private int privatefield;
    protected int protectedfield;

    public String doStuff() { ... }
    public int doMoreStuff() { ... }
}

class MyExtendedAPIClass extends APIClass {
    // you dont have to override doStuff and doMoreStuff

    void setValues() {
        protectedfield = 10; //compiles, protectedfield is protected
        privatefield = 1; //does not compile, privatefield is private
    }
}
如果它是一个私有字段,并且您仍然希望更改其值,那么您可以使用反射,在这种情况下,您不需要另一个类:

void setFieldWithReflection() {
    APIClass apiClass = new APIClass();
    try {
        Field fieldToEdit = apiClass.getClass().getField("privatefield");
        fieldToEdit.set(apiClass, 25);
    }
    catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
        e.printStackTrace();
    }
}
编辑:由于setter只设置一个字段,所以可以使用反射设置该字段。但OP要求它是一种我不知道的方法,但好吧,我会采用这种实现:

//this is our class within the library. We cant edit its source
class APIClass {
    private int privatefield;

    public int getPrivatefield() {
        return privatefield;
    }
}

class MyExtendedAPIClass extends APIClass {
    // you dont have to override doStuff and doMoreStuff

    public void setPrivatefield(int value) {
        try {
            Field field = this.getClass().getSuperclass().getDeclaredField("privatefield");
            field.setAccessible(true);
            field.set(this, value);
        }
        catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}
以上工作。代码测试

MyExtendedAPIClass mApi = new MyExtendedAPIClass();
mApi.setPrivatefield(5);
System.out.println(mApi.getPrivatefield);//outputs '5'

如果我是你,我会创建一个包装类,并在你自己的项目/代码中只使用该类。很难提供有意义的建议,但是如果你想修改的类不是你的,你可能不应该修改它。如果不知道您真正想用它做什么,就很难说您是否应该扩展同一个类。替代方法包括AOP、带有委托的简单组合、装饰器等@DaveNewton:我只需要添加一个简短的setter方法。@stealthjong:你是说在引用的类周围添加一个包装器?你能给我举个简单的例子吗?谢谢!我只需要向类添加另一个setter方法,而不修改任何字段。