当有多个不同的字段时,如何对类进行生成?

时间:2017-04-05 19:18:14

标签: java oop generics

假设:

class PhysicsClass {
    private PhysicsInstructor instructor;
    private Set<PhysicsStudent> students;
}

class ChemistryClass {
    private ChemistryInstructor instructor;
    private Set<ChemistryStudent> students;
}

class MathemeticsClass {
    private MathemeticsInstructor instructor;
    private Set<MathemeticsStudent> students;
}

是否可以在一个通用类中收集所有这些类,如:

class ScienceClass<T> {
    // What to write here?
    // What to write here?
}

如果无法做到这一点,那么如何防止代码重复?

我想把它变成:

class ScienceClass<T extends Instructor, S extends Student> {
    private T instructor;
    private Set<S> students;
}

但这可以让我做出类似的事情:

ScienceClass<PhysicsInstructor, ChemistryStudent> scienceClass;

这是不正确的。

3 个答案:

答案 0 :(得分:5)

从主题的界面开始

public interface Subject {}

public interface Physics extends Subject {}
public interface Chemistry extends Subject {}
public interface Mathematics extends Subject {}

下一步

public class Instructor<T extends Subject> {
  ...
}

然后,你可以为你的&#34;类&#34;创建一个类。

public class SchoolClass<T extends Subject> {
  Instructor<T> prof;
  ArrayList<Student<T>> students;
}

答案 1 :(得分:2)

根据你的例子,最自然的事情是从以下内容开始:

public interface Subject

public interface Instructor<S extends Subject> { ...

public interface Student<S extends Subject> { ...

以上例如允许执行以下操作:

public class Whatever<S extends Subject> {
  private T<S> instructor;
  List<S> students;

另一点在这里:永远记住好的旧“偏爱继承”。含义:要非常小心在这里创建各种不同的类和复杂的继承设置。

最后:当然,人们必须了解编程语言提供的内容;但是:对象/类模型的核心部分是:对现实有用的抽象。含义:首先不要过分关注如何使用泛型。首先,您应该仔细查看您的应用程序必须处理的现实世界的各个方面。然后围绕它构建你的解决方案!

答案 2 :(得分:2)

假设您希望两种类型符合&#34;匹配&#34;,您可以执行以下操作:

interface Subject {}

interface Instructor<T extends Subject> {}

interface Student<T extends Subject> {}

通过设置我们的基本界面,我们现在可以创建主题的实现:

class Physics implements Subject {}

class Chemistry implements Subject {}

你在这些课程中的内容取决于你,从技术上讲,你甚至可以把它们留空。接下来,定义代表学校类的泛型类。

class SchoolClass<T extends Subject> {
    private Instructor<T> instructor;
    private Set<Student<T>> students;
}

这两个字段之间存在链接,因为它们都引用相同的T类型参数。

从这一点可以看出,设计仍然不是很干净,特别是毫无意义的Subject实现。

在这一点上,做这样的事情是一个很诱人但很明显的坏主意:

//PLEASE DON'T DO THIS!
interface Instructor {}
interface Student<T extends Instructor> {}

万岁,我们已经避免了那个丑陋的Subject界面,但我们已经创造了看起来像学生和教师之间的错误关系。

故事的寓意是(这实际上取决于你的实际用例),继承和泛型可能不是解决这个问题的最佳工具。