11

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 a file called "HelloWorld.java". The Java compiler complains about this code. It writes that the class IServiceAnnouncer is public and it should be declared in a file called "IServiceAnnouncer.java".

I have several questions about this:

  1. Why would the compiler say 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 called "IServiceAnnouncer.java" (as the compiler wants), how then can I use it from the "HelloWorld.java"?

  3. What does public interface mean? What is the difference between a public interface and non-public one?

Roman
  • 124,451
  • 167
  • 349
  • 456
  • Not related to your question, but per standard Java coding standards you should put "I" in front of interfaces. – Steve Kuo Mar 05 '10 at 22:28
  • 1
    @Steve Kuo: Good advice, but you may have out a word. :-) http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html – trashgod Mar 06 '10 at 01:54

6 Answers6

17

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
  • 268,207
  • 37
  • 334
  • 440
  • 3
    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 Mar 05 '10 at 21:26
  • can you provide an example and how to compile it. It would really help. I am stuck with same problem. https://stackoverflow.com/questions/64442243/how-can-i-put-interface-in-a-seperate-file – Aman Oct 20 '20 at 09:30
8

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
  • 66,182
  • 23
  • 141
  • 173
7

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

Chris K
  • 11,996
  • 7
  • 37
  • 65
2

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
  • 265,237
  • 58
  • 395
  • 493
0
  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
  • 10,550
  • 1
  • 41
  • 68
-1

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
  • 1,325
  • 1
  • 11
  • 23
  • 3) not true: not all top level (non-nested) interfaces are public. They are only public when defined public. Try it! – Pindatjuh Mar 05 '10 at 21:28
  • Yes, I should've mentioned package visibility! – pkananen Mar 05 '10 at 21:33
  • 1
    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 Mar 06 '10 at 10:51