Java is the primary language used to create Android apps. Java, you may have heard, is an ‘object oriented’ programming language. But what precisely does that mean?

Before Object Oriented Programming

One of the easiest ways to understand what is meant by ‘object oriented’, is to define what it is not. Before Object Oriented Programming (OOP) programs were written an imperative way, essentially a long list of commands (instructions). In imperative programming, you write your code the way you would write an essay: from top to bottom.

In imperative programming, you write your code the way you would write an essay: from top to bottom.

The ZX Spectrum, where I learned to code. Image from Amazon.

In fact, my first programming language was BASIC on the ZX Spectrum which was very much imperative. So much so, that all the lines were numbered as ’10, 20, 30’ etc. If I wanted the program to repeat something it had already done earlier, then I could use the command ‘GOTO 320’ to get it to jump back to a certain point and then continue to progress as before.

The problem with this kind of programming is that it can get incredibly complicated and difficult to navigate as the code gets larger. If you’ve built a program that’s millions of lines long (which is common) and you have commands that jump between seemingly random points in that code, it becomes almost impossible to follow, or to find errors when things start going wrong. This is what some people now refer to as ‘spaghetti code’.

This is a good approximation of what procedural code can end up looking like…

To fight the spaghetti, new programming languages were invented which tried to make the code more modular, more structured. These new procedural languages promoted GOTO free code, with nested control structures along with procedure calls. A procedure (or function) is a discreet unit of logic which performs a task give a certain input. After procedural and structured programming came object oriented programming.

The Idea Behind Object Oriented Programming

It’s perhaps best to think of OOP as a design philosophy. With procedural languages there was no connection, no relationship between the data being used and the procedures which used them. One procedure could alter a data structure and then a seemingly unrelated procedure could also alter it. With OOP the procedures (which are now called methods) and the data are intrinsically tied together.

An object contains data and behaviors

A great side effect of object oriented programming is also just how easy it makes it for us to share code with other people and to build more elaborate programs without having to handle every last line ourselves. OOP is ideal for collaboration and facilitates an open source attitude.

There’s a certain elegance to object oriented programming and while it’s a lot more complicated to grasp, it pays off once you do get to grips with it.

What is an Object?

The way the data and the methods work on the data is by being tied together in an object. An object contains data and behaviors. To define an object, to define the data and to define its methods, you use a class. Let’s imagine you want to create a class to represent a bank account. The class, let’s call it BankAccount, would have some data like account holder name, account number and balance. The methods would be things like getAccountHolderName() or deductFromAccount(). By default only the methods that belong to the BankAccount class have the right to work on the data associated with the class. By limiting access to the data then, a class can be sure that no other part of the program has manipulated its data. It also means that an object can hide its internal data structures from other objects.

When designed properly, a class (and probably a set of other dependent classes – classes within classes that inherit the same properties and data) can be re-coded and improved without affecting the other parts of the program that use it. As long as the public facing interface remains the same (the API), and as a long as the functionality remains consistent.

That is how the Android SDK works (in part). Google releases new versions of the SDK frequently, however our Android programs still build and work as before because Google doesn’t change the behavior, however it might re-work the internals of the classes.

An Example

To demonstrate how all this works, let’s see how we might actually write the code for our bank managing example. I’m going to share the code twice: once without comments so you can look it over and try to work it out without me getting in the way, and once with comments explaining what each line does.

public class BankManager
{
 
    public static void main(String[] args)
    {
        BankAccount adamsAccount = new BankAccount();
 
        adamsAccount.setBalance(100);
        System.out.println("Balance was: " + adamsAccount.getBalance());
        System.out.println("He withdrew 14");
        adamsAccount.deductFromAccount(14);
        System.out.println("New balance is: " + adamsAccount.getBalance());
    }
}

public class BankAccount
{
    private int balance;
 
    public BankAccount() {
    }
 
    public void setBalance(int balance) {
        this.balance = balance;
    }
 
    public int getBalance() {
        return balance;
    }
 
    public void deductFromAccount(int withdrawal) {
        this.balance = this.balance - withdrawal;
    } 
 
}

Okay, now here it is with the comments added. A comment is anything with ‘//’ preceding it, which means it is not part of the code. You’ll often see these marking up programs to make them easier to navigate!

// The class 'BankManager' is the superclass and the name of the file.
public class BankManager
{
    // Usually, you need one class in any piece of code with a method
    // called 'main'. This is where the code will 'start'.
    public static void main(String[] args)
    {
        // When you use a class to create an object, you refer to it as
        // creating an 'instance' of that object.
        // Here, we are creating a specific bank account called 'adamsAccount'
        // - but we could make as many as we wanted!
        BankAccount adamsAccount = new BankAccount();
 
        // This launches the method 'setBalance' method, which accepts an
        // integer (number) as a parameter
        // So we are passing the value 100 to the 'balance' variable of this
        // instance of our bank account object
        adamsAccount.setBalance(100);

        // Using a basic Java IDE (programming environment) then 
        // 'System.out.println' allows us to output data to the screen.
        // Here, we are outputting a string followed by the return string
        // of 'getBalance'
        // This retrieves the private integer balance for this object, 
        // which we just set to 100
        System.out.println("Balance was: " + adamsAccount.getBalance());
        System.out.println("He withdrew 14");

        // This is a first method within our BankAccount class which accepts
        // another integer parameter
        // This time though, that number will be deducted from the
        // balance variable
        adamsAccount.deductFromAccount(14);

        // Finally, we retrieve and show the balance once again, which
        // should now have changed!
        System.out.println("New balance is: " + adamsAccount.getBalance());
    }
}

public class BankAccount
{
    // This is a private variable belonging to this class, meaning that we can't
    // access it from our 'main' class
    // i.e. We could not just write 'system.out.println(balance)
    // However a subclass - class within a class - would be able to access
    // this because it would 'inherit' it
    private int balance;
    private int interestRate;
 
    //This is called a 'constructor' and always needs to be present in a new class
    public BankAccount() {
    }
 
    // This is the method we reference when we set the balance. 
    // Remember, we passed this method the integer 100, which will
    // now become the new balance
    public void setBalance(int balance) {
        // 'this' means 'this instance of the object'. 
        // In other words, it means that we're talking about adamsAccount,
        // not any old account!
        this.balance = balance;
    }
 
    // Notice that this is not a method but rather an integer itself.
    // Because this returns an integer, that means we can use this
    // just like a local variable within our code 
    public int getBalance() {
        return balance;
    }
 
    // Finally, this method uses a little math to withdraw
    // the amount from the overall balance
    public void deductFromAccount(int withdrawal) {
        this.balance = this.balance - withdrawal;
    } 
}

Don’t worry if you don’t follow all of that right away, it can take a little time to get your head around. For those that are looking at this purely theoretically, hopefully this has helped illustrate how you might actually use objects and classes in practice. For those actually starting to play with Java, maybe it will help phrases like ‘this’ seem a little obtuse and provide some context for why things are structured the way they are!

Moving Forward

This rabbit hole goes pretty deep, but if you’re struggling with all that, then the analogy that many people will use is that a class acts like a blueprint to build the object, just as a real blueprint builds a house. An object meanwhile is a collection of behaviors (commands) and data which are useful for the code to function.

There are more advantages to OOP. For example, one object can be derived from another. Going back to the BankAccount example, if the bank also offered savings accounts then a saving account is a type of BankAccount but with some extra data, say interestRate. That might also be a new method, like calculateInterestEarned(). But it still needs access to the other methods and data like balance or deductFromAccount().

When a class is derived from another class it is known as inheritance. Technically a more generic base class is called a ‘superclass’ and the derived class is called a subclass.

If you did want to get a better understanding of what it means to code in an object oriented programming language though, then I would actually recommend having a little play with Python. Python is a particularly simplistic and straight forward programming language that just happens to use objects and classes. And I use the term ‘simplistic’ in the best possible way – it’s very elegant and makes the whole concept a lot easier to grasp whereas Java can be pretty daunting for a newcomer.

As ever though, focus on learning what you need to know to complete the jobs you are working on. Don’t get bogged down with unnecessary theory until you need it!

 

Show 2 comments