Win a copy of Classic Computer Science Problems in Swift this week in the iOS forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Why is Path an interface if it is treated as object?  RSS feed

 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Studying the java.nio.file package, I came across the Paths class that has 2 static methods that both return a Path object. Looking at the API for Path, I read that this is an interface with the description : An object that may be used to locate a file in a file system. It puzzles me that Path - an interface (not meant to be instantiated and used as an object) - is used as object. It seems to me that Path could be - or should be - a regular class, while it is not using it's interface functionality of offering generic functionalities for inheritance and polymorphism. What am I missing here? I would appreciate your guidance on this.
 
author
Sheriff
Posts: 23484
138
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

It is a feature of Java. All instances of classes may be referred to by its interfaces. Of course, doing so means that the object is limited by its interface's API (without casting). The actual class type that is instantiated (and returned) by the Paths class' static methods are considered an implementation detail, and are not specified by the Javadoc.

Henry
 
Marshal
Posts: 58830
179
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Richard Legué wrote:. . . an interface (not meant to be instantiated and used as an object) . . .

That is a common misinterpretation of the intention of an interface. An interface is intended to have classes which implement it and those classes are intended to be instantiated and used as objects. That class is also a Path, so you declare the return type as Path.Search for “program to the interface, not the implementation” for more information.
 
Saloon Keeper
Posts: 8752
162
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Richard Legué wrote:an interface (not meant to be instantiated and used as an object)


What makes you say that interfaces are not meant to be used as objects? The entire point of an object oriented language is that you treat things as objects. An interface is just a description on what an object looks like. The fact that you can't instantiate them directly doesn't mean that you can't create instances of a class that implements the interface, and refer to that interface using a reference of the interface type.

It seems to me that Path could be - or should be - a regular class, while it is not using it's interface functionality of offering generic functionalities for inheritance and polymorphism.


But it does. You can have different Path implementations, depending on what file system the Path is associated with. For instance, you could make an implementation for Unix systems that doesn't allow backslashes as separators, or something completely different (for instance, there are file systems that don't have a hierarchical folder structure at all).

The methods of the Paths class just return instances of Path that are associated with the default FileSystem. If you want to get a Path for a different file system (maybe you have mounted some kind of storage device with a custom file system), you need to call getPath() on the appropriate FileSystem instance, which is free to returns its own implementation of Path.
 
Richard Legué
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I figured as much, but I could'nt find in the API what the (to me invisible) class was that implemented the Path interface to produce the Path objects. I read some related topics on the forum as well and now it's clear to me. Thanks for your help guys.
 
Campbell Ritchie
Marshal
Posts: 58830
179
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's a pleasure

What did you find as the class name?
 
Bartender
Posts: 19365
86
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Unlike OLE/COM, in Java you're always working with Objects. The Interface is just a guarantee that the object will implement certain methods. Thus the different classes that implement that Interface are interchangeable for the purposes of the contract defined for that Interface.

Not actually knowing what class implements an Interface is actually pretty common. When you open a JDBC Connection, you're given something that implements the JDBC interface, but you don't know or care whether that something is an Oracle driver, an PostgreSQL driver, a MySQL driver, or what. Only that it can be relied on to execute SQL commands and return SQL query results.

When you write a J2EE/JEE web application, your servlet gets passed an HttpServletRequest and HttpServletResponse. These are also interfaces, and the actual classes and their internals are specific to whichever webapp server you're using, The Tomcat server's classes are Tomcat-specific, the Firefly server's classes are Firefly-specific, so on for WebSphere, etc. These classes may hold all sorts of information that helps the server get its job done, but the only information that you could know about when using the interfaces is what's defined for the interfaces. That means that a servlet written for Tomcat is going to be able to run more or less unchanged in WebLogic.

 
Campbell Ritchie
Marshal
Posts: 58830
179
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Richard Legué wrote:. . . the (to me invisible) class was that implemented the Path interface . . . .

It is possible that Paths has a private nested class which implements Path; that will never be visible in the public API. You can find out quite a bit simply from the code I showed you to find the class name. I expect it will differ with the implementation. The class might also be in a separate package whose documentation is omitted from the published API. That allows the implementer to change the actual class without having to give notice.
 
Sheriff
Posts: 21308
87
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:For instance, you could make an implementation for Unix systems that doesn't allow backslashes as separators, or something completely different (for instance, there are file systems that don't have a hierarchical folder structure at all).


By default there are (at least) two Path implementations: one for the local file system, and one for files inside ZIP files. But because almost all of NIO.2 is based on interfaces (like JDBC), it's actually not that hard to write custom classes. For instance (shameless plug):
  • memory-fs that stores "files" in memory. Can be quite useful to prevent storing content in a temporary file just because a method expects a Path.
  • ftp-fs to access FTP(S) file systems as if they were local.
  • sftp-fs: likewise but for SFTP (SSH).
  •  
    Rob Spoor
    Sheriff
    Posts: 21308
    87
    Chrome Eclipse IDE Java Windows
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:It is possible that Paths has a private nested class which implements Path; that will never be visible in the public API. You can find out quite a bit simply from the code I showed you to find the class name. I expect it will differ with the implementation. The class might also be in a separate package whose documentation is omitted from the published API. That allows the implementer to change the actual class without having to give notice.


    Actually, Path is based on the concept of FileSystemProvider and FileSystem. A FileSystemProvider can be "injected" through the service loader mechanism. It can then return one or more FileSystem and/or Path instances. The get method from Paths that takes Strings will always use the default FileSystem, which uses the local file system. The overloaded method that takes a URI will lookup the appropriate FileSystemProvider based on the scheme, then let that return the actual Path instance. For example, if you use memory-fs, a URI that starts with mem: will return an in-memory Path.

    This is all documented in Paths.
     
    Richard Legué
    Greenhorn
    Posts: 9
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks for all your additional explanation. Very helpful and also showing that there's lots to be learned yet. By the way, the 'hidden' class name I found when running the piece of code Campbell Ritchie posted is sun.nio.fs.WindowsPath. Thanks again for your help.
     
    Campbell Ritchie
    Marshal
    Posts: 58830
    179
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    That may be a package which isn't described in the public API documentation; I haven't looked. Also, when I tried it I got a class called UnixPath from the same package. So the return type varies with the OS used. That means the return type cannot be a class name, but has to be an interface which both those classes implement.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!