3

I am having a debate with another developer who dislikes my idea of sub-classing java.io.File for our custom needs (such as, for example, having an AWSFile, or GoogleCloudStorageFile, (for the sake of argument), where we would need to override some of the methods like listFiles(), getAbsoluteFile, etc.). When is it okay to sub-class java.io.File?

Why is there, for example, no generic interface for this, which java.io.File could be implementing, so that it would be more generic? Was this done so on purpose?

I would like to understand whether, or not my approach is indeed good, or bad, as I've seen it in other API-s before (if I recall correctly, I'd seen the same approach in TrueZip a while ago).

The purpose of this question is not to start a flame war, or anything, but to get an examples of how to implement different types of File entities (AWSFile, JDBCFile, etc.) and potentially get a meaningful list of pros and cons.

carlspring
  • 31,231
  • 29
  • 115
  • 197
  • 3
    The first line of the class's javadoc states: ``An abstract representation of file and directory pathnames.`` - that sounds like the ideal class to subclass for your needs. My main concern is that there's a load of methods that probably won't be applicable for something like a cloud file and none of the methods should be inherited. The cleaner approach would be to implement a ``File`` interface, which does not exist in java. So... keep debating :D – f1sh Dec 12 '16 at 10:40
  • 1
    I would say your approach is good.. – Jobin Dec 12 '16 at 10:40
  • I see no need to subclass. You can implement those methods if you wish without subclassing. Inheritance means IS-A; that is not the case here. – duffymo Dec 12 '16 at 10:42
  • What is the arguments agains this approach? For me it sounds good. – Sergii Bishyr Dec 12 '16 at 10:42
  • 1
    @duffymo Isn't `AWSFile` or `GoogleCloudStorageFile` a `File`? – Sergii Bishyr Dec 12 '16 at 10:43
  • What would be the point of subclassing `File` to represent a non-local file? It can't be used with any Java `File` API like `FileReader` or `FileOutputStream`. If you want to support non-local "files" and use them like files, you should instead implement your own [`FileSystemProvider`](https://docs.oracle.com/javase/8/docs/api/java/nio/file/spi/FileSystemProvider.html) (Java 7+). – Andreas Dec 12 '16 at 10:43
  • IS-A holds only if you can satisfy the Liskov Substitution principle: Can you use your subclass in every situation where a File is correct? That means every method in the API, not one or two that you want to cherry pick. – duffymo Dec 12 '16 at 10:44
  • 4
    Why not base your API on the `java.nio.file` API, instead of the old `java.io.File` etc.? See, for example, class [`java.nio.file.FileSystems`](http://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystems.html) to learn what you need to do to provide your own `FileSystem` implementation. – Jesper Dec 12 '16 at 10:44
  • You should only subclass if any class which currently takes a File as argument, would work with an AWSFile. Would they? What would mkdir() do? Btw: I think you want to implement InputStream and OutputStream instead. – MTilsted Dec 12 '16 at 10:54
  • This is a interesting question, but it's too open for arguments and discussion, so it must be closed according to the rules. Here's my two cents: I join @duffymo's comment. – MC Emperor Dec 12 '16 at 10:54
  • I think that sub-classing is very bad idea in this case, and there are many reasons why it is bad: 1. If `Java SDK` developers supposed that somebody need to totally override or extend some entities then they make Interfaces or Abstract classes, like they do with `InputStream` and `OutputStream` for example. 2. You can't override some final or hidden members like `java.io.File.fs` which is used in other `Java SDK` components and can cause them to be confused; 3. You can have a lot of problems in case of migration from one Java version to another. – Sergey Bespalov Dec 12 '16 at 10:57

2 Answers2

1

My personal preference would be that you make an interface RemoteFile and you implement there the methods you need for the remote files.

In it I would suggest you put all the method types you will need for remote getting and setting file.

public interface RemoteFile {
    public File getLocalFile();
    public String getRemotePath();
    public boolean isDirectory();
    public List<RemoteFile> listFiles();
    ... etc...
}
Tschallacka
  • 27,901
  • 14
  • 88
  • 133
  • Why would you this? What are the pros/cons? Why should this be considered a better approach? The OP seems to be searching for an argumented ansawer. – tftd Dec 12 '16 at 16:44
-1

Subclasses will be tightly coupled to superclasses, your code would be weak. You must try delegation before inheritance if possible.

public class YourFileWrapper {

private File yourFile;


public File getYourFile() {
    return yourFile;
} 
//rest of your code
karthik
  • 17
  • 2
  • 1
    I don't understand what's "weak" about inheritance. Therefore, I don't see why one should prefer delegation over inheritance. – f1sh Dec 12 '16 at 12:15
  • As i already explained, "Subclasses will be tightly coupled to superclasses" – karthik Dec 13 '16 at 09:23
  • Yes, that's what inheritance means. What's the bad thing about that? And if it's bad, why is there inheritance everywhere in every project in every oop language language? – f1sh Dec 13 '16 at 09:27
  • https://www.reddit.com/r/learnprogramming/comments/2or9oz/what_are_the_benefits_and_drawbacks_of_a_tightly/ – karthik Dec 13 '16 at 10:16
  • That is in no way a reason to promote delegation instead of inheritance. But if you want to avoid inheritance in your projects, do so. As long as nobody else ever has to work on them. – f1sh Dec 13 '16 at 12:00