views:

108

answers:

6

I have the following code:

import com.apple.dnssd.*;

public interface IServiceAnnouncer {
    public void registerService();
    public void unregisterService();
    public boolean isRegistered();
}

class HelloWorld {
        public static void main(String[] args) {
                System.out.println("Hello, World!");
        }
}

This code is saved in the file colled "HelloWorld.java". Java-compiler complains about this code. I writes that class IServiceAnnouncer is public and it should be declared in a file colled IServiceAnnouncer.java.

I have several questions about this situation:

  1. Why compiller says that IServiceAnnouncer is a class? It s an interface. Or interface is a partial case of a class?

  2. If I put the interface IServiceAnnouncer in a separate file colled IServiceAnnouncer.java (as compiler wants), how then can I use it from the HelloWorld.java?

  3. What does it mean "public interface"? What is a difference between the public interface and not public one?

+2  A: 

You don't have a choice. All public classes/interfaces must be in files named ClassOrInterfaceName.java.

Chris Kaminski
+2  A: 

You should put it in a separate file. That way it's easier to swap in a different implementation, or make the interfaces (the API of your system) available for others to code against without knowing the details of your implementation, or having to drag in related dependencies.

e.g. implementations of common Java APIs - e.g. servlets - will have an implementation coded against the package of interfaces provided by Sun (in this case javax.servlet)

How can you use it from your implementation ? By importing it. This is unnecessary if it's in the same package and you're compiling all your interfaces/implementations at once.

Note that an interface compiles down to a .class file in the same way as an implementation (what you define using class).

Brian Agnew
Interfaces don't have to be public. They can be useful within a package, or even privately within a class (I've done this for the State pattern).
erickson
Of course! Doh. Corrected. Thx
Brian Agnew
A: 
  1. The problem with more than one class-definition in one file is the following error, which may occur when using Versioning and multiple developers are working on the same project:

    duplicate class: X
    class X {
    

    Thus, it's preferred to place public (and also non-public, btw) classes in separate files. This will reduce the chance of having these errors.

  2. If it's in the same folder, just use the IServiceAnnouncer, if it's in a different folder, import it.

  3. public is visible from all packages. No public means a kind of protected (while the keyword protected is prohibited, weird huh!): it's only visible from within the same package. If you're not sure what a package is, check out the Java Tutorial. http://java.sun.com/docs/books/tutorial/java/package/packages.html

Pindatjuh
A: 

1) The compiler is just complaining that you have 2 public top level types defined. You can't do that in Java. You can nest the interface in your class if you'd like, or make it non-public (default visibility), but that's not too common in Java, and probably not too useful here.

2) You'll either need to implement the interface, or have access to an object that does it implement it.

3) Interfaces can either be public, or default (package) visibility. Methods in an interface don't need the public modifier as they're public by default.

pkananen
3) not true: not all top level (non-nested) interfaces are public. They are only public when defined public. Try it!
Pindatjuh
Yes, I should've mentioned package visibility!
pkananen
You can define as many top-level classes as you like in Java, it's just that the public ones must match the file's name, which means that you can only declare one top-level public type in one file.
Sean Owen
A: 

The compiler is using the term "class" a little loosely. A more general term might be "type". I'm guessing the compiler uses the term "class" because it produces ".class" files of the same format from every type declaration (class, interface, and enum).

An interface doesn't have to be public. If it is declared without an access modifier, it can be accessed only within its "package."

A Java type can (should) be declared in a package. Packages are a collection of Java types that should be built and deployed together. By default, all types in a package are implicitly imported, so if your interface is in the same package, it will be available to the HelloWorld class.

When you don't declare a package, a type is in the default package. So even if you just put the IServiceAnnouncer interface in a separate file, it will be available to HelloWorld. Just compile both files at the same time.

erickson
A: 

These answers are dancing around the right one.

  1. Yes, you can declare multiple classes in one file in Java.
  2. You cannot declare more than one public class, because:
  3. A public class's name must match its containing file name; this is your compile error

It is very strange in Java to declare multiple classes in one file, even though you can. Don't do it.

You put IServiceAnnouncer in a separate file, and import the class name in HelloWorld.java. You merely compile them at the same time, passing both file names to javac. That all works.

A public interface, like anything else that's public in Java, is a type that's visible and usable from any other class. Without "public", its visibility is called package-private, which means only things in the same package can use it.

Sean Owen