当前位置: 首页 > 知识库问答 >
问题:

使用基本抽象类组合两个相似的类

李建中
2023-03-14

我正在处理一个项目的pull请求,有人告诉我,将两个类似类的代码组合成一个抽象类可能是个好主意,其他两个类将从中扩展。我的问题是我没有正确的方法来做这件事。以下是两个课程:

public class ClassOne<OUT> extends RichInputFormat<OUT, InputSplit> implements NonParallelInput {
private static final Logger LOG = LoggerFactory.getLogger(ClassOne.class);

private final String query;
private final ClusterBuilder builder;

private transient Cluster cluster;
private transient Session session;
private transient Result<OUT> resultSet;
private Class<OUT> inputClass;

public ClassOne(String query, ClusterBuilder builder, Class<OUT> inputClass) {
    Preconditions.checkArgument(!Strings.isNullOrEmpty(query), "Query cannot be null or empty");
    Preconditions.checkArgument(builder != null, "Builder cannot be null");
    Preconditions.checkArgument(inputClass != null, "InputClass cannot be null");

    this.query = query;
    this.builder = builder;
    this.inputClass = inputClass;
}

@Override
public void configure(Configuration parameters) {
    this.cluster = builder.getCluster();
}

@Override
public BaseStatistics getStatistics(BaseStatistics cachedStatistics) throws IOException {
    return cachedStatistics;
}

/**
 * Opens a Session and executes the query.
 *
 * @param ignored
 * @throws IOException
 */
@Override
public void open(InputSplit ignored) throws IOException {
    this.session = cluster.connect();
    MappingManager manager = new MappingManager(session);

    Mapper<OUT> mapper = manager.mapper(inputClass);

    this.resultSet = mapper.map(session.execute(query));
}

@Override
public boolean reachedEnd() throws IOException {
    return resultSet.isExhausted();
}

@Override
public OUT nextRecord(OUT reuse) throws IOException {
    return resultSet.one();
}

@Override
public InputSplit[] createInputSplits(int minNumSplits) throws IOException {
    GenericInputSplit[] split = {new GenericInputSplit(0, 1)};
    return split;
}

@Override
public InputSplitAssigner getInputSplitAssigner(InputSplit[] inputSplits) {
    return new DefaultInputSplitAssigner(inputSplits);
}

/**
 * Closes all resources used.
 */
@Override
public void close() throws IOException {
    try {
        if (session != null) {
            session.close();
        }
    } catch (Exception e) {
        LOG.error("Error while closing session.", e);
    }

    try {
        if (cluster != null) {
            cluster.close();
        }
    } catch (Exception e) {
        LOG.error("Error while closing cluster.", e);
    }
}
}

第二点是:

public class ClassTwo<OUT extends Tuple> extends RichInputFormat<OUT, InputSplit> implements NonParallelInput {
private static final Logger LOG = LoggerFactory.getLogger(ClassTwo.class);

private final String query;
private final ClusterBuilder builder;

private transient Cluster cluster;
private transient Session session;
private transient ResultSet resultSet;

public ClassTwo(String query, ClusterBuilder builder) {
    Preconditions.checkArgument(!Strings.isNullOrEmpty(query), "Query cannot be null or empty");
    Preconditions.checkArgument(builder != null, "Builder cannot be null");

    this.query = query;
    this.builder = builder;
}

@Override
public void configure(Configuration parameters) {
    this.cluster = builder.getCluster();
}

@Override
public BaseStatistics getStatistics(BaseStatistics cachedStatistics) throws IOException {
    return cachedStatistics;
}

/**
 * Opens a Session and executes the query.
 *
 * @param ignored
 * @throws IOException
 */
@Override
public void open(InputSplit ignored) throws IOException {
    this.session = cluster.connect();
    this.resultSet = session.execute(query);
}

@Override
public boolean reachedEnd() throws IOException {
    return resultSet.isExhausted();
}

@Override
public OUT nextRecord(OUT reuse) throws IOException {
    final Row item = resultSet.one();
    for (int i = 0; i < reuse.getArity(); i++) {
        reuse.setField(item.getObject(i), i);
    }
    return reuse;
}

@Override
public InputSplit[] createInputSplits(int minNumSplits) throws IOException {
    GenericInputSplit[] split = {new GenericInputSplit(0, 1)};
    return split;
}

@Override
public InputSplitAssigner getInputSplitAssigner(InputSplit[] inputSplits) {
    return new DefaultInputSplitAssigner(inputSplits);
}

/**
 * Closes all resources used.
 */
@Override
public void close() throws IOException {
    try {
        if (session != null) {
            session.close();
        }
    } catch (Exception e) {
        LOG.error("Error while closing session.", e);
    }

    try {
        if (cluster != null) {
            cluster.close();
        }
    } catch (Exception e) {
        LOG.error("Error while closing cluster.", e);
    }
}
}

不同之处在于Constructor()、open()和nextRecord()方法以及resultSet变量。一班和二班也有。我假设open和nextRecord方法只是不在抽象基类中实现它们,而让它们在类一和类二中实现。但是抽象基类需要有一个构造函数,这两个类有不同的构造函数,基类必须有or,这将使ClassOne或ClassTwo不能工作,这取决于所使用的构造函数。我觉得我忽略了一个简单的解决方案。

感谢任何帮助!谢谢!

共有1个答案

梁丘逸仙
2023-03-14

在Java(和其他语言)中,完全有可能有一个包含空构造函数的抽象类。因此,使用抽象类提供的两个类的组合可能看起来像这样:

public abstract class ClassAbstract extends RichInputFormat<OUT, InputSplit> implements NonParallelInput {

    private final String query;
    private final ClusterBuilder builder;
    private transient Cluster cluster;
    private transient Session session;

    public ClassAbstract(String query, ClusterBuilder builder) {
        Preconditions.checkArgument(!Strings.isNullOrEmpty(query), "Query cannot be null or empty");
        Preconditions.checkArgument(builder != null, "Builder cannot be null");
        this.query = query;
        this.builder = builder;
    }

    @Override
    public void configure(Configuration parameters) {
        this.cluster = builder.getCluster();
    }

    @Override
    public BaseStatistics getStatistics(BaseStatistics cachedStatistics) throws IOException {
        return cachedStatistics;
    }

    @Override
    public boolean reachedEnd() throws IOException {
        return resultSet.isExhausted();
    }

    @Override
    public InputSplit[] createInputSplits(int minNumSplits) throws IOException {
        GenericInputSplit[] split = {new GenericInputSplit(0, 1)};
        return split;
    }

    @Override
    public InputSplitAssigner getInputSplitAssigner(InputSplit[] inputSplits) {
        return new DefaultInputSplitAssigner(inputSplits);
    }

    /**
     * Closes all resources used.
     */
    @Override
    public void close() throws IOException {
        try {
            if (session != null) {
                session.close();
            }
        } catch (Exception e) {
            LOG.error("Error while closing session.", e);
        }

        try {
            if (cluster != null) {
                cluster.close();
            }
        } catch (Exception e) {
            LOG.error("Error while closing cluster.", e);
        }
    }

}

然后,您的ClassOne构造函数可以简单地:

    public ClassOne(String query, ClusterBuilder builder, Class<OUT> inputClass) {
        super(query, builder);
        Preconditions.checkArgument(inputClass != null, "InputClass cannot be null");
        this.inputClass = inputClass;
    }

ClassTwo的构造函数将变成:

    public ClassTwo(String query, ClusterBuilder builder) {
        super(query, builder);
    }

然后可以通过扩展抽象类并删除抽象类中已经存在的所有代码来实例化子类。

 类似资料:
  • 问题内容: 场景 我正在用Java编写涉及汽车的程序。 注意:我已尽最大可能简化了此方案,以使其更加通用和易于理解。 我实际上不是在开车。 我创建了一个类,它是对象的集合。 该对象具有一个(double)和一个(int)。构造函数将年份作为参数,例如: 这是棘手的部分…汽车必须具有某种类型(比如说Corvette或Clunker)。克尔维特(克尔维特)的车子为and,Cl子(Clunker)的车子

  • 抽象路由类 aiohttp使用抽象类来管理web接口。 aiohttp.web中大部分类都不打算是可以继承的,只有几个是可以继承的。 aiohttp.web建立在这几个概念之上: 应用(application),路由(router),请求(request)和响应(response)。 路由(router)是一个可插拔的部分: 用户可以从头开始创建一个新的路由库,不过其他的部分必须与这个新路由无缝契

  • 本文向大家介绍PHP抽象类基本用法示例,包括了PHP抽象类基本用法示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了PHP抽象类基本用法。分享给大家供大家参考,具体如下: 运行上述代码,会提示如下错误信息: Fatal error: Class Managers contains 1 abstract method and must therefore be declared abstr

  • How ABCs Work # abc_base.py import abc class PluginBase(metaclass=abc.ABCMeta): @abc.abstractmethod def load(self, input): """Retrieve data from the input source and return

  • 我只是开始尝试在我非常简单的项目上使用Hilt。现在它都是在Dagger2上,但我想迁移到Hilt。 我有一个活动: 和下面这样的基本活动: 或者(就像我用匕首那样): 另外,我只是一个初学者,所以,也许我错过了什么。我将继续搜索:) 感谢您的时间和回答:) java.lang.NullPointerException:尝试对空对象引用调用虚拟方法“Android.content.pm.Appli

  • 我有两个数组: 阵列 1: 和阵列 2: 我需要根据合并这两个数组并得到这个: 不通过< code>Object.keys进行迭代,我如何做到这一点?