(OOP5) Packages & Interfaces

(OOP5) Packages & Interfaces



Packages are containers for classes, and are used to keep the class namespace compartmentalized. Normally, when the package command isn’t used at the top of the file, classes and their .class files are stored in the default package. Hence, we haven’t had to worry about it so far.
// stores in 'mypackage/' package mypackage; // stores in 'a/b/c/' package a.b.c;
Multiple files can be saved in the same package, and there can be subdirectories to store and categorize them. java.utils.* is an example.
Q. How does Java runtime know where to look for your packages?
  1. Java uses the current directory as a starting point to look from.
  1. The directory path/paths can be specified through the CLASSPATH env variable.
  1. You can use the -classpath argument in java or javac commands to specify the same.
(From JDK 9, a package can be a part of a module, and thus be a part of the module path.)

Packages & Member Access

As seen for class member access before,
notion image
Anything declared public can be accessed from different classes/packages, subclassed or otherwise. All private elements cannot be accessed outside of their class. If an element should be visible to outside packages, only is directly subclassed, then protected is used.

Importing Packages

import pkg1[.pkg2].(classname | *); import java.lang.* // implicitly imported by compiler at all times. import java.util.* class MyDate extends Date {} // OR class MyDate extends java.util.Date {} // without import.


It helps specify the implementation of its classes, with no instance variables or method body (as a general rule). All methods/declared vars are implicitly public, static and final.
  • Before JDK 8, an interface could not define method body.
  • From JDK 8, you can add default implementations and static interface methods.
  • From JDK 9, you can also include private methods.
interface Callback { void callback(int param); } class Client implements Callback { public void callback(int p) { System.out.println("This 'p' is the same as 'param': " + p) } } public class TestRun { // can use interface to refer to implementations. Callback client = new Client(); client.callback(24); }

Partial Implementation

If a class includes an interface but does not fully implement the methods required by that interface, then that class must be declared as abstract.
abstract class Incomplete implements Callback { int a, b; void show() { System.out.println(a + " " + b); } // ... }

Variables in Interfaces

When an interface includes variables, any class implementing the interface will have them in scope as constants (final variables).
import java.util.Random; interface SharedConstants { int NO = 0; int YES = 1; int MAYBE = 2; } class Question implements SharedConstants { Random random = new Random(); int ask() { int prob = (int) (100 * random.nextDouble()); if (prob < 50) return NO; else if (prob == 50) return MAYBE; else return YES; } }

Extending Interfaces

interface A { void meth1(); } interface B extends A { void meth2(); void meth3(); } public class ExtendingInterfaces implements B { // this should now include meth1(), meth2() and meth3(). // ... }

Methods in Interfaces

interface MethodsInHere { private int getNext() { // this will have code shared commonly by inner methods. } default String getString() { // this can execute stuff, be a common method to implementations. } static double nextDouble() { // this can be accessed under the interface name. } }