Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.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_Inheritance_Design Patterns_Overriding - Fatal编程技术网

Java-如何在子匿名类中强制重写方法?

Java-如何在子匿名类中强制重写方法?,java,inheritance,design-patterns,overriding,Java,Inheritance,Design Patterns,Overriding,我一直在设计一些源代码,因为我们的项目中有很多代码在进行SQL查询时被重复 因此,我在下面编写了这段代码,尝试类似于命令模式的东西似乎效果不错。它只接收一个字符串形式的SQL查询和一些要在语句上设置的参数(如果需要)。因此,您可以将此代码用作匿名类,只执行定义如何处理查询输出的查询 我的问题是,我想将其设计为强制在匿名子类中定义和编写方法getResult,但如果不生成抽象方法和类,我想不出任何方法 如果QueryCommand变得抽象,我应该创建另一个类来实例化,而这个类不能是抽象的。有没有其

我一直在设计一些源代码,因为我们的项目中有很多代码在进行SQL查询时被重复

因此,我在下面编写了这段代码,尝试类似于命令模式的东西似乎效果不错。它只接收一个字符串形式的SQL查询和一些要在语句上设置的参数(如果需要)。因此,您可以将此代码用作匿名类,只执行定义如何处理查询输出的查询

我的问题是,我想将其设计为强制在匿名子类中定义和编写方法getResult,但如果不生成抽象方法和类,我想不出任何方法

如果QueryCommand变得抽象,我应该创建另一个类来实例化,而这个类不能是抽象的。有没有其他方法可以使强制在子类中优先?我正在寻找最聪明最简单的方法来实现它

不知道如何搜索类似的模式或解决方案

提前谢谢

源代码:

import java.sql.Connection;
import java.sql.SQLException;

public interface IQueryCommand<T> {
    T executeQuery(Connection conn, String query, Object... args) throws SQLException;
}


import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.MessageFormat;
import org.apache.log4j.Logger;

public class QueryCommand<T> implements IQueryCommand<T> {
    private Logger LOGGER = Logger.getLogger(this.getClass());

    /** The constant ERROR_CLOSING_RESULT_SET */
    protected static final String ERROR_CLOSING_RESULT_SET = "Error when closing ResultSet";

    /** The Constant ERROR_CLOSING_PREPARED_STATEMENT. */
    protected static final String ERROR_CLOSING_PREPARED_STATEMENT = "Error when closing PreparedStatement";

    // FIXME: I want this method to be mandatory to be defined in the anonymous child class
    protected T getResult(ResultSet rs) throws SQLException {
        return null;
    };


    public T executeQuery(Connection conn, String sqlQuery, Object... args) throws SQLException {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug(sqlQuery);
        }
        PreparedStatement ps = null;
        ps = conn.prepareStatement(sqlQuery);

        return executeQuery(conn, ps, args);
    }

    public T executeQuery(Connection conn, PreparedStatement ps, Object... args) throws SQLException {
        ResultSet rs = null;
        try {
            if(args != null && args.length > 0) {           
                for(int i=0; i< args.length; i++) {
                    setArg(ps, i+1, args[i]);
                }
            }
            rs = ps.executeQuery();
            T result = getResult(rs); // Method defined in child class

            return result;
        } catch (SQLException e) {
            throw e;
        } finally {     
            if(rs != null) {
                try {
                    rs.close();
                } catch (final SQLException e) {
                    LOGGER.error(ERROR_CLOSING_RESULT_SET, e);
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                } catch (final Exception e) {
                    if(ps instanceof CallableStatement) {
                        LOGGER.error("Error when closing CallableStatement", e);
                    } else if(ps instanceof PreparedStatement) {
                        LOGGER.error(ERROR_CLOSING_PREPARED_STATEMENT, e);
                    }
                }
            }
        }
    }


    /**
     * Sets a value on the PreparedStatemente with a method dependending on dataType
     * 
     * @param ps the preparedStatement
     * @param idx the index on which the value is set
     * @param value the value to set
     * @throws SQLException if an error is detected
     */
    private void setArg(PreparedStatement ps, int idx, Object value) throws SQLException {
        // Implementation not relevant...
    }
}
导入java.sql.Connection;
导入java.sql.SQLException;
公共接口命令{
T executeQuery(连接连接、字符串查询、对象…参数)抛出SQLException;
}
导入java.math.BigDecimal;
导入java.sql.CallableStatement;
导入java.sql.Connection;
导入java.sql.PreparedStatement;
导入java.sql.ResultSet;
导入java.sql.SQLException;
导入java.text.MessageFormat;
导入org.apache.log4j.Logger;
公共类QueryCommand实现IQueryCommand{
私有记录器=Logger.getLogger(this.getClass());
/**常量错误\u关闭\u结果\u集*/
受保护的静态最终字符串错误\u关闭\u结果\u SET=“关闭结果集时出错”;
/**常量错误\u关闭\u准备了\u语句*/
受保护的静态最终字符串错误\u关闭\u准备好的\u语句=“关闭准备好的语句时出错”;
//FIXME:我希望此方法必须在匿名子类中定义
受保护的T getResult(ResultSet rs)引发SQLException{
返回null;
};
public T executeQuery(连接连接、字符串sqlQuery、对象…args)抛出SQLException{
if(LOGGER.isDebugEnabled()){
调试(sqlQuery);
}
PreparedStatement ps=null;
ps=conn.prepareStatement(sqlQuery);
返回执行(conn、ps、args);
}
public T executeQuery(连接连接、PreparedStatement ps、对象…args)引发SQLException{
结果集rs=null;
试一试{
如果(args!=null&&args.length>0){
对于(int i=0;i
如何使用此功能的示例

sqlQuery = " SELECT X FROM Y WHERE countryId = ? and languageId = ?";
return new QueryCommand<String>() {
    // This method should be REQUIRED when compiling
    @Override
    protected String getResult(ResultSet rs) throws SQLException {
        String result = "";
        while (rs.next()) {
            result = rs.getString("DESCRIPTION");
        }
        return result;
    };
}.executeQuery(getDB2Connection(), sqlQuery.toString(), new Object[] { countryIdParameter, languageIdParameter});
sqlQuery=“从Y中选择X,其中countryId=?和languageId=?”;
返回新的QueryCommand(){
//编译时应该需要此方法
@凌驾
受保护的字符串getResult(ResultSet rs)引发SQLException{
字符串结果=”;
while(rs.next()){
结果=rs.getString(“说明”);
}
返回结果;
};
}.executeQuery(getDB2Connection(),sqlQuery.toString(),新对象[]{countryIdParameter,languageIdParameter});

生成
QueryCommand
抽象,然后创建一个额外的具体final类。这样,任何匿名类都需要实现该方法,但您仍然可以实例化一个非抽象类(因为这显然是一个要求,尽管我不明白为什么)

如果没有一个抽象的方法和类,我想不出任何方法来实现它

抽象类正是您需要的机制

我应该创建另一个能够实例化的类,它不能是抽象的

这是不正确的:匿名类完全可以继承抽象类,甚至可以扩展接口,当然前提是它们实现了所有抽象方法:

public class AbstractQueryCommand<T> implements IQueryCommand<T> {
    abstract protected String getResult(ResultSet rs) throws SQLException;
    ...
}
return new AbstractQueryCommand<String>() {
    @Override
    protected String getResult(ResultSet rs) throws SQLException {
        String result = "";
        while (rs.next()) {
            result = rs.getString("DESCRIPTION");
        }
        return result;
    };
}
公共类AbstractQueryCommand实现IQueryCommand{
抽象保护字符串getResult(ResultSet rs)抛出SQLException;
...
}
返回新的AbstractQueryCommand(){
@凌驾
受保护的字符串getResult(ResultSet rs)引发SQLException{
字符串结果=”;
while(rs.next()){
结果=rs.getString(“说明”);
}
返回结果;
};
}

你似乎知道该怎么做:制作
QueryCommand
摘要。有什么问题吗