【问题标题】:class that extends from a generic type parameter (type variable)?从泛型类型参数(类型变量)扩展的类?
【发布时间】:2014-01-02 23:12:45
【问题描述】:

是否可以让类从泛型类型扩展?

我想使用implementsextends 对不同的组件进行子类化,以便为所有子类添加统一的功能。

我想要实现的是:

class MyTable extends MyAbstractComponent<JTable> {...}
class MyPanel extends MyAbstractComponent<JPanel> {...}


    MyAbstractComponent t = new MyTable();
    MyAbstractComponent p = new MyPanel();
    container.add(t);
    container.add(p);

在这种情况下,我将如何制定MyAbstractComponent
我尝试了以下方法,但它给了我错误“找到类型:参数 C。预期:类”:

abstract class MyAbstractComponent<C extends Component> extends C {...}

【问题讨论】:

  • 你想用C做什么?
  • @SotiriosDelimanolis 让子类从 C 扩展。例如,我可以在 MyTable 中执行 getSelectedRows(),因为 C 是那里的 JTable。

标签: java generics abstract-class


【解决方案1】:

你已经从编译器那里得到了一个很好的答案,所以不可能让一个类扩展一个类型参数。类型参数不是类。而不是abstract class MyAbstractComponent&lt;C extends Component&gt; extends C {...},我会简单地省略泛型(在这里不太有用)或写:

abstract class MyAbstractComponent<C extends Component> extends Component {...}

关于重写getSelectedRows()的愿望:

这只能在 JTable 子类中实现,而不能在您的面板子类中实现。在这种情况下,我推荐另一种方法:

  1. 将 MyAbstractComponent 定义为接口。
  2. 重新定义你的子类。

    class MyTable extends JTable implements MyAbstractComponent // 这里覆盖 getSelectedRows() 类 MyPanel 扩展 JPanel 实现 MyAbstractComponent

如果您的 MyAbstractComponent 中已经有一些方法实现,那么请考虑将此代码移动到由 MyTable 和 MyPanel 调用的帮助器类中。由于历史原因,在不使用此语言功能的环境 (SWING) 中,泛型并不是很有用。

无论如何,如果您有兴趣了解有关泛型的更多信息,我推荐 Angelika Langers 教程和有关泛型的常见问题解答(只需 google)。

【讨论】:

  • 所以我尝试的是不可能的。还有其他方法可以实现我的目标吗?我需要覆盖我的类中的某些方法,所以你的方法是不可能的。 (例如,覆盖 MyTable 中的 getSelectedRows())
  • @Zom-B 我已经为您的用例扩展了我的答案。
  • 我考虑了那个确切的选项,甚至在问题中写了它并在提交之前将其删除。问题是您不能强制子类从组件扩展,因此container.add((Component)x) 可能会出现运行时错误。
  • @Zom-B 你的变量容器是什么类型的?如果只是 java.awt.Container 并且考虑到 MyTable 和 MyPanel 间接继承自 Component 的事实,那么 container.add(x) 应该是可能的(x = MyTable-instance 或 MyPanel-instance)。
  • 你的假设是正确的。我的意思是:如果有人让class MyEvilClass extends Integer implements MyAbstractComponent 怎么办?
【解决方案2】:

我做了某事。我的 DAO 层类似

public interface EntityDAO<E, I> {
    public boolean update(final E entity, Connection connection);
    public E getByID(I id, Connection connection);
    public boolean delete(final I identifier, Connection connection);
}

public abstract class AbstractEntityDAO<E extends Entity, I extends Number> implements EntityDAO<E, I> {

    @Override
    public boolean update(E entity, Connection connection) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public E getByID(I id, Connection connection) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean delete(I identifier, Connection connection) {
        // TODO Auto-generated method stub
        return false;
    }
}

最后,具体的子类将定义实体对象的类型。

public class AddressEntityDAO extends AbstractEntity<Address, Integer> {

    @Override
    public boolean update(Address entity, Connection connection) {
        return super.update(entity, connection);
    }

    @Override
    public Address getByID(Integer id, Connection connection) {
        return super.getByID(id, connection);
    }

    @Override
    public boolean delete(Integer identifier, Connection connection) {
        return super.delete(identifier, connection);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    相关资源
    最近更新 更多