This material is licensed under the Creative Commons BY-NC-SA license, which means that you can use it and distribute it freely so long as you do not erase the names of the original authors. If you make changes in the material and want to distribute this altered version of the material, you have to license it with a similar free license. The use of the material for commercial use is prohibited without a separate agreement.
Authors: Arto Hellas, Matti Luukkainen
Translators to English: Emilia Hjelm, Alex H. Virtanen, Matti Luukkainen, Virpi Sumu, Birunthan Mohanathas, Etiënne Goossens
Extra material added by: Etiënne Goossens, Maurice Snoeren, Johan Talboom
The course is maintained by Technische Informatica Breda
In Exercise overwriting-methods-2 there’s a problem though. It is possible to execute the following code
Vector2D vector = new Vector3D(10,10,10);
This would not make any sense though, as a Vector3D would be the same as a Vector2D.
In the shape example of last chapter, there’s also a big problem. It is possible in java to make a new Shape
Shape shape = new Shape(Color.green);
This would of course be nonsense, as a ‘shape’ does not really have a surface area or circumference. The methods in this class now return 0, but we can also remove the code for these methods, by turning this class into an abstract
class
class Shape {
private Color color;
public Shape(Color color) {
this.color = color;
}
public abstract double getArea();
public abstract double getCircumference();
}
An abstract class can contain abstract methods, which are methods that do not have an implementation. There is no code for these methods because it makes no sense, like in our Shape example. This also makes sure that there can be no new Shape objects, because it has abstract methods.
Shape shape = new Shape(Color.green); // won't compile, as Shape is an abstract class
In order to make an object, just extend the Shape class, and implement the abstract methods, as done before. This new class is not abstract anymore.
Exercise abstract-classes-1: Bank accounts
A bank has 2 kinds of accounts, a deposit account and a savings account. Deposit account costs 5 euro per year, and has no interest. A savings account costs 50 euro per year but has 5% interest. We are going to model this using an abstract class
abstract-classes-1.1 Account class
An account stores the name of the type of the account (Savings or Deposit), and have an amount of money on them. We will model these as attributes. Make an abstract class
Account
with the following properties
- attribute
String name
- attribute
double amount
- Constructor with parameters
String name
anddouble initialAmount
. The name attribute gets set toname + " (initial " + amount + ")"
- getter and setter for
amount
. Make sure the setter rounds the amount to 2 decimals- toString that prints
name - amount
- abstract
void calculateNextYear()
abstract-classes-1.2 Savings and Deposit account
Make a class
DepositAccount
that extendsAccount
. Implement a constructor with 1 parameter,initialAmount
. The name is set to ‘Deposit’. The classDepositAccount
overwrites the calculateNextYear, which sets the amount to the amount - 5.Make a class
SavingsAccount
that extendsAccount
. Implement a constructor with 1 parameter,initialAmount
. The name is set to ‘Savings’. The classSavingsAccount
overwrites the calculateNextYear, which sets the amount to the (amount - 50) * 1.05.abstract-classes-1-3 Using the accounts
Write a main method that tests the accounts. Make a program that outputs the following output (use the toString for the account to print the accounts)
Year 1 Savings (initial 500.0) - 472.5 Savings (initial 1500.0) - 1522.5 Deposit (initial 500.0) - 495.0 Deposit (initial 1500.0) - 1495.0 Year 2 Savings (initial 500.0) - 443.63 Savings (initial 1500.0) - 1546.13 Deposit (initial 500.0) - 490.0 Deposit (initial 1500.0) - 1490.0 Year 3 Savings (initial 500.0) - 413.31 Savings (initial 1500.0) - 1570.94 Deposit (initial 500.0) - 485.0 Deposit (initial 1500.0) - 1485.0
Exercise abstract-classes-2: Walking monsters
Given is a simulation with a
Hero
andEnemy
s. All theseCharacter
s are simulated, and can walk around, and attack other characters.
In this diagram we can see see it is quite easy to add new enemies, just extend the
Enemy
class. TheCharacter
class provides the following methods:
getX()
andgetY()
to get the position of the charactermoveTo(int x, int y)
to move the character to another positiondistanceTo(int x, int y)
anddistanceTo(Character other)
to calculate the distance to another characterArrayList<Character> getCharactersNear(int range, boolean isEnemy)
returns a list of all the enemies around this characterspawn(Character character)
adds a new charactersuicide()
kills this characterProvided is a simple enemy, the
RandomEnemy
, that just moves around randomly.Exercise abstract-classes-2.1 : Running away
Create a new enemy called
RunningEnemy
that will run away from the hero characters near. Create the class, and override theupdate()
method to run away from any players nearby. Give this enemy a ‘R’ as display character, and a health of 1Exercise abstract-classes-2.2 : Breeding enemies
Create a new enemy, called
BreedingEnemy
. The behavious of this enemy should be
- If a player is nearby, it should go towards the player to attack it
- If no player is nearby, it should move towards other
BreedingEnemy
nearby.- If the enemy is next to another
BreedingEnemy
, it should perform suicide on both BreedingEnemies, and make 1 new BreedingEnemy (and spawn it), with the health of both enemies, multiplied by 2Note Due to time constraints, this exercise does not test the behavious completely