有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

类重载Java中的抽象方法?

我有以下接口和抽象类:

public interface DataExporter {
    MultipartFile export() throws IOException;
}


public abstract class AbstractExporter<T> implements DataExporter {
    protected abstract Iterable<T> getData();
}

我在exporter类中调用getData()方法,如下所示:

public class EmployeeExporter extends AbstractExporter<EmployeeDTO> {
    
    protected Iterable<EmployeeDTO> getData() {
        // code omitted
    }
}

然而,在另一个类中,例如managerxporter,我需要将参数传递给getData()方法:

public class ManagerExporter extends AbstractExporter<ManagerDTO> {
    
    protected Iterable<ManagerDTO> getData(UUID uuid) {
        // code omitted
    }
}

我认为在AbstractExporter中重载该方法不是一个好主意, 因为在这种情况下EmployeeExporter将需要实现它,即使它不使用它。那么,在&;没有参数

注意:我可能还需要其他需要多个参数的实现,例如protected Iterable<ManagerDTO> getData(UUID uuid, UUID departmentUuid, UUID staffUuid)。在这种情况下,我是否需要使用对象数组等,比如Object[]


共 (4) 个答案

  1. # 1 楼答案

    这取决于如何使用数据导出器。如果你想使用这个类的两个方法,那么你必须在所有的实现中添加一个方法,否则,你不需要在父类中使用这些方法中的一个

  2. # 2 楼答案

    如果参数化版本getData(...)可以安全且一致地处理信标值,那么您可以始终在抽象类中实现伸缩式无参数版本,并且只需要实现参数化版本

    abstract class AbstractExporter<T> implements DataExporter {
        protected final Iterable<T> getData() {
            return getData(new UUID( 0 , 0 ));
        }
        
        protected abstract Iterable<T> getData(UUID uuid);
    }
    
  3. # 3 楼答案

    您需要查看调用getData()的代码

    在最初的问题中,您说“我在导出器类中调用getData()方法,如下所示”。但下面展示的不是调用,而是抽象方法的具体实现

    getData()方法受到保护,因此它只被AbstractExporter或其子类调用。AbstractExporter是否至少有一个调用getData()的具体方法实现

    如果没有,那么您可以简单地从该抽象类中删除getData()。对getData()的所有调用都在子类中,它们可能知道要传递的正确参数。可以从抽象类中删除getData()方法,并在具体的实现类中声明(可能是私有的)

    public interface DataExporter {
        MultipartFile export() throws IOException;
    }
    
    public abstract class AbstractExporter<T> implements DataExporter {
        // No call to getData() occurs anywhere in this class
    }
    
    public class EmployeeExporter extends AbstractExporter<EmployeeDTO> {
    
        private Iterable<EmployeeDTO> getData() {
            // code omitted
        }
    }
    
    public class ManagerExporter extends AbstractExporter<ManagerDTO> {
    
        private Iterable<ManagerDTO> getData(UUID uuid) {
            // code omitted
        }
    }
    

    如果AbstractExporter包含对getData()的调用,那么它如何确定应该传递给该方法的参数?有股腥味。AbstractExporter的实例可以互换使用。每个子类都应该知道如何使用相同的参数集执行getData()。如果ManagerExporter需要一个UUID来执行其导出,那么您可以在构造实例时分配该值,而不是将其作为参数传递给getData()

    public interface DataExporter {
        MultipartFile export() throws IOException;
    }
    
    public abstract class AbstractExporter<T> implements DataExporter {
        protected abstract Iterable<T> getData();
    
        public MultipartFile export() throws IOException {
            // Call to getData() occurs here or somewhere else in this class
        }
    }
    
    public class EmployeeExporter extends AbstractExporter<EmployeeDTO> {
    
        protected Iterable<EmployeeDTO> getData() {
            // code omitted
        }
    }
    
    public class ManagerExporter extends AbstractExporter<ManagerDTO> {
        private uuid;
        public ManagerExporter( UUID uuid ) {
            // The uuid is determined when the object is constructed
            this.uuid = uuid;
        }
        protected Iterable<ManagerDTO> getData() {
            // Use this.uuid in my implementation
        }
    }
    
  4. # 4 楼答案

    如果需要不同的方法签名,那么不应该扩展同一个抽象类

    所以。。。不用麻烦了

    public interface DataExporter {
        MultipartFile export() throws IOException;
    }
    
    public class EmployeeExporter implements DataExporter {
        protected Iterable<EmployeeDTO> getData() {
            // code omitted
        }
    }
    public class ManagerExporter implements DataExporter {   
        protected Iterable<ManagerDTO> getData(UUID uuid) {
            // code omitted
        }
    }