owned this note
owned this note
Published
Linked with GitHub
# Using pokemon as example for option D of Computer Science
In this note I will use pokemon as example to do many posible practical questions that can be asked in a Computer Science Option D. The scenario will be described little by little adding more complexity.
## Description of the scenario
We're going to have the following classes
* Pokemon
* Pikachu
* Charmander
* Squirtle
* Bulbasaur
Here you have the Pokemon class (part of it)
```java=
public class Pokemon {
public final static int FIRE_TYPE = 0;
public final static int WATER_TYPE = 1;
public final static int PLANT_TYPE = 2;
public final static int ELECTRIC_TYPE = 3;
private int hp; //health points
private String name;
private int type;
private Attack[] attacks; //This is done later probably
//Contructor 1
public Pokemon(int hp, String name, int type, Attack[] attacks) {
this.hp = hp;
this.name = name;
this.type = type;
if(attacks.size == 4) {
this.attacks = attacks;
}
else{
attacks = null;
Sytem.out.println("pokemon created without attacks. Array of attacks doesn't have the correct size");
}
}
public Pokemon(int hp, String name, int type) {
this.hp = hp;
this.name = name;
this.type = type;
this.attacks = null;
}
//accessors and mutators methods
}
```
### Questions about attributes of variables
* Why do we have FIRE_TYPE as a public variable?
Because we want everybody to access it in the code. And we're not worried because this value can't be changed.
* Why do we use the static attribute for FIRE_TYPE?
Because we want only one variable for all instances. We don't want to waste memory if we have 2000 pokemon by having 2000 times that variable.
* Why do we use the final attribute for FIRE_TYPE?
Because it's not going to change during runtime.
* Why not making an array of types (numbers)?
Maybe we can if we have an array of Strings {"FIRE", "WATER", "PLANT", "ELECTRIC"} and the index is pointing the key. Problem is that any given time that we want to find one of these keys we need to loop through the array.
Using this system without the array. I'd write outside the class Pokemon.FIRE_TYPE and I'd get the info. Also many IDEs are going to autocomplete from Pokemon.F
* Why do we use private atttribute for the variable name?
We want to ensure encapsulation. For actually working on there we need to add the relevant accessor and mutator methods.
### Questions about the contructors
* Outline the general purpose of a contructor.
The usual purpose of a constuctor is to initialize the values of the instance. (there are other purposes like validating those values or instanciate Aggregated objects if needed).
:::info
Example of validation:
```java=12
public Pokemon(int hp, String name, int type, Attack[] attacks) {
this.hp = hp;
this.name = name;
this.type = type;
if(attacks.size == 4) {
this.attacks = attacks;
}
else{
attacks = null;
Sytem.out.println("pokemon created without attacks. Array of attacks doesn't have the correct size");
}
}
```
:::
:::success
Example of extra instanciating:
```java=
public Pokemon(int hp, String name, int type) {
this.hp = hp;
this.name = name;
this.type = type;
this.attacks = new Attack[4];
//new array
attacks[0] = new Attack("Tackle", 35, 40);
//example of how we could instanciate a new attack
}
```
:::
* Explain what is the OOP feature that allows Pokemon class to have more than one constructor.
Polymorphism, or method override allows two different methods have the same name but diffferent parametes (so they change the signature) and the code from this information can tell which one needs to execute.
* Construct another constructor method of Pokemon that without parameters it's going to instanciate a "Pikachu" with no attacks, electric type and 10 hp.
```java!
public Pokemon () {
this.name = "Pikachu";
this.hp = 10;
this.type = ELECTRIC_TYPE;
//this.type = 3 ; This would be correct even if it's not that consistent
//this.type = "Electric"; //This would be incorrect. type is an int and "Electric" is a String. It wouldn't even compile.
//this.type = Electric;//This would be incorrect. There is no variable called Electric. It wouldn't even compile.
this.attacks = null;
//this.attacks = new Attack[ null, null, null, null]; //this would be also correct.
}
```
### Questions about adding more variables
* Add a new variable to the pokemon class that is a boolean
Examples:
* shiny or isShiny
* hasEvolution
* likesStrawberry
Remember to try to make sense. For example "Faint" could be already in the pokemon since it's when the pokemon has 0 hp.
:::info
When they ask for these variables you don't need to write the semicolon nor an accessor or a mutator.
:::
* Add a new variable to the pokemon class that is a String
alias
owner (if we don't have a object for owner/trainer)
PlaceOfCatch
FavouriteFruit
* Add a new variable to the pokemon class that is a int
level
pokedexNumber
battlesWon
numberOfArms
### Question about mutators and accessors methods.
* State a possible accessor method for the Pokemon class
getHp, getName, getType
::: info
If you have a variable that is an object and/or an array, it's better not to use this for the examples.
:::
* State a possible mutator method for the pokemon Class
setHP, setName
::: info
If you have a variable that is an object and/or an array, it's better not to use this for the examples.
If possible also don't add elements that are not likely to change
:::
* Construct the getName method for the Pokemon class
```java
public String getName() {
return this.name;
}
```
* Construct the setHP method for the Pokemon class
```java
public void setHP(int hp) {
this.hp = hp;
}
```
## Subclasses. The Pikachu, Chikorita, the Squirtle and the Charmander classes.

_image of chikorita_
Let's say that we have different subclasses that are Pokemon, in this case, Pikachu class, Chikorita class, Squirtle class and Charmander class.
Here we can implement the Chikorita class
```java
public class Chikorita extends Pokemon {
public Chikorita (int hp, Attack[] attacks) {
super(hp, "Chikorita", Pokemon.PLANT_TYPE, attacks); //follow the structure of the constructor of Pokemon
}
}
```
* Define what is the relationship between the Squirtle and the Pokemon class
Inheritance
* Discuss the necessity of using different layers of classes between pokemon. Should we have a Pokemon, then Water pokemon and finally Squirtle.
Here we have the UML diagram of both options

Using the [K.I.S.S. principle](https://en.wikipedia.org/wiki/KISS_principle) we shouldn't add an intermediate layer of pokemon (waterPokemon) unless we have an actual reason to. In this case if we have data and behaviours that are specific to the water pokemon (and shared) but they are not relevant for any other type of pokemon.
:::info
This is not related to the number of _instances_. If we have 3000 Squirtles doesn't mean anything.
:::
:::success
**concept of Singleton**
Singleton is a paradigm where we have an object that we're going to allow only one instance in memory
The example that I gave in class was the pikachu that follows you in pokemon yellow, the player itself and connections.

They are not going to ask you in the exam but I think is a very useful concept.
Here you have some reference of implementation in java:
https://howtodoinjava.com/design-patterns/creational/singleton-design-pattern-in-java/
And the wikipedia includes also some more general concepts around it including its criticism
https://en.wikipedia.org/wiki/Singleton_pattern
:::
#### Concept of superclass
They usually ask about superclasses. Superclasses are the parent classes. All Objects in java have by default the superclass Object
So even if it's implied this would be the UML diagram

We can use methods of the superclass as if they were ours. We implied that in this case that we have getters and setters (accesssors and mutators) in Pokemon (but no in Chikorita)
So for example if we have this in the Main class.([main method in python](https://www.geeksforgeeks.org/python-main-function/))
```java
Pokemon pikachu = new Pokemon(54, "pikachu", Pokemon.ELECTRIC_TYPE, null);
Chikorita chiqui = new Chikorita (65, null);
System.out.prinln(chiqui.getHp());
System.out.println(pikachu.getName());
```
What would have been printed?
```
65
"pikachu"
```
### The Attack class
Let's do the attack class. It would have a lot of attributes in pokemon but we're going to K.I.S.S.
Let's do it from a UML diagram

If they ask you to construct the class this would be the answer. Usually in an exam you're going to be asked to create just one mutator or accessor (getter or setter)
* From the previous UML diagram construct the class Attack
```java
public class Attack {
private int power;
private int type;
private String name;
public Attack(int power, int type, String name) {
this.power = power;
this.type = type;
this.name = name;
}
public void setPower(int power) {
this.power = power;
}
public void setType(int type) {
this.type = type;
}
public void setName(String name) {
this.name = name;
}
public int getPower() {
return power;
}
public int getType() {
return type;
}
public String getTypeName() {
return typeName;
}
}
```
:::info
Reference of an example of attack: https://pokemon.fandom.com/wiki/Absorb

If we use this data from the wiki we would have more information.
Something that they can ask (and we have already discussed in this hackmd) would be adding more plausible variables to the class Attack
affectedByMagicCoat would be a boolean type
contact would be also a boolean type
Accuracy, PP (power points) would be ints.
:::
In this case something that you may have notice is that this Class doesn't have methods apart from the constructor, the accessors and the mutators. This is something that you might see in some exams.
:::info
**POJO** concept
This type of paradigm is called **POJO** (you can pronounce it in an English or Spanish way) that stands for **Plain Old Java Object** and is a _paradigm_ of having some objects as simple as possible. Also not restricted for implementing or extnding other classes
https://en.wikipedia.org/wiki/Plain_old_Java_object
They don't ask you directly about it but having this concept is useful. Specially when you can say about a specific class "ah, it's just a POJO"
:::
#### The concept of the "this." keyword
If you check the accessors and the mutators you will see this.
```java=
public Attack(int power, int type, String name) {
this.power = power;
this.type = type;
this.name = name;
}
public void setName(String name) {
this.name = name;
}
```
They may ask you:
* What is the purpose of using this. in the context of these methods?
The answer is to allow the compiler to differenciate the parameter (power or name) from the variables of the instance (this.name or this.power
:::warning
It's common to see it in contructors and mutators but they may appear in any kind of method.
:::
### How to add attacks to the pokemon.
In the [description of the class Pokemon](https://hackmd.io/SFDaYNufTESC4_k5GehaKw#Description-of-the-scenario) we have a way to add Attacks in the same Pokemon class, that is when we add them in the constructor. If it's not added in a size of 4 attacks (4 is the maximum number of attacks a pokemon can have) we're not creating that array. Here is the code:
```java
public Pokemon(int hp, String name, int type, Attack[] attacks) {
this.hp = hp;
this.name = name;
this.type = type;
if(attacks.size == 4) {
this.attacks = attacks;
}
else{
attacks = null;
Sytem.out.println("pokemon created without attacks. Array of attacks doesn't have the correct size");
}
}
```
### Setting an array of attacks after the pokemon has been constructed.
We have different solutions. First we can implement a mutator that it's going to change the array only if the new array is size 4.
Like this:
```java=
public void setAttacks (Attack[] attacks){
if (attacks.size == 4) {
this.attacks = attacks;
}
else{
//do something?
}
}
```
In the else depending on the level that we're working and the type of object we may just write a log, totally ignore it, or we may _raise an exception_.
:::info
Errors and exceptions handling
They are not included in the curriculum but they are nice to know.
Here more info. This is common in many programming languages
https://www.w3schools.com/java/java_try_catch.asp
:::
### Adding more attacks once we have an array of attacks
If we have an array of attack we may want to add a new one. For that we may implement a method called `addAttack(Attack newAttack)`
```java=
public void addAttack(Attack newAttack){
for (int i= 0; i<4; i++) {
if (attacks[i] == null) {
attacks[i] = newAttack;
return;
}
}
}
```
[[]]
///Construct the method public void joinLine(Cart newCart) that adds a newCart
to line in the next empty array location. You may assume that line is not full.
//Construct the method public Cart leaveLine(int n) that removes the cart
at position n from line by shifting down all the array entries bigger than n, before
returning the indicated Cart object. You may assume that a cart exists at position n.
## Read the properties of some objects
//TO-DO
## Infer other variables that make sense given the context
//TO-DO
## Write accessors and mutators
//TO-DO
## State the name of accessors and mutators
//TO-DO
## Instanciate something
When we instance something or they ask to instanciate something it should be something like:
```java
Potato potato = new Potato(parameters);
```
the first Potato is the class, in this case is the type of the new instance. The capital letter is important because it's a class
The second potato is the name, identifier of the variable. We can change it to myPotato or frenchFry. The first letter should go in lowercase because it's not a class.
New is the keyword to create a new instance
The third Potato() is the method that we're calling. The constructor that we specify.
```
UKSalesPerson peter = new UKSalesPerson(32, salesTotal, 5);
```
## Mention the properties of a variable:
### Private /protected /public
### Static
### Final
### Following a method and implement it
public boolean equals(SalesPerson salesPerson){
if (this.id != salesPerson.getId()){
return false;
}
else{
output("They are the same!");
Sales [] combined = this.combineSales(this.salesHistory, salesPerson.getSalesHistory());
this.salesHistory = combined;
salesPerson.setSalesHistory(combined);
// python. DO NOT USE salesPerson.salesHistory = combined;
int sum = this.counter + salesPerson.getCounter();
this.counter = sum;
salesPerson.setCounter(sum);
return true;
}
}
## HL extension
## Pointers and equals
Implementation of equal method.
In the first case of pokemon we don't have an id so it doesn't matter too much but if we have a type int ID (or UUID)
let's say that we have this member in Pokemon
```java=
private int id;
```
Then we can implement an equals method in the Pokemon class
```java=
public boolean equals(Pokemon other){
return this.id == other.getID();
}
```
The method equals() always returns a boolean and always is going to have at least one object as a parameter.
There is a static version
```java=
public static boolean equals(Pokemon pokemon1, Pokemon pokemon2) {
return pokemon1.getID() == pokemon2.getID();
}
```
Sometimes these equals methods can get complicated. For example let's say that we have a dot (or a position) in 3 dimensions
```java=
public class Dot {
private int x;
private int y;
private int z;
//all getters, setters and constructs
}
```
The equals method would look like this:
```java=
public boolean equals(Dot other){
return this.x == other.getX() &&
this.y == other.getY() &&
this.z == other.getZ();
}
```
## To String method
# HL extension
## Linked list of pokemon
### Using a LinkedList
Using a linked list:
Remember that a linked list have their methods and here you have the reference to state how to
### Distinguish between an array, an arraylist and a linked list
You _should_ have an idea of the difference between a linked list and an array but let's go more specific in Java.
They may have different implementations in different programming languages. Let's check out the docs.
### Implementing a LinkedList
//TO-DO
```java=
public class PokemonNode {
//pointer
private PokemonNode next;
//payload
private Pokemon data;
//try to include the scheme of pointers
//Constructor
public PokemonNode (Pokemon data) {
this.data = data;
}
//accessors
public Pokemon getData(){
return this.data;
}
public PokemonNode getNext() {
return this.next;
}
//mutator
public void setNext(PokemonNode next) {
this.next = next;
}
//we don't mutate the payload.
}
```
:::info
We don't change the payload because **encapsulation**. The idea is that if we are going to change the payload, we would change the node itself.
:::
```java=
public class PokemonLList {
PokemonNode head;
/*
* This method adds a new element at the end of the list. O(n)
*/
public void append(Pokemon data) {
if (head == null) {
head = new PokemonNode(data);
return;
}
PokemonNode current = head;
//Here we traverse the linked list until the end.
while (current.getNext()!= null) {
current = current.getNext();
}
current.setNext(new PokemonNode(data));
}
/*
*This method adds a new element at the beggining of the list O(1)
*/
public void prepend(Pokemon data) {
PokemonNode newHead = new PokemonNode(data);
newHead.setNext(this.head); //this keyword is not mandatory but it's useful to remember that we're talking about a instance variable
this.head = newHead;
}
/*
* First implementation of isEmpty
*/
public boolean isEmpty(){
if (this.head == null){
return true;
}
return false;
}
/*
* Second implementation of isEmpty
*/
public boolean isEmpty(){
return this.head == null;
}
/*
* This method finds a specific pokemon and deletes the first instance that is the same.
*
*/
public void deleteWithValue(Pokemon data) {
if (this.isEmpty()) {
return;
}
PokemonNode current = this.head; //remember that the class of this is PokemonNode, not Pokemon
if (current.getData() == data){
this.head = current.getNext();
}
while (current.getNext().getNext()!=null && current.getNext().getData() != data) {
current= current.getNext();
}
//check if we arrive to the end and we didn't found the pokemon reference
if (current.getNext().getData() != data) {
return;
}
//delete node
//case that it was the last node
if (current.getNext().getNext()==null){
current.setNext() = null;
}
else {
current.setNext = current.getNext().getNext();
}
}
/*
* This method finds a specific pokemon and deletes the first instance that has the same name.
*
*/
public void deleteWithName(String name) {
if (this.isEmpty()) {
return;
}
PokemonNode current = this.head; //remember that the class of this is PokemonNode, not Pokemon
if (current.getData().getName().equals(name)){
this.head = current.getNext();
}
while (current.getNext().getNext()!=null && !current.getNext().getData().getName().equals(name)) {
current= current.getNext();
}
//check if we arrive to the end and we didn't found the pokemon reference
if (!current.getNext().getData().getName().equals(name)) {
return;
}
//delete node
//case that it was the last node
if (current.getNext().getNext()==null){
current.setNext() = null;
}
else {
current.setNext = current.getNext().getNext();
}
}
}
```
## Binary tree of pokemon
## Stack of Pokemon
## Other questions
### Object reference
### Why use coding style and naming conventions