Saturday, September 3, 2016

JAVA 15 - Inheritance

So ... we've got a pretty sweet class that represents dice classes all built.  Then this guy happened ...

Tim Hall, aka Kalyr on Twitter.  You see Tim has a broader range of RPG games than even me, and reminded me that there are some games which use dice which don't have numbers on them!


A good example is Halo Fleet Battles by Spartan games - their dice look like this ...


I did some analysis on the dice, for their 6 sides,

  • 1 side has "skull" on it. This represents and absolute fail.
  • 2 sides have "N/A" on them. This is a fail, but can be re-rolled in some circumstances.
  • 2 sides have "One hit" on them. This represents a single hit.
  • 1 side has "Two hits" on it.  This represents two hits, and the user get to re-roll any "N/A" dice.

These dice are fundamental to how Halo Fleet Battles plays - but it doesn't fit well with my original dice class.  What am I to do?

Inheritance

The answer to this is called inheritance - you can build a new class which is derived from another class (which is often called the base class).

This new class is called a child class, and can be declared in a new class definition using the extends keyword,

public class ChildClass extends BaseClass {...

Extends shows sets up the relationship between the BaseClass and the ChildClass.  So for our example, we're going to use ...

public class HaloFleetBattlesDiceClass extends DiceClass {...


A good rule of thumb for when you need a new class derived from an old one is when you say "I need to cover a Halo Fleet battle dice - it's a kind of dice".  Those two words "kind of" are crucial.

That's essentially what we're saying here - that our Halo dice has a lot of similarities with a normal dice, but it has just a few additional pieces of behaviour, which are unique to a Halo dice, so we're going to capture in it's own class but use those features which make sense from the base class for dice.

Accessing elements from the baseclass

There are, however, some problems.  The child class cannot see anything private within the base class - it does make some sense to work with this - although another option is to set things you absolutely need to protected.

Protected means they're visible to the child class, but outside of that, treated as private.  Generally though it's better to think of ways to share this information with getter methods if needed.

Sometimes I will be in the child class, and need to refer to a method in the base class which has been overriden (not as I'd originally written overloaded) - that is has a method in my child class of the same name.  I can access this by using the super keyword to reference attributes or methods in the base class which are public or private.



Let's walk through the Halo Fleet Battles dice class as we build it from the ground up.  You can find the code for this here on Github.

Please note - I have made some minor changes to method names compared to last time - for instance I think getDiceResult is a better method name than diceResult, which sounds like it should be an attribute over a method.

Declare as a child class



We do this using the extends keyword as we talked about.  I've also added a String attribute which describes the dice result, as we're not dealing with simple number here.

Create a constructor


We need a customised constructor here, however we also need to use our base class constructor.  All our dice are 6-sided, so I use super(6) to call the base class constructor with an argument of 6 (to make a 6-sided dice).

Roll Halo dice


I couldn't reuse and override the base class method rollDice, because I want to return a String from this which describes the dice face.  Consequentially, as rollDice isn't redefined in this childClass, I can use rollDice() instead of super.rollDice() to call the base class function.

I then do a switch on the number I get back, and convert it into the appropriate string.

Dice value

This method returns how many hits have been achieved on the dice - and does override the getDiceValue function in the base class.  Hence we have to use super.getDiceValue() ... you should try it without the super, and you'll see how much it doesn't like it!

Our @Test method



Nothing too revolutionary here - just take note of how we're declaring our class using haloFleetBattlesDiceClass.

The output looks like this ...


Interested in more on Halo?


For more information about Halo Fleet Battles, my son and I run a wargaming channel.  Check out our unboxing video here.

Extension material

Look up and read more about,

  • Inheritance
  • Child/parent classes
  • super keyword
  • protected declarations
  • overloading in Java
  • override in Java
Typically in class hierarchies we use,
  • "parent", "base" or "super" class for the original class.  [I like "super" as it reminds me that when we're using the super keyword, we're doing things in the "super" class]
  • "child" or "sub" class for the derived class.

In case you come across different terms, just different ways of saying the same thing.

EDIT - You'll see below Andrew Morton makes a comment, which I've now included to correct.  Thanks Andrew.

4 comments:

  1. Terminology query:
    "Sometimes I will be in the child class, and need to refer to a method in the base class which has been overloaded - that is has a method in my child class of the same name" <- Isn't this Overriding and not Overloading?
    I believe Overloading is where you have the same method name but different parameters and is used to supply default values for a method.

    ReplyDelete
    Replies
    1. I believe you're right. I think one of the problems with my very hands on approach is I get the terminology wrong occasionally.

      Delete
  2. Here when Flight is Flying it has got only Wings when it is Landing it shows the behaviour of Flying as well as Landing. ie. When Landing type object is created, it can use both the method - wings() in class Flying as well as wheels() in class Landing, because Class Landing extends Class Flying.

    java training in chennai

    ReplyDelete
  3. Gambling games suitable for gamblers of all ages.


    รอยัล1688 Online gaming sites that can be played every day are casino games that will enjoy great returns. Complete with various investments. Enjoy the chance to make good money every day. Can be gambled in a friendly way. With the bets that anyone can choose to play each day. Where are you going? I want to make a good income. Make more money, have fun, have simple investment games. Have fun all the time.

    Investment to help generate a good income. Have a simpler casino game. Get this good return. Make good money every day, enjoy fun, make more money with fun entrance, all kinds of gamblers have fun every time. Risky game that anyone choose. Give a good return. This is a great fun game with lots of fun. You can gamble yourself in all areas. Get things like this. Join the gamble every day. Realistic gamble with the chance to give the player a lot of options to gamble well in all areas. Where can I bet every time. viva3388

    ReplyDelete