Chapter four Interfaces and Packages Contents; abstract classes and methods, interfaces, Final methods and classes, inner classes 1 Organizing Classes into a Package • A package is, essentially, a grouping of classes. • A package provides a mechanism by which related pieces of a program can be organized as a unit. • Classes defined within a package can be made private to that package and not accessible by code outside the package. • Thus, the package provides a means by which classes can be encapsulated • All classes in Java belong to some package. When no package statement is specified, the default (global) package is used. 2 To create a package, put a package command at the top of a Java source file This is the general form of the package statement: package pkg; Here, pkg is the name of the package.(Lowercase is often used for package names.) For example, the following statement creates a package called mypack: package mypack; Example // A short package demonstration. package bookpack; This file is part of the bookpack package class Book { Thus, Book is part of bookpack private String title; private String author; private int pubDate; Book(String t, String a, int d) { title = t; author = a; pubDate = d; 3 } void show() { System.out.println(title); System.out.println(author); System.out.println(pubDate); System.out.println();}} BookDemo is also part of bookpack. class BookDemo { public static void main(String args[]) { Book books[] = new Book[5]; books[0] = new Book("Java: A Beginner's Guide", "Schildt", 2014); books[1] = new Book("Java: The Complete Reference", "Schildt", 2014); books[2] = new Book("The Art of Java", "Schildt and Holmes", 2003); books[3] = new Book("Red Storm Rising", "Clancy", 1986); books[4] = new Book("On the Road", "Kerouac", 1955); for(int i=0; i < books.length; i++) books[i].show(); } } 4 Abstract Classes An abstract class is one that cannot be instantiated. If a class is abstract and cannot be instantiated, the class does not have much use unless it is subclassed. Use the abstract keyword to declare a class abstract. A class is abstract if the class contains an abstract method or does not provide an implementation of an inherited abstract method. We say a method is implemented if it has a method body. Abstract methods consist of a method signature, but no method body. The following points about abstract classes are worth noting: • An abstract method cannot be contained in a nonabstract class. If a subclass of an abstract superclass does not implement all the abstract methods, the subclass must be defined as abstract. 5 In other words, in a nonabstract subclass extended from an abstract class, all the abstract methods must be implemented. Also note that abstract methods are nonstatic and noneprivate. • An abstract class cannot be instantiated using the new operator, but you can still define its constructors, which are invoked in the constructors of its subclasses. • A class that contains abstract methods must be abstract. However, it is possible to define an abstract class that doesn’t contain any abstract methods. • A subclass can override a method from its superclass to define it as abstract. In this case, the subclass must be defined as abstract. • A subclass can be abstract even if its superclass is concrete. • You cannot create an instance from an abstract class using the new operator, but an abstract class can be used as a data type. 6 Example public abstract class Employee The keyword abstract { here denotes an abstract private String name; class. private String address; private int number; public Employee(String name, String address, int number) { System.out.println(“Constructing an Employee”); this.name = name; Abstract method has no this.address = address; method body, just a this.number = number; semicolon. } public abstract double computePay(); The keyword abstract here denotes an public void mailCheck() abstract method. { System.out.println(“Mailing a check to “ + this.name + “ “ + this.address); } 7 public String toString() { return name + “ “ + address + “ “ + number; } public String getName() { return name; } public String getAddress() { return address; } public void setAddress(String newAddress) { address = newAddress; } public int getNumber() { return number; } } 8 public class Contractor extends Employee { private double dailyRate; private int daysWorked; public Contractor(String name, String address, int number, double dailyRate) { super(name, address, number); setDailyRate(dailyRate); } public double computePay() { System.out.println(“Computing contractor pay for “ + getName()); return dailyRate * daysWorked; } public void setDailyRate(double newRate) { if(newRate >= 0.0 && newRate <= 2000.00) { dailyRate = newRate; } } 9 public double getDailyRate() { return dailyRate; } public void setDaysWorked(int daysWorked) { if(daysWorked >= 0) { this.daysWorked = daysWorked; } } } public class SmartBoss { public void payEmployee(Employee e) { double pay = 0.0; 10 if(e instanceof Salary) { pay = ((Salary) e).computePay(); } else if(e instanceof Hourly) { pay = ((Hourly) e).computePay(); } System.out.println(“Pay = “ + pay); e.mailCheck(); } } public class PayEmployees { public static void main(String [] args) { Salary s = new Salary(“Tsehay”, “CS3”,3, 2600.00); Hourly h = new Hourly(“Nuri A”, “MU”, 2,2.50); h.setHoursWorked(40); Contractor c = new Contractor(“Belay M”, “KA”,44, 1000.00); c.setDaysWorked(5); SmartBoss boss = new SmartBoss(); boss.payEmployee(s); boss.payEmployee(h); boss.payEmployee(c); } } 11 Interfaces An interface is a class-like construct that contains constants and abstract methods. Suppose that a person is calling her pets to dinner by whistling. Each animal responded in its own way: Some ran, some flew, and some swam. Let’s specify some behaviors for these pets. For example, suppose our pets are able to • Be named • Eat • Respond to a command We could specify the following method headings for these behaviors: public void setName(String petName) public boolean eat(String food) public String respond(String command) These method headings can form a class interface Now imagine that each of the three classes Dog, Bird, and Fish implements all of these methods. The objects of these classes then have the same behaviors—that is, each object can be named, can eat, and can respond. 12 The nature of these behaviors, however, can be different among the objects. Although dogs, birds, and fish respond to a command, for example, the way they respond differs. Java interface begins like a class definition, except that you use the reserved word interface instead of class. That is, an interface begins with public interface Interface_Name rather than public class Class_Name. By convention, • An interface name begins with an uppercase letter, just as class names do. • You store an interface in its own file, using a name that begins with the name of the interface, followed by .java. • An interface does not declare any constructors for a class. • Methods within an interface must be public, so you can omit public from their headings. • An interface can also define any number of public named constants. It contains no instance variables, however, nor any complete method definitions—that is, methods cannot have bodies 13 As with an abstract class, you cannot create an instance from an interface using the new operator. Here is an example of an interface: public interface Edible { /** Describe how to eat */ public abstract String howToEat(); } You can use the Edible interface to specify whether an object is edible. This is accomplished by letting the class for the object implement this interface using the implements keyword. To implement more than one interface, just list all the interface names, separated by commas, as in implements MyInterface, YourInterface Example public interface Measurable { /** Returns the perimeter. */ public double getPerimeter(); /** Returns the area. */ public double getArea(); } 14 /** A class of rectangles. */ public class Rectangle implements Measurable { private double myWidth; private double myHeight; public Rectangle(double width, double height) { myWidth = width; myHeight = height; } public double getPerimeter() { return 2 * (myWidth + myHeight); } public double getArea() { return myWidth * myHeight; } } 15 /** A class of circles. */ public class Circle implements Measurable { private double myRadius; public Circle(double radius) { myRadius = radius; } public double getPerimeter() { return 2 * Math.PI * myRadius; } This method is not public double getCircumference() declared in the interface. { return getPerimeter(); Calls another method instead } of repeating its body. public double getArea() { return Math.PI * myRadius * myRadius; } 16 } An interface is a reference type. Thus, you can write a method that has a parameter of an interface type, such as a parameter of type Measurable. For example, suppose that your program defines the following method: public static void display(Measurable figure) { double perimeter = figure.getPerimeter(); double area = figure.getArea(); System.out.println("Perimeter = " + perimeter + "; area = " + area); } Your program can invoke this method, passing it an object of any class that implements the interface Measurable. For instance, your program might contain the following statements: Measurable box = new Rectangle(5.0, 5.0); Measurable disc = new Circle(5.0); 17 Thus, the invocation display(box); displays Perimeter = 20.0; area = 25.0 while the invocation display(disc); displays Perimeter = 31.4; area = 78.5 Example 2 (let us implement the Edible interface) abstract class Animal { /** Return animal sound */ public abstract String sound(); } class Chicken extends Animal implements Edible { @Override public String howToEat() { return "Chicken: Fry it"; } 18 @Override public String sound() { return "Chicken: cock-a-doodle-doo"; } } class Tiger extends Animal { @Override public String sound() { return "Tiger: RROOAARR"; } } abstract class Fruit implements Edible { // Data fields, constructors, and methods omitted here } class Apple extends Fruit { @Override public String howToEat() { return "Apple: Make apple cider"; } } 19 class Orange extends Fruit { @Override public String howToEat() { return "Orange: Make orange juice"; } } public class TestEdible { public static void main(String[] args) { Object[] objects = {new Tiger(), new Chicken(), new Apple()}; for (int i = 0; i < objects.length; i++) { if (objects[i] instanceof Edible) System.out.println(((Edible)objects[i]).howToEat()); if (objects[i] instanceof Animal) { System.out.println(((Animal)objects[i]).sound()); } } } } 20 Output Tiger: RROOAARR Chicken: Fry it Chicken: cock-a-doodle-doo Apple: Make apple cider An interface is different from a class in several ways, including: • You cannot instantiate an interface. • An interface does not contain any constructors. • An interface cannot contain instance fields. The only fields that can appear in an interface must be declared both static and final. • An interface is not extended by a class; it is implemented by a class. • An interface can extend multiple interfaces. 21 Inner Classes An inner class, or nested class, is a class defined within the scope of another class. Inner classes are useful for defining handler classes. Example // OuterClass.java: inner class demo public class OuterClass { private int data; /** A method in the outer class */ public void m() { // Do something } // An inner class class InnerClass { /** A method in the inner class */ public void mi() { // Directly reference data and method // defined in its outer class data++; m(); } 22 } Normally, you define a class as an inner class if it is used only by its outer class. An inner class has the following features: • An inner class is compiled into a class named OuterClassName$InnerClassName.class. • An inner class can reference the data and the methods defined in the outer class in which it nests, so you need not pass the reference of an object of the outer class to the constructor of the inner class. For this reason, inner classes can make programs simple and concise. • An inner class can be defined with a visibility modifier subject to the same visibility rules applied to a member of the class. • An inner class can be defined as static. • A static inner class can be accessed using the outer class name. • A static inner class cannot access nonstatic members of the outer class. 23 • Objects of an inner class are often created in the outer class. But you can also create an object of an inner class from another class. If the inner class is nonstatic, you must first create an instance of the outer class, then use the following syntax to create an object for the inner class: OuterClass.InnerClass innerObject = outerObject.new InnerClass(); • If the inner class is static, use the following syntax to create an object for it: OuterClass.InnerClass innerObject = new OuterClass.InnerClass(); Example // Use an inner class. class Outer { int nums[]; Outer(int n[]) { nums = n; } 24 void analyze() { Inner inOb = new Inner(); System.out.println("Minimum: " + System.out.println("Maximum: " + System.out.println("Average: " + } // This is an inner class. class Inner { int min() { int m = nums[0]; for(int i=1; i < nums.length; if(nums[i] < m) m = nums[i]; return m; } int max() { int m = nums[0]; for(int i=1; i < nums.length; if(nums[i] > m) m = nums[i]; return m; } inOb.min()); inOb.max()); inOb.avg()); i++) i++) 25 int avg() { int a = 0; for(int i=0; i < nums.length; i++) a += nums[i]; return a / nums.length; } } } class NestedClassDemo { public static void main(String args[]) { int x[] = { 3, 2, 1, 5, 6, 9, 7, 8 }; Outer outOb = new Outer(x); outOb.analyze(); } } Output Minimum: 1 Maximum: 9 Average: 5 26 it is possible to nest a class within a block scope. Doing so simply creates a localized class that is not known outside its block. Example 2 class LocalClassDemo { public static void main(String args[]) { // An inner class. class ShowNEven { int numevens; ShowNEven(int n) { numevens = n; } void show() { int cnt = 2; for(int i =1;i<= numevens; i++) { System.out.print(cnt+" "); cnt+=2; if(i==numevens) System.out.println(); } } } 27 for(int b=1; b <= 10; b++){ ShowNEven byteval = new ShowNEven(b); System.out.print(b +(b==1?" even:":" evens:")); byteval.show(); } } } run: 1 even:2 2 evens:2 4 3 evens:2 4 6 4 evens:2 4 6 8 5 evens:2 4 6 8 10 6 evens:2 4 6 8 10 12 7 evens:2 4 6 8 10 12 14 8 evens:2 4 6 8 10 12 14 16 9 evens:2 4 6 8 10 12 14 16 18 10 evens:2 4 6 8 10 12 14 16 18 20 28 Anonymous Inner Class Handlers An anonymous inner class is an inner class without a name. It combines defining an inner class and creating an instance of the class into one step. 29