Friday, September 2, 2016

JAVA 12 - Introducing classes

So far we’ve put together a lot of important groundwork for Java, there is one last area to cover in this basics course – and that’s on classes, which we'll cover over the next few sessions.

Up until now we’ve looked at

  • Data – whether variables or in an array.  Often called attributes
  • Methods – which act on that data

A class is an amalgamation of both – it is a representation in code which contains both attributes and the methods relevant to those attributes.

Okay – let’s model a dice then.  There are a whole world of dice out there … just in case you thought it only came in the 6-sided kind ...



Attribute analysis

Lets think about attributes.  What are values on a dice which might be important to us, and we’d want to model?

  • Number of sides.  That’s pretty important.  Most dice are 6-sided.  But not all.
  • Value displayed.  The side that’s currently up, this determines the value, “what we rolled”.
We could also have mapped the colour of the dice, that's an attribute, but generally in games, the colour doesn't matter.  And so we'll keep at those two attributes for now.

Method analysis

Methods are “things we want to do with the dice”.  Now remember we’re just trying to model the dice itself, not any aspect of rules for the game (we’ll do that in a later layer).
Obvious ones are,

  • Set the number of sides on the dice.  That will define if we're using a D6, D4, D12 etc ...
  • Roll dice.  Rolls the dice, using a random number generated.  Can’t exceed the Number Of sides.
  • Dice value.  Returns the value shown on the dice
  • Above X.  Some games want to know if you’ve rolled higher than a set number.  In Warhammer 40k, one of my Space Marines causes a hit if he rolls 3+.  This function should return 1 if the dice value is above a threshold, otherwise 0 is returned.
  • Below Y.  Likewise some games want to know if you’ve rolled below a set number.  In Warhammer 40k if I have an Imperial Guard player with strength of 3, I might have to roll 3 or under for him to avoid being sucked into a void, as he tries to grab onto something.
  • Matches X. Might want to know if the dice matches a number.
Epic Imperial Guard cosplay. In Warhammer, these guys are cannon fodder.

Classes and objects

Something worth being aware of.  The talk between classes and objects can be confusing, especially as some people use them interchangeably.

An object is an instance of a class.  That's probably confusing at first - so let's think in terms of Strings,
String str1 = "Hello";
String str2 = "World;

Both str1 and str2 are instances of a String class.  Both str1 and str2 share a lot of similar functionality through being of the same class, but their contents are unique.


Still confused a bit?  When you have ships built to the same design, that design is called a class.  Each ship is it's own implementation of that class, and "it's own thing".  So for instance the Second World War aircraft carrier USS Enterprise was one of the Yorktown class.

When we code, we design a class, like the ship designed.  When we run our code we're not running with the design (the class), but an actual version (maybe even multiples) of what we've designed (the objects).



Creating our dice class

This won't be too difficult, we've really been working within classes all this time, just not really thinking about it.

As always, my code for this is up on Github here.



I'm only focusing on the attributes and the key methods here.  You might notice I've made my attributes private and my methods public.  There's a reason for this we'll cover in a later section, but generally you only want your methods to be able to manipulate your class attributes.  If you need an attribute altered, use a method - if a suitable one doesn't exist, make one.

  • setNumSides is passed a value, which it uses to set the numSides for the object.
  • rollDice uses random number to set (and return) the value of diceRollValue
  • diceValue returns the value of diceRollValue


All these methods are examples of what are called "getters and setters", they either set the value of an attribute (setNumSides), or else return/get the value of an attribute (diceValue).  Of course rollDice can be said to be doing both.

There are some extra methods in there which I don't want to dwell on today - do read them if you have time.  I just want to point out something unusual I did though ...


You'll notice in this example I've not used {...} after the if/else statement.  That's because it's not needed when you're working with a single command.  The {...} brackets are used to collect up multiple statements for a pathway in not just if statements, but also methods and classes - they're well worth reading more about here.  I've avoided talking about them in depth earlier as they can get a bit confusing as you're trying to learn.

Generally though, most places use a coding standard to always use the curly brackets, I just like to point out it's not strictly necessary, because I like to know these things.

Declaring and referencing classes

So, we've got our class all designed.  How do we actually use it?

Once completed you can use a class very much like how you use variables - you can declare them, and use their methods.  In fact String that we've used a few times is actually a class.

The difference between a variable which is a "primitive type" (such as int, double or boolean) and classes (such as String) is that classes have methods associated with them.

When you're using an object (a declared version of a class), and use the "." after the object name, you can access the public attributes and methods of that class.  I've been looking for the name of this ".", which is not easy to Google, and the best I've found so far is "object access member operator".

To use this, for instance with a String you will see ..

So how do you declare an object?  Here is the format you use,

ClassName  objName = new className();

Here

  • ClassName - the first instance declares the type of class being used
  • objName - this is any name you want which you will used as a handle to manipulate your object.  Make the name relevant.
  • new - declares you're making a new object.  It's possible to use assignment to point to an existing object type.
  • className() - the inclusion of () means this calls the constructor for the className object.  We'll cover more about them next time.


You can then feel free to call attributes and methods from this object using,

objName.attribute1;
objName.attribute2;
objName.method1;

Let's explore this with our example,



Here,

  • DiceClass dice1 = new DiceClass() - this declares a dice object named dice1, which is of the class diceClass
  • dice1.setNumSides(6) - calls the setNumSides method, passing the value of 6, for our object dice1
  • dice1.rollDice() - this calls the rollDice method for our dice1 object



4 comments: