views:

102

answers:

4

1) Why in the files that are in a Java package I shoud write the "package" thing in it?, its not indirectly assumed that if it's in the directory, then its in the package?.

2) I come from the C++ world. I always imported the .h of the classes wich I need from other files that use that class (I mean, I want only to "show" the header, not the implementation). But now I'm a bit confused about the imports in Java. How is this done in Java?

Thanks

+2  A: 

1) The package declaration has to match the directory hierarchy on the project.

If I use package com.stackoverflow.bakkal; in Car.java then the following hierarchy is expected.

com/
|-- stackoverflow/
|   `-- bakkal/
|       |-- Car.java

2) If you want to hide an implementation you can use interface in Java instead of a class. Then distribute the actual implementations in .class files or JARs for example.

Mmm but an interface cannot be instantiated...

The interface works like a prototype in C++ to some extent. You have the contract, then the actual implementation comes from elsewhere.

I want to instantiate a class, but without giving the implementation, only the prototype

That's not possible even C++, how can you instantiate something without having its actual implementation? In C++ you'd still need to link to the object files. In Java you use .class files.

Bakkal
1) My question is why its not assumed? :S 2) Mmm but an interface cannot be instanciated... I want to instanciate a class, but without giving the implementation, only the prototype.
makakko
@makakko: So long as the .java file is available, the implementation will always be available. Period. If you want to hide the implementation, give the user/programmer/ET only .class files (or .jar containing .class). Make sure you include documentation, though.
Brian S
Thanks Brian, I got it. :). BTW, the .class can be reversed in a "nice" way?, I mean, restore the original "name" variables/functions? Because I guess that the Java VM doesn't handle "offsets" to class members or functions...
makakko
@makakko: A class file can be decompiled. That doesn't necessarily mean that the result will be the same as the original source, because the decompiler has to guess at the original based on the bytecode. But this is similar to inspecting the machine instructions of a compiled C++ program to guess what the original C++ code was. It's a bit easier in Java, but it's not something you should waste time (and it is a waste) worrying about.
Brian S
@makakko: A Java decompiler can restore the class and function names, but not the names of local variables.
dan04
+1  A: 

Packages are not assumed because Java's philosophy is that it's better to be explicit than implicit/assumed.

It does give you the ability to access anything in your current package, but anything outside needs to be explicitly imported. (I believe Java.lang is the exception because that contains so much base functionality such as String that there wouldn't be a single package that wouldn't use it).

This is also why you tend to see:

import java.util.ArrayList;
import java.util.LinkedList;

instead of:

import java.util.*;

This can seem annoying until the one day you are trying to figure out someone elses code and it hits you how much harder this would be if things were hidden/implied.

If you use Eclipse, Netbeans or IntelliJ, you'll never even notice because of two features.

First of all, if you hit ctrl-space in the middle of typing a class name it will not only complete the class name for you, but it will also automatically add it to the imports list.

Secondly if you ever get to where imports are "Wrong" or you don't use ctrl-space expansion, you can just type ctrl-shift-o (eclipse) to have it "Fix imports". This will automatically import things that need importing and remove imports you no longer need. Depending on your settings it will also expand or collapse *'s.

Once you get a system down you never even consider imports.

Bill K
A: 

The package specifies a path to the class. It must match the directory on disk or in the jar (zip). Location is relative to a location on the classpath. Protected access is restricted to classes in the same package.

Some of the things you might do in a .h file are done in the class definition. Constants belong to a class and may be publicly visible. In a .h the constants must be publicly visible.

Import is the equivalent to including a .h, but helps deal with issues of conflicting definitions of the same name. You can include only one item or all visible items from a class. It is also possible to skip the import and use the package name to prefix the class you are accessing something from.

The implementation is not really visible via an import (At least not beyond that provided by the compiled class. What is visible is the visible interface public methods and data. For imports from the same package methods and data which have no access specified (public/protected/private) are also visible. Protected methods and variables are visible to subclasses of the class. .h files may be usable without providing either source or object files. Imports require the specified classes be provided. (A class may consist of only constants, although that would be be poor design.)

BillThor
`protected` access means subclasses, not same package. Package access (also "default access") is specified by omitting any access keyword (public/protected/private).
Brian S
Answer has been corrected.
BillThor
+1  A: 
  1. No, that is not assumed. After all, what's my package called? com.mypackage.stuff? src.com.mypackage.stuff? myproject.com.mypackage.stuff? C.Users.makakko.workspace.myproject.src.com.mypackage.stuff?

    If you only base the package off of the folders, is it relative to the drive root? What if the project is developed on a different drive letter on a different machine? Is it relative to the location of javac.exe? Again, what about different install directories? What about the working directory when running javac? But you can specify a location for javac to find your sourcefiles in. What if you want to do a simple test program, or teach someone Java who has never programmed before; do you have to use/explain the whole concept of package structure?

    If you omit the package specifier, then you're still in a package. It's just the "default package", which has no name.

  2. Header files are more of an artifact from the way C needs to be compiled than a way to achieve information hiding. In C, a method must be defined before it can be referenced. If you want to have several methods which refer to one another, you have to define all of them before using any of them, hence the header. The headers in C++ carry over from that, but changes in C++ alter the necessity of headers.

    In Java, the compiler will look at all of your method and class signatures before doing anything which required the method/class. The function served by headers is put into the compiler itself. You can't depend on the header for your information hiding, because

    1. Code can be placed within a header file

    2. Unless you use real information hiding such as a separate library, a programmer can go find the c/cpp file that matches the header without issue

    Similarly in Java, you can only get real information hiding by removing the source. Once you've made the source inaccessible, you expose the API with public/protected classes, enums, and interfaces. For bonus points, write explanatory JavaDoc comments for everything, and run javadoc.exe over your source to produce separate documentation for anyone who will use your package(s).

Brian S