I'm trying to wrapp two interfaces in one to not have to rewrite each method using each interface. I searched a lot but I don't know how can I do this:
class ApplyFilter
{
public static File[] filter (File directory, FileFilterORFilenameFilter filterWrapper)
{
return directory.listenFiles(filterWrapper);
}
}
I tried it creating a class that implements both interfaces but then I need to cast the variable. I also tried using java generics using a class like this:
public class CustomFilter<T>
{
/* Where we store our filter */
private T filter = null;
/* The method to return it */
public T getFilter ()
{
return filter;
}
/* The constructor to define the filter */
public CustomFilter (T filt)
{
if ( !(filt instanceof FileFilter) || !(filt instanceof FilenameFilter) ) throw new IllegalArgumentException("The argument must be an instance of FilenameFilter or a FileFilter.");
this.filter = filt;
}
}
Then I used it like this and it worked:
class test
{
public static void main (String[] args)
{
CustomFilter<FileFilter> onlyShowFolders = new CustomFolder<FileFilter>(new FileFilter ()
{
@Override
public boolean accept (File file)
{
return file.isDirectory();
}
});
File root = new File("/");
for (File folder : root.listFiles(onlyShowFolders.getFilter()))
{
System.out.print(folder.toPath());
}
}
}
But when I use it in the ApplyFilter class it doesn't work.
class ApplyFilter
{
/* DOESN'T WORK :( */
public static File[] filter (File directory, CustomFilter filterWrapper)
{
return directory.listenFiles(filterWrapper.getFilter());
}
}
Thanks in advance.
You can do like what the java library itself does with File.listFiles
ie two functions with same name and different argument type.
class ApplyFilter {
public static File[] filter(File directory, FileFilter filter) {
return directory.listFiles(filter);
}
public static File[] filter(File directory, FilenameFilter filter) {
return directory.listFiles(filter);
}
}
Example holder class, see comments
public class FilterHolder {
private FileFilter fileFilter;
private FilenameFilter filenameFilter;
public FilterHolder(FileFilter fileFilter) {
this.fileFilter = fileFilter;
}
public FilterHolder(FilenameFilter filenameFilter) {
this.filenameFilter = filenameFilter;
}
public FileFilter getFileFilter() {
return fileFilter;
}
public FilenameFilter getFilenameFilter() {
return filenameFilter;
}
}
It does not work because you omit the most important part for the compiler so that it compile:
public static File[] filter (File directory, CustomFilter filterWrapper)
{
return directory.listenFiles(filterWrapper.getFilter());
}
The actual type representation is:
public static File[] filter (File directory, CustomFilter<Object> filterWrapper)
{
return directory.listenFiles(filterWrapper.getFilter());
}
And then, it looks for a method listenFiles
taking an Object
as single parameter.
Beside, FilenameFilter
and FileFilter
does not have a common ancestor, and you can't restrict the type of T, like this:
public class CustomFilter<T extends FileFilter>
{
/* Where we store our filter */
private T filter = null;
/* The method to return it */
public T getFilter () {
return filter;
}
/* The constructor to define the filter */
public CustomFilter (T filt) {
this.filter = Objects.requireNonNull(filt, "filt");
}
}
If you are sure you always use the FileFilter
, you should probably don't use your CustomFilter
and stick with FileFilter
unless you know you will add more functionalities. But in that case, have CustomFilter
implements FileFilter
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.