Programming with Java: Keeping Things Simple in Your Android App

By Barry A. Burd

The key to succeeding with Java programming is to keep it simple. Most programs operate entirely in the virtual realm. They have no bricks, nails, or girders. You can type a fairly complicated program in minutes. Even with no muscle and no heavy equipment, you can create a structure whose complexity rivals that of many complicated physical structures. You, the developer, have the power to build intricate, virtual bridges.

One goal of programming is to manage complexity. A good app isn’t simply useful or visually appealing — a good app’s code is nicely organized, easy to understand, and easy to modify.

Certain programming languages, like C++, support multiple inheritance, in which a class can have more than one parent class. For example, in C++ you can create a Book class, a TeachingMaterial class, and a Textbook class. You can make Textbook extend both Book and TeachingMaterial. This feature makes class hierarchies quite flexible, but it also makes those same hierarchies extremely complicated. You need tricky rules to decide how to inherit the move methods of both the computer’s Mouse class and the rodent’s Mouse class.

To avoid all this complexity, Java doesn’t support multiple inheritance. In Java, each class has one (and only one) superclass. A class can have any number of subclasses. You can (and will) create many subclasses of Android’s AppCompatActivity class. And other developers create their own subclasses of Android’s AppCompatActivity class. But classes don’t have multiple personalities. A Java class can have only one parent. The Executive class cannot extend both the FullTimeEmployee class and the PartTimeEmployee class.

The relationship between a class and its subclass is one of inheritance. In many real-life families, a child inherits assets from a parent. That’s the way it works.

But consider the relationship between an editor and an author. The editor says, “By signing this contract, you agree to submit a completed manuscript by the fifteenth of August.” Despite any excuses that the author gives before the deadline date, the relationship between the editor and the author is one of obligation. The author agrees to take on certain responsibilities; and, in order to continue being an author, the author must fulfill those responsibilities. (By the way, there’s no subtext in this paragraph — none at all.)

Now consider Barry Burd. Who? Barry Burd — that guy who writes Java Programming for Android Developers For Dummies, 2nd Edition, and certain other For Dummies books (all from Wiley Publishing). He’s a college professor, and he’s also an author. You want to mirror this situation in a Java program, but Java doesn’t support multiple inheritance. You can’t make Barry extend both a Professor class and an Author class at the same time.

Fortunately for Barry, Java has interfaces. A class can extend only one parent class, but a class can implement many interfaces. A parent class is a bunch of stuff that a class inherits. On the other hand, as with the relationship between an editor and an author, an interface is a bunch of stuff that a class is obliged to provide.

Here’s another example. Though a company might hire consultants, consultants who work for the company aren’t employees. Consultants are normally self-employed. They show up temporarily to help companies solve problems and then leave the companies to work elsewhere. In the United States, differentiating between an employee and a consultant is important: So serious are the U.S. tax withholding laws that labeling a consultant an “employee” of any kind would subject the company to considerable legal risk.

To include consultants with employees in your code, you need a Consultant class that’s separate from your existing Employee class hierarchy. On the other hand, consultants have a lot in common with a company’s regular employees. For example, every consultant has a getPayString method. You want to represent this commonality in your code, so you create an interface. The interface obligates a class to give meaning to the method name getPayString.
package com.allyourcode.company;

public interface Payable {

public String getPayString();
}
The element in the code above isn’t a class — it’s a Java interface. Here’s what the listing’s code says:
As an interface, the getPayString method has a header, but no body. In this interface, the getPayString method takes no arguments and returns a value of type String. A class that claims to implement the Payable interface must provide (either directly or indirectly) a body for the getPayString method. That is, a class that claims to implement Payable must, in one way or another, implement the getPayString method.

The next two sections of code implement the Payable interface and provide bodies for the getPayString method.
package com.allyourcode.company;

import java.text.NumberFormat;
import java.util.Locale;

public class Consultant implements Payable {

String name;
double hourlyFee;
int hoursWorked;

static NumberFormat currency = NumberFormat.getCurrencyInstance(Locale.US);

public Consultant() {
}

public Consultant(String name, double hourlyFee, int hoursWorked) {
this.name = name;
this.hourlyFee = hourlyFee;
this.hoursWorked = hoursWorked;
}

public double pay() {
return hourlyFee * hoursWorked;
}

@Override
public String getPayString() {
return name + ", " + currency.format(pay()) + "\n";
}
}
Check out this code: Another Class Implements the Interface
package com.allyourcode.company;

public class Employee implements Payable {
String name;
String jobTitle;
int vacationDays;
double taxWithheld;

public Employee() {
}

public Employee(String name, String jobTitle) {
this.name = name;
this.jobTitle = jobTitle;
}

@Override
public String getPayString() {
return name + ", Pay not known\n";
}
}
Both the Consultant and Employee classes implement the Payable interface — the interface that summarizes what it means to be paid by the company. With this in mind, consider this code:
package com.allyourcode.a10_10;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import com.allyourcode.company.Consultant;
import com.allyourcode.company.Employee;
import com.allyourcode.company.Payable;

public class MainActivity extends AppCompatActivity {
TextView textView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

textView = (TextView) findViewById(R.id.textView);

Employee employee = new Employee("Barry", "Author");
Consultant consultant = new Consultant("Willy", 100.00, 30);

textView.setText("");

displayPay(employee);
displayPay(consultant);
}

void displayPay(Payable payable) {
textView.append(payable.getPayString());
}
}

java-programming-for-android-developers-2e-employee
Paying an employee and a consultant.

The displayPay method doesn’t know anything about Employee classes or Consultant classes. All the displayPay method knows is that it wants its parameter to implement the Payable interface. As long as the object you pass to displayPay implements the Payable interface, the displayPay method’s body can safely call the getPayString method.

Both the Employee and Consultant classes implement the Payable interface. So, you can pass an Employee object to the displayPay method, and pass a Consultant object to the displayPay method. That flexibility — the ability to pass more than one kind of object to a method — illustrates the power of Java’s interfaces.

Two otherwise unrelated classes (Employee and Consultant) both implement the Payable interface.

java-programming-for-android-developers-2e-interface
An interface cuts across the class hierarchy.

The dotted line isn’t part of standard UML. The folks who manage the standard have much better ways to represent interfaces.