Showing posts with label objects. Show all posts
Showing posts with label objects. Show all posts

Saturday, June 11, 2016

Basics: Just what IS an object, anyway?

This is a pretty long one by the standards of this blog.  Try to stay with it, though, the concepts are crucial.

Whether people are experienced developers used to procedural languages or newcomers to programming in general, really understanding objects tends to be a bit of a sticking point.  It's odd, because once you start to get it, everything seems quite natural.

An object is a representation of...  something.  Sometimes they represent fairly nebulous concepts, sometimes they represent very real physical things, but in all cases they're a kind of model.  Objects have properties, just like a flower has a color or a bee has [6] legs.  Objects have methods, which are really just things you can ask them to do, like 'release pollen' or 'sting someone'.  Finally, objects have events, or at least they can generate events.  That could be 'I've been pollinated' or 'I left my stinger in someone'.  Any particular object may make use of one, two or all three of these constructs.

Objects are based on classes in Java.  There is an all too human tendency to use the terms interchangeably and I've probably been guilty of doing that, too.  Technically, a class defines how an object should be built and an object is an instance of such a class.  Basically, after you write your code you compile it to create a .class file, and then when you run your code you can make a new object from said class. Making objects is easy enough, most of them get created (or instantiated) by using the new keyword like this:

    SimpleObject myObject = new SimpleObject();

Let's break that down:

First, we have declared that we're interested in working with a variable of type SimpleObject.  In other words, someone out there has written a SimpleObject.java file that defined a SimpleObject class and you're going to make an object from that definition.

That variable will be called 'myObject'.  We have to name our variables or we'd have a really hard time referring to them in our code!

We're not referring to a previously existing SimpleObject, we're going to make a completely new one.  The actual creation is handled by a constructor inside of SimpleObject.java, and we need to rely on that constructor doing its job, correctly setting up anything within the new object that needs to be in place.

Some objects don't appear to have constructors at all if you read the code, but that just means that there is no need for a constructor to do any setup work, so the programmer was able to rely on Java creating a default constructor for them.  The code for SimpleObject may have been written either way.  We don't care at this point, we just know we can call it.  I'll get back to constructors a little later when we talk about actually writing a class of your own.

Defining an class in Java is straightforward enough.  You don't really have to do any more than create a .java file with a bit of correct syntax.  The following example is enough to make a SimpleObject class (which really can't do anything but exist):

package com.oopuniversity.simpleobject;

public class SimpleObject {
}

Of course, a class that doesn't do anything isn't very useful, but I think it's good to have a picture in your head of all the 'extra' stuff that absolutely needs to be in place.  Code can look a bit busy to new developers, and its best to know what is basically template stuff that you should make sure is there and then ignore.

Just to break it down, that 'package' statement up at the top tells the compiler where the generated class file should go.  It's basically specifying an output directory, but using periods instead of slashes or backslashes.   Packaging is primarily an organizational tool and it turns out to be an important one later on.

Then we have 'public class SimpleObject' which tells us we're defining a class called SimpleObject.  That public keyword is important, it controls whether other objects in a larger program are able to create SimpleObjects or even refer to them at all.  For now, just use 'public'.  The day will come when you start to use other modifiers for specific reasons, but if you're reading this to learn you don't have those reasons yet.

Then we have some curly braces.  Those are ubiquitous in Java programs, and basically set boundaries for chunks of code.  In this case, they are setting the boundary for the beginning and end of the class, although they don't actually contain anything.  Anything between those brackets will be considered an attempt at having something be a part of SimpleObject.

Man, four paragraphs to describe three lines...  I guess a fair amount of information is consolidated down into even that useless bit of code!  Fortunately, that stuff always stays pretty much the same.  Once you understand that structure, you can kind of stop worrying about it and move on.

I mentioned above that I would talk about constructors.  Well, that time has come.  The following code is (aside from being in a different package) precisely identical to the previous code:

package com.oopuniversity.simpleobjectwithconstructor;

public class SimpleObject {
    public SimpleObject() {
    }
}

The only differences are:

  1. We changed the package definition, which lets us have this version of SimpleObject sit in the same project as the previous version without any conflicts.
  2. Now we have something new inside the braces that define the class.

The package definition is needed because I'm keeping everything inside one big project.  Just like you can't have two files with the same name in one directory, you can't have two classes with the same name in one package.

The new stuff inside the braces is defining a default constructor for SimpleObject.  It's public which means other objects can use it to make a new SimpleObject.  It has nothing between the parentheses, which means you can create a SimpleObject without having to give it any parameters, which are nothing more than pieces of information you give it (we'll talk about those soon).  Then it has some more of those fun curly braces, which again define boundaries.  Anything inside this particular pair of braces belongs not just to the class, but to the constructor itself.

Why would you want to write a constructor like this, making your class busier?  Well, you wouldn't, and that's why you get this for free with any class you write that doesn't bother defining a constructor of its own.  However, you DO need to know about and understand this for one simple reason:  It is also possible to define a class using a constructor (or a whole bunch of them if you like) that has parameters.  If you do this, the compiler will *not* create a default constructor for you and you won't be able to use a default constructor unless you explicitly write one.

https://github.com/OOPUniversity/OOP_Basics

Friday, June 3, 2016

Super basic object stuff

I am not going to rework this right now, I think it gets the main points across as is.

From a recent Reddit post:

What you are asking about is quite basic to object oriented programming. Let's start with the first point I'd like to make: PersonA and PersonB are exactly the same thing, except the data is different. However, they cannot be simple methods that return integer values, that will never fly. The values you're setting up are lost as soon as the methods end.
Instead, you want to create objects of type Person. You do this by creating a class called Person and setting up variables to represent the values you want. At its absolute most basic (and this isn't correct, it's just showing the idea) it would look like this:
public class Person {
    public int x;
    public int y;
    public int range;
}
This is more akin to what we used to call a struct in c. Ordinarily you'd have a lot more stuff in there, but adding that right now could inhibit understanding so I want to take this slowly.
With the above class you could do this in the class you've posted:
public static void main(String [] args) {
    Person a = new Person();
    a.x = 200;
    a.y = 100;
    a.range = 160;

    Person b = new Person();       
    b.x = 100;
    b.y = 400;
    b.range = 170;
After that, you could use 'a.x' or 'b.range' the same way you were originally trying to use 'xA' or 'rangeB'.
Remember when I said that I was just showing the basics? Well, objects are a lot more powerful than just bags of variables. Let's use just another couple of features.
First, let's make a 'constructor' for Person so you can slim down your code:
public class Person {
    ... //What you already have
    public Person(int newX, int newY, int newRange) {
        x = newX;
        y = newY;
        range = newRange;
    }
}
Now your main can do this:
Person a = new Person(200, 100, 160);
Isn't that nicer?
Next, let's add 'accessor' methods to Person. Accessors are also called 'getters' and there are good reasons to use them. Trust me on this, I'm on the train and don't have time to fully explain:
public class Person {
    ... //What you already have

    public int getX() {
        return x;
    }

    //Do the same thing for 'y' and 'range'
}
At this point, you could still do 'a.x = 5' or 'range = b.range'. We can prevent that by marking the variables as 'private'
public class Person {
    private int x;
    private int y;
    private int range;
    ... //what you otherwise already have
}
But wait! Now when I try to write a.x=5 I get some horrible error and everything is broken and the world is ending!
No, you just need 'setters', also known as modifiers to do the job for you:
public class Person {
    ... //Everything you already have
    public void setX(int newX) {
        x = newX;
    }
    // Follow the same pattern for y and range
}
Now the equivalent to 'int range = a.range' is 'int range = a.getRange()', and the equivalent of 'a.range = 50' is 'a.setRange(50)'.
There's a LOT more to OOP, we've really just scratched the surface. But just encapsulating your data in this way will go a long way towards making your programs more readable, maintainable and robust.
I have no doubt that questions are coming up in your mind. I tried to make this clear and left out a few niceties in the interest of getting it written quickly and not overloading you, but it's a lot to absorb. Please ask questions when you need clarification.

Friday, November 13, 2015

Design Patterns: Singleton

The word 'singleton' is used to describe a design pattern for objects where only one instance of the object is allowed to exist.

It would technically be possible for you to use nearly any Java class as a singleton by being very, very careful to only create one instance and use it throughout your application.  But why do you want to work that hard?  It's pretty easy to force a class to act as a singleton with a few lines of code.

First of all, we make sure that there is no constructor available to the public.  This means we must create at least one constructor and mark it with the keyword private.  This will keep random objects from just creating their own instances of the class you wish to protect.

    public class MySingletonClass {
        private MySingletonClass() {}
    }

Of course, that means you can't create your single object either!  Never fear, we can get around that.  After all, the singleton class itself can still invoke the constructor.  Since we can't make an instance, though, it will have to be a static method.  I prefer to call it 'getInstance' because that's a good description of what it does.

Of course, it's not safe or desirable to have getInstance just create a new object each time it's called.  So instead we'll store an object reference of the classes' own type inside it and use that:

    public class MySingletonClass {
        private MySingletonClass() {}
        private static MySingletonClass singleton = null;
        ....
        public static MySingletonClass getInstance() {
            ....
            return singleton;
        }
    }

And the rest is just the work that needs to be done to make this function reliably:

     public class MySingletonClass {
        private MySingletonClass() {}
        private static MySingletonClass singleton = null;
        ....
        public static MySingletonClass getInstance() {
            if (null == singleton) {
                singleton = new MySingletonClass();
            }
            return singleton;    
        }
    }

So what have we done here?  We've created a class that can't just be instantiated by anyone.  Instead, we've enforced a contract on client classes, one that states they can only create one copy of this object.  Whichever object attempts to obtain the singleton first will (unknowingly) be responsible for creating it as well in a case of lazy initialization.  The getInstance method is our gatekeeper for this, handing out the same object reference whenever asked:

    MySingletonClass aSingleton = MySingletonClass.getInstance();

As you can see, using it is pretty easy.  You could of course provide parameters to this method and pass them on to the constructor if needed.

Wednesday, November 11, 2015

Stop giving me so much static

Let's talk about the keyword static for a moment.

There are two different uses for this in our code.  It can be applied to methods or it can be applied to variables.

When static is applied, it disassociates the item being declared from any specific instance of the class.  For methods, this means that the method can be called by anyone at any time without creating a new class of that type.  This can be particularly handy for utility functions, initializers, or any other chunk of code that wants to run without caring that it's about a particular person, bill, or list of stocks.  For variables, it mostly means that the value is shared across all instances of the class.

Static Methods

Static methods can be called without making a new class.  For instance, it could be used for a factory method, which is a design pattern that calls for objects to be built by calling a function to do so.

public class Person {
    ...
    public static Person createPerson(firstName, lastName) {
        ...
    }
}

You can call createPerson without having a Person object, like so:

Person.createPerson("John", "Doe");

Many utility functions are declared as static, and as a general rule they will need to operate free of any context supplied by objects.

Static Variables

Static variables come from the same basic idea of being disassociated from any specific instances of the class.  They're useful for maintaining overall context, for instance, if we want to keep track of how many Person objects we've created we could write something like this:

public class Person {
    ...
    private static int numberCreated = 0;
    ...
    public static Person createPerson(firstName, lastName) {
        ...
        numberCreated ++;
        ...
    }
}

Now, every time we invoke createPerson, we'll also be incrementing the value of numberCreated, and it will always be available as a statistic our programs can check.

Many times, inexperienced programmers will overuse static methods, because when they first start creating methods and functions, they just call them from main.  Your main method has to be static, and if you try calling non-static methods directly from it, the compiler complains.  So the path of least resistance is often seen as just making those other methods static too.  This does seem to work, but it goes against object oriented design principals, and it's best to nip this in the bud.  So they start with this:

public class OutputTest {
    ...
    private PrintStream outputStream = ...;
    ...
    public static void main(String [] args) {
        print("This is a test");
    }
    ...
    public void print(String message) {
        outputStream.println(message);
    }
}

But that fails because you can't call 'print' from a static context, so they change it to this

public class OutputTest {
    ...
    private PrintStream outputStream = ...;
    ...
    public static void main(String [] args) {
        print("This is a test");
    }
    ...
    public static void print(String message) {
        outputStream.println(message);
    }
}

That fails, too, because outputStream isn't static, so they change the code again:

public class OutputTest {
    ...
    private static PrintStream outputStream = ...;
    ...
    public static void main(String [] args) {
        print("This is a test");
    }
    ...
    public static void print(String message) {
        outputStream.println(message);
    }
}

And they're satisfied.  Everything works now!  I call this the static cascade, and I recommend avoiding it.  If you did not originally intend for these items to be shared and free of binding to specific objects, then don't go changing them to act that way.  

Get used to writing object oriented code.  Do this instead:

public class OutputTest {
    ...
    private PrintStream outputStream = ...;
    ...
    public static void main(String [] args) {
        OutputTest test = new OutputTest();  //The key!
        test.print("This is a test");
    }
    ...
    public void print(String message) {
        outputStream.println(message);
    }
}

While it might be a bit more of a conceptual leap, it's actually a far smaller change to the original code, and it opens your class up to being more adaptable to use in other systems.  It's also a necessary step towards object oriented thinking, so you might as well get it over with now.

Friday, December 5, 2014

Encapsulation - Protecting You From Yourself

Encapsulation sounds like the central plot point of some weird science fiction movie, but actually it's a fundamental technique for improving the reliability and predictability of object oriented programs. Let's pull out our old friend PersonData and see what's ailing him today: 

public class PersonData { 
    public String givenName; 
    public String surName; 
   
    public PersonData() { } 

    public PersonData(String given, String sur) { 
        givenName = given; 
        surName = sur; 
    } 

    public String toString() { 
        return givenName + " " + surName; 
    } 


Let me start by saying that there is nothing fundamentally wrong with this class. It is properly formed, is created with a valid constructor, and has a fully functional toString override method that formats the name is a reasonable manner. Is it object oriented? Well, it's an object at any rate, but we can do better.

 Here's the key issue I'd like to address today. Suppose we had a method that we wanted to use to ensure that a person's name begins with a capital letter. The logic for this is simple enough, but I'm going to deliberately break it for this example, so don't use this method as-is:

public static String ensureFirstCharacterIsUpperCase(String input) { 
    String upperCaseString = null; 
    if (Character.isUpperCase(input.charAt(0))) { 
        return input; 
    } 
    upperCaseString = input.substring(0,1).toUpperCase() + input.substring(1); 
    return input; //Bad programmer! No Pizza! 


 Ignoring for the moment the fact that this method will not quite do what we actually want, how would one go about using it? Well, we could go ahead and write something like this:

PersonData joeBlow = new PersonData(); joeBlow.givenName=ensureFirstCharacterIsUpperCase("joe"); joeBlow.surName=ensureFirstCharacterIsUpperCase("blow"); 
System.out.println(joeBlow); 

That would work just fine, the first, second, and eight hundredth time you do it. But why would you want to? What if you decided that you wanted to capitalize all surnames? What if you wanted to plug in some library that understands how to capitalize special names like MacNeil or something? Do you really want to search out every instance of setting the last name and change it?

There is a better way, my friend, and it gets to one of the other key aspects of object oriented programming. Encapsulation is basically protecting your data from your own programs by making it inaccessible except through a very clearly defined path that you strictly control.

We start by making the fields surName and givenName private. This indicates that they cannot be changed by code in any class except PersonData.

private String givenName; 
private String surName; 

Of course, we aren't quite finished at this point, because we can't change or even see these values. That could make for a remarkably useless class if we did not find a way around it. The way around it is by creating 'accessor' and 'mutator' methods. Those are horrible names so we usually just call them 'getters' and 'setters'. These labels actually make a lot more sense, because the naming convention is to prefix the field name with 'get' and 'set'. 

The required methods for PersonData could look like this:

public void setGivenName(String newGivenName) { 
    givenName = newGivenName; 


public String getGivenName() { 
    return givenName; 


public void setSurName(String newSurName) { 
    surName = newSurName; 


public String getSurName() { 
    return surName; 


 With the fields marked private, and with our getters and setters in place, we would now write the code above more like this:

 PersonData joeBlow = new PersonData(); 
 joeBlow.setGivenName (ensureFirstCharacterIsUpperCase("joe")); 
 joeBlow.setSurName (ensureFirstCharacterIsUpperCase("blow")); 
 System.out.println(joeBlow); 

 But wait, there's more!

 Why should we take a chance that we (or some other developer) fails to use that method to make sure our first character is correct? We can do better than that, and make sure it always happens no matter what kind of night someone had. For now, we'll move 'ensureFirstCharacterIsUpperCase' into PersonData (we'll talk about a better way later) and we'll change our setters a bit:

public void setGivenName(String newGivenName) { 
    givenName = ensureFirstCharacterIsUpperCase(newGivenName); 


public void setSurName(String newSurName) { 
    surName = ensureFirstCharacterIsUpperCase(newSurName); 


 With this done, we can now do this instead:

 PersonData joeBlow = new PersonData(); 
 joeBlow.setGivenName ("joe"); 
 joeBlow.setSurName ("blow"); 
 System.out.println(joeBlow); 

 And still get everything looking the way we expect. We've minimized the amount of code we need to write, and we've encapsulated both field access and a bit of business logic in our PersonData class. Malicious or misinformed programmers will not be able to bypass our hard and fast rules. IDEs won't even let you see the fields in their helpful pop-up dialogs. Dogs will love us.

Of course, we can (and really should) do more than this. First off, we have a constructor that accepts the two names, and we need to make sure it's also performing this task. That's probably most easily done by also having it call the setters. Second, we can think about other business rules we can enforce, like "A user's first name cannot be null or zero length". The setter can check for this and refuse to accept a bad value. Of course, if it does so it also needs to complain to the caller that they've done it wrong. This would be done via an Exception, which we'll need to talk about soon.

Get used to writing your code this way. Protect your data from yourself. Use accessor and mutator methods regularly and uniformly. It's a small amount of extra work, but you will thank yourself later. It's actually a VERY small amount of extra work, given that any decent IDE will create the methods for you if you just ask, and it will certainly save you time and energy later on.

I'll update this post later with a link to a gist containing the fully updated PersonData Object.

Wednesday, December 3, 2014

Diamonds are not an Object's Best Friend

Once again, I turn to a post I made on reddit for inspiration.

Some people wonder why inheritance branch but never join.  Why not tie two different families of objects together and extend both of 'em?

I can see the point of that, one could conceivably build objects that join several disparate branches of inheritance into large and versatile classes.  Conceivably.  One could also get oneself into a world of trouble, though, and this is most easily explained via the so-called diamond inheritance problem.

Please note that you cannot do this and expect your code to compile, it's just a conceptual demonstration.
Diamond.java
public class Diamond extends Class1, Class2 {
}

Class1.java
public class Class1 {
    public void doSomething() {
         System.out.println("Class1.doSomething()");
    }
}

Class2.java
public class Class2 {
    public void doSomething() {
         System.out.println("Class2.doSomething()");
    }
}
Now you have a main that uses the above classes:
public static void main(String[] args) {
    Diamond diamond = new Diamond();
    diamond.doSomething();
}
So, when you run main, what happens? This is the essence of the diamond problem. You wind up having two lines of inheritance converging on one and run into a quite serious issue.

This basically just scratches the surface of the problem, of course.  We can also think about what happens when you try to invoke something in super.  The question would have to become 'which super'?  There are many potential negative ramifications from the interactions that could be created by allowing this kind of inheritance, and the creators of Java decided that the best way to avoid them was by preventing the issue altogether.
One can achieve most of the positive effects of multiple inheritance via Interfaces and a few helpful design patterns such as Adapter, Composite and Decorator.

Inheritance Part 1 - That Class is Super!

I would like to discuss the concept of inheritance, and no, I don't mean the vase that Aunt Gladys left you in her will.

When we talk about inheritance in object oriented programming languages, we are talking about how one object can be based on another object.  In Java, we use the keyword extends to do this.

However, in order to make this as simple as possible, let's ignore even that keyword for a moment.  EVERY single Java class automatically extends the class Object without any effort at all on your part.

Let's look at an example Person data object, which I will continue to use as an example for future posts.

public class Person {
    private String firstName;
    private String lastName;

    public Person(String newFirstName, String newLastName) {
        firstName = newFirstName;
        lastName = newLastName;
    }
    ...
}

As I mentioned above, Person automatically extends Object, so in reality the class definition is really more like this:
    public class Person extends Object {

But we just don't bother writing it.  We call Object the superclass of Person and Person is called a subclass of Object.

As far as what this brings to the table, let's use what is perhaps simultaneously one of the most common features and one of the most common issues people have with objects when they are starting out.  Printing them out.

If I create a new Person object and want to see what it looks like, I might be tempted to do this:

    Person joe = new Person("Joe", "Blow");
    System.out.println(joe);

If I do this, I will be sorely disappointed when I run my program, because while I might expect to see this:

    Joe Blow

I will instead see something like this:

    Person@4f1d0d

At this point, I begin to tremble and sweat.  In a panic I turn to stackoverflow.com or /r/javahelp and complain that my object is broken and my printouts are garbled.  The regulars there probably make fun of me for not actually posting my code correctly or something.  My dog bites me and my girlfriend refuses to go out with me.  OK, I may have exaggerated a bit.

But what's happening here is that when you call 'System.out.println(joe)' you are (again, invisibly) actually in effect calling 'System.out.println(joe.toString())'.  After all, you need to turn your object into something that can be displayed on the console.  

You might at this point be saying to yourself "But wait, I don't have a 'toString' in Person" and in a sense you're right.  You certainly didn't create such a thing.  But you did in fact inherit a toString method from Object.  Object is pretty ignorant about your code, though, and has no idea how you intend to format your printouts, so it just tells you the type of object and where in your JVMs memory that object is stored.  In general, if a superclass contains a method, a subclass can call it as though it were a part of the subclass itself.

This is all inheritance really is, in the end.  If we try to call a method or refer to a variable in an object, and it isn't mentioned in that object, the compiler tries to see if it's available via inheritance.  If so, you avoid compile errors and things 'work'.  They may not work the way you want, but at least something interesting happens.

Let's fix the problem now.  I could take the cheap and easy way out like this:

    System.out.println(joe.firstName + " " + joe.lastName);

And that would work.  But honestly, all we really need to do is create our own 'toString' method in Person that does things the way we want.  This will save us the effort of having to write the above code everywhere that wants to just display someone's name.  You'll really appreciate that when you decide that you'd rather display that guy as "Blow, Joe" instead and have to change code in 23 different places.

Add the following block of code to Person:

public String toString() {
    return firstName + " " + lastName;
}

And just like that, the original program will print the name out the way you wanted it to in the first place.

There, you've done it.  You've made use of an inherited method, and then you created an override for it.  An override is nothing more or less than specifying that instead of using the method found somewhere up the line of inheritance, you want to use this specific method instead.

When it comes down to it, overriding toString is just the tip of the iceberg, and I will of course be revisiting this later on.  There are some extremely interesting things that you can do with inheritance, and it forms the basis for many important language structures.  For now though, just remember that one class can extend another one, and that when it does so it has the option of replacing methods in its superclass with its own more specific version.  There are a few other rules you'll need to follow, but most of them are not too horrible to deal with.

Friday, November 21, 2014

Collections Part 1: List

Let's talk about Collections.  I don't mean baseball cards...  or dust.  I'm talking about the Collections framework, which is a powerful set of classes included with your Java distribution.

This is not meant to be an in depth tutorial.  I'm merely going to scratch the surface and give a few guidelines regarding basic use of the framework.

The Collections framework is incredibly important to the Java developer.  You will spend a great deal of time working with the data structures within it.  The two that you will most likely use more than any other are List and Map.

List and Map are not classes.  They are interfaces.  An interface can be thought of as the set of controls for a range of classes.  Much like you might have a gas powered or electric powered oven, you still turn a dial and set a desired temperature.  The interface is the same, although the implementation is different.  This is a key concept:  Code to the Interface is commonly said, and slightly less commonly actually done.  I will do other posts on this idea, it's very important.

Let's start with List.  We'll do Map in another post.

Suppose I wanted to keep track of a few numbers read in from a file.  Each line contains one number, but I don't know how big the file is.  While it would be possible to load the numbers into an array, it would be a bit messy, as I would have to manage the size of the array.  Enter the 'ArrayList'.  This is a Collections based object that works very much like an Array with a turbocharger on it.  I don't have any hard numbers on this, but my suspicion is that it is the most commonly used Collections class out there.

Let's say my pseudocode looks something like this:

Open a file

For each line in the file:

    Read an integer number from the file
    Store the integer in a list for later use

Generate a sum of all the integers in the list as SumTotal
Display SUM to the user

There are multiple paths to success of course, and it's hard to say that any given solution is exactly 'wrong'.  However, unless we know in advance how many values we're going to store, or we wildly oversize the initial allocation, using an array would require us to modify the length of the array regularly.  It's not that this is particularly hard, but it's even easier not to do it.

And let's face it:  One of the secrets of successful programming is doing things the easy way.  It's a hard enough job, there's no reason to add unnecessary bells, whistles and epicycles to our code.

I'm not going to address the bits about reading the file right now, that will be in another post.  I just want to concentrate on 'Store the integer in a list for later use' and 'Generate a sum of all the integers in the list as SumTotal'.

First, we have to create the ArrayList object.  I'm going to do so in a way I haven't shown you before, but it's not too awful to understand:

List<Integer> numberList = new ArrayList<Integer>();

What?

Well, honestly Java can deal with this without having those '<Integer>' parts, but I thought you ought to get used to using them.  They're really handy for preventing certain classes of errors when programs get bigger.

What this is doing is creating a variable called 'numberList'.  It is an object of type 'List', and that 'List' is constrained to hold only Integer values.  That's the reason for the syntax, it makes sure we don't do something silly like try to put a String or a PersonData in there.

List is NOT a class.  You cannot create a 'new List()' directly.  It is what's known as an interface, and essentially describes how to use a category of classes, rather than one single class.

ArrayList IS a class.  You could do this if you so choose:

ArrayList<Integer> sillyNumberList = new ArrayList<Integer>();

This is roughly akin to adding the name of the manufacturer before mentioning an appliance.  Every time.  You wouldn't tell someone to go get you a beer from the Acme refrigerator, you'd just say refrigerator.  The fact that it's an Acme was only important when you bought it (or when you need to have it repaired.  Don't ask me about refrigerator repair, it's a sore spot).  The fact that it's a refrigerator means that you will grab a handle, pull it, and find something yummy and cold inside.  The specific manufacturer does not matter.  Similarly, a List allows you to add items, remove items, look at items and such, all without having to know that it is specifically an ArrayList.

Let's imagine that we've now got a value we want to add as an Integer, in a variable called 'numberToAddToList' (imaginative, huh?)  We'd just do this:

numberList.add(numberToAddToList);

No muss, no fuss, no checking capacity.  Set it and forget it.  You can do this once, or a thousand times or more.  That one line is all you'll need to use.

The other bit we need to work on is generating a sum of the numbers.  The way to do this, of course, is to take all the numbers, one by one, and add them to a variable that started at zero.  I'm going to do this three times here.  The first time using a for loop the way we've already done.  Next, I'll do so using an 'Iterator', which is a helper type designed to go through all the items in a Collection one by one, has been around forever, and is oftentimes a better choice than a standard for loop.  The last is using the 'enhanced' for loops that have been in the Java spec for a few years now.  None of these ways are strictly wrong, but if I was reviewing your code I'd want to see or hear a good reason for not doing it the third way.

Integer sumTotal = 0;

1)
for (int i = 0; i < numberList.size(); i++ ) {
    sumTotal = sumTotal = numberlist.get(i);
}

2)
Iterator<Integer> iter = numberList.iterator();
while(iter.hasNext()) {
    sumTotal = sumTotal + iter.next();
}

3)
for(Integer number : numberList) {
    sumTotal = sumTotal + number;
}


In all cases, we'd just then write:

System.out.println("The total is " + sumTotal);

As I think you can see, the new enhanced for loop makes life pretty easy.  You declare a variable and state where it comes from, and then just use it in the loop.

The iterator probably looks pretty awful to you, and to be fair, that's the cleaned up version available to us since we got to start using Generics.  Back before we could add that <Integer> tag it would have looked like this:
Iterator iter = numberList.Iterator();
while(iter.hasNext()) {
    sumTotal = sumTotal + (Integer)(iter.next());
}

But it was still a useful construct quite often.  Naturally in small examples like these the full impact does not show itself.

List can be used for much more than numbers of course.  Any sort of Object can be stored in a list.  You can have a List of Strings, or a List of Lists, or a List of Maps...

Next time, we'll discuss Maps, which instead of sequential access specialize in looking up specific objects based on a key value.

Wednesday, November 19, 2014

Don't Treat me Like an Object

I originally posted this on Reddit, and got some positive feedback on it, so I thought I would put it up here as an early lesson in object orientation.  That is, after all, our goal here and a dozen posts in I haven't really mentioned it at all yet.

Moving from procedural code to object oriented code is a major leap and takes a real adjustment in thinking.
Very often, multiple pieces of data logically belong together. For instance, a person's given name and family name should generally not be separated. There's little point in having separate references to "John" and "Doe", after all.
This concept existed before object oriented programming did, in the form of 'structures'. In c we'd do this
struct PersonData {
    char givenName[20];
    char surname[20];
}
Which helped some. Now we could declare a variable of type PersonData and pass it around, knowing that the fields would be kept together. Believe it or not that was a big step forward.  Of course a bit of energy was spent on doing things like determining if '20' was enough storage for a name.  
Objects are basically structs with functions added, and with the ability to hide internal details from users of said objects.
So while it would be possible to recreate the above struct as an object like this:
public class PersonData {
    public String givenName;
    public String surName;
}
That doesn't really take advantage of the power of the language yet. Sure, we can now go:
PersonData johnDoe = new PersonData(); //Use default constructor that comes free
johnDoe.givenName = "John";
johnDoe.surName  = "Doe";
But we can do better. For instance, a person ALWAYS has those names, right?  So why allow a PersonData object to even be created without them? Enter the 'Constructor'. It's just a method designed for one purpose: To initialize a new object. We could insert the following into our PersonData class:
public PersonData(String given, String sur) {
    givenName = given;
    surName = sur;
}
And now we could write the earlier code like this:
PersonData johnDoe = new PersonData("John", "Doe");
This PersonData is quite limited as it stands right now, since it's got no methods on it. But you know, that's OK, there's a place for objects that just store data, too. It is, however, a starting point to think about how objects work.
Of course, a constructor can do much more than set values for a few fields, too, performing any sorts of setup and initialization that might be required.
Please note, I am not saying that exposing those variables as public is a good idea, and I would not write them quite that way for a production application, but I'm trying to keep this example simple to understand.

Since whenever you write Java code you're forced to put it into classes anyway, I suggest that you always treat your classes as though they're going to be objects.  Make your main() methods as minimal as possible.  In short,don't do this:

public class InputData {
    public static void main(String args[]) {
        Scanner s = new Scanner(System.in);
        while(s.hasNextLine()) {
        ...

Instead, write it like this from the start:

public class InputData {
    public static void main(String args[]) {
        InputData inputData = new InputData();
        inputData.execute();
    }

    public void inputData() {
        Scanner s = new Scanner(System.in);
        while (s.hasNextLine()) {
        ...

Note that by adding just a few lines I've turned this into slightly more object oriented code.  I've avoided the static cascade problem.  I've also made it so that if I want to I can use this object from some other piece of code without a great deal of trouble.  That code I have in main could be duplicated anywhere.