Code reusing with anonymous class in Java

时间:2015-10-08 08:48:02

标签: java code-reuse anonymous-class

Java 7

I have the following interface:

public interface SqlOperator{

    public String apply(Object o);

    /**
    * @return an operator representing the set defined 
    * by inversing the image of {@this operator}.
    */
    public SqlOperator not();

    //Some other methods
}

And I have a few its implementations that look like:

public class Foo implements SqlOperator{

    public SqlOperator not(){
        return new Foo(){
            @Override
            public String apply(Object o){
                return String.format("NOT (%s)", super.apply(o));
            }
        };
    }

    //other methods implementation
}

and this

public class Bar implements SqlOperator{

    public SqlOperator not(){
        return new Bar(){
            @Override
            public String apply(Object o){
                return String.format("NOT (%s)", super.apply(o));
            }
        };
    }

    //other methods implementation
}

The thing is the not() method is pretty much the same for all implementation for now (Currently I have 7 ones) except the class to be instantiated with the new operator. Is there a way to avoid wiritng such boilerplate code any time I need to implement the SqlOperator.

3 个答案:

答案 0 :(得分:3)

在Java-8之前,标准选项是创建一个像AbstractSqlOperator implements SqlOperator这样的抽象类,它定义了具有一些标准实现的方法。然后具体实现扩展这个抽象类,而不是直接实现接口。

Java-8引入了一种使用默认方法执行此操作的新方法:

public interface SqlOperator{

    public String apply(Object o);

    /**
    * @return an operator representing the set defined 
    * by inversing the image of {@this operator}.
    */
    default public SqlOperator not() {
        return new SqlOperator(){
            @Override
            public String apply(Object o){
                return String.format("NOT (%s)", SqlOperator.this.apply(o));
            }

            @Override
            public SqlOperator not() {
                // double not: just return the original operator
                return SqlOperator.this;
            }
        };
    }

    //Some other methods
}

答案 1 :(得分:2)

将SqlOperator接口包装在抽象类中。然后让您的SomeImplementation类继承自抽象类。抽象类将实现接口not()方法。

public abstract class AbstractImplementation implements SqlOperator
{
    public SqlOperator not(){
    return new SomeImplementation(){
        @Override
        public String apply(Object o){
            return String.format("NOT (%s)", super.apply(o));
        }
    };
}

//...
public class SomeImplementation extends AbstractImplementation
{
    //... your stuff here
}

答案 2 :(得分:2)

你有很多选择。

如果您使用的是Java8,则可以在SqlOperator界面中创建默认方法,并且不需要跨子类实现它:

public interface SqlOperator{
    public default SqlOperator not() {
        return new SomeImplementation(){
            @Override
            public String apply(Object o){
                return String.format("NOT (%s)", super.apply(o));
            }
        };
    }
}

但是,如果您还没有升级到Java8,那么您可以只引入一个abstract子类SqlOperator,其中您将拥有not()实现,然后是所有其他实现者可以扩展这个抽象类。例如:

public abstract class AbstractSqlOperator implements SqlOperator {
    public SqlOperator not() {
        return new SomeImplementation(){
            @Override
            public String apply(Object o){
                return String.format("NOT (%s)", super.apply(o));
            }
        };
    }
}

public class SomeImplementation extends AbstractSqlOperator { ... }