簡體   English   中英

在 java 中使用具有泛型列表作為返回類型的抽象方法

[英]Using abstract method with generic list as return type in java

我試圖在抽象 class 中構建這個抽象方法,並在我的一個子類中使用它,它的返回類型應該是 List / ArrayList。 我真的在語法上苦苦掙扎,之前提出的大多數問題都不是指我的特殊問題。

對我來說最重要的是用簡單的話來描述它。

  1. 讓我用一個方法
  2. 該方法的 Output (返回)應該是一個列表......我還沒有什么對象
  3. 它的原始聲明是抽象的

這里抽象 class *

private int employeeID;
    private String name, sID, department;
    private double salary;

    // Constructor (empty)
    public Employee() {

    }

    // Constructor => Every Employee has at least this attributes => Subclasses may have additonal attributes
    public Employee(int employeeID, String name, String sID, double salary, String department) {
        this.employeeID = employeeID;
        this.name = name;
        this.sID = sID;
        this.salary = salary;
        this.department = department;
    }

    // Getters and Setters below
    //.......

 // Abstract method with generic list as return type
    public abstract <T> List<T> read(String path);

這是子類

public class Clerk extends Employee {

    public Clerk() {

    }

    public Clerk(int employeeID, String name, String sID, double salary, String department) {
        super(employeeID, name, sID, salary, department);
    }

    @Override
    public <T> List<T> read(String path) {
        // TODO Auto-generated method stub

        String line = null;
        List<Clerk> clerk = new ArrayList<Clerk>();

        try {
            BufferedReader reader = new BufferedReader(new FileReader(path));
            reader.readLine();

            while ((line = reader.readLine()) != null) {
                String[] clerkValues = line.split(";");
                clerk.add(new Clerk(Integer.parseInt(clerkValues[0]), clerkValues[1], clerkValues[2], Double.parseDouble(clerkValues[3]), clerkValues[4]));

            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return clerk; // Error here,Type mismatch: cannot convert from List<Clerk> to List<T>

我總是遇到錯誤。 而且我不想將超類(Employee)構建為通用的 Class 像 =>

 public abstract class Employee <T>{
    // Code here
    }

預先感謝您對我們的支持。

您可以像這樣在Employee中聲明該方法:

public abstract List<? extends Employee> read(String path);

您可以將其翻譯成英語,例如“讀取返回某個未知類型員工的列表”。 您將能夠迭代列表並以其他方式從中讀取,並將元素視為Employee 您將無法將新的Employee元素添加到列表中,或者將Employee元素作為參數傳遞給方法。 對於這個用例,這可能沒問題。

您可以在Clerk和其他具有方法簽名的子類中覆蓋它,如下所示:

public List<Clerk> read(String path)

這是因為List<Clerk>List List<? extends Clerk> List<? extends Clerk>和 Java 允許您使用覆蓋方法返回比它覆蓋的方法更具體的類型來覆蓋方法。

如果您隨后在Clerk類型的引用上調用read ,則返回類型將為List<Clerk> ,如預期的那樣。

如果Employee class 返回List<Employee>而不是List<? extends Employee> List<? extends Employee> ,因為List不變的,因此List<Clerk>不是List<Employee>的子類型。 要理解為什么會這樣,請考慮List<Employee>確實允許您向其中添加新的Employee元素。 如果列表的實際類型是List<Clerk> ,但編譯器允許將不是Clerk實例的其他類型的Employee添加到列表中,則將違反列表僅包含Clerk元素的預期,並可能導致運行時錯誤。

我同意 Gene 的評論,即在EmployeeClerk的實例上使用這些方法沒有多大意義。 也許擁有一個EmployeeReader接口和ClerkReader實現會更好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM