owned this note
owned this note
Published
Linked with GitHub
# Object Oriented Programming concepts
## What is Object Oriented Programming
The idea of making programs using objects.
Is a paradigm of using objects to divide big projects of code.
The opposite would be the paradigm of functional programming (there are other paradigms also). Functional programming divides the code into different functions.
## What is an object?
An object is a block of code that includes
* Name (or identifier)
* Attributes (data/variables)
* Actions (functions/subprograms/methods)
Another definition (from the book p.291)
:::success
An _object_ is an _abstract entity_ that describes the data this entity has (propierties, varialbes, attributes, members) and the actions this entity can perform (methods, functions)
:::
:::info
What is the difference between a method and an object?
Functions don't have attributes (they can have local variables or parameters but is a different concept)
:::
### Differences between attribute/parameter/local variable
When we instanciate an object (create a vehicle or a goomba) we usually are going to initialize the variables (attributes) that are inside the object that will be in memory for the life of the object.
When we have a local variable the life of that variable is only the local block (usually a methhod) where is executed. We don't have access to it afterwards.
Parameters are variables that are inputed into methods (they are from outside that method)
## Why using OOP?
OOP is not perfect but what it aims is to create **modularity**
### Modularity

_modulor by Le Corbusier_

_Lego Bricks_
Modularity is the concept of dividing the code (the program) into modules so each of the modules can be re-used in other projects and also can be worked on parallel.
This doesn't mean that the code itself is more efficient in doing its job! It means that can be more efficient to divide the task into teams or reuse code.
This is done using not only OOP but also the concept of **encapsulation**
### Encapsulation

One way to achieve the best modularity is by restricting the access to methods or variables that are in objects so only the objects themselves are in charge of changing those values or interact with them.
:::success
**Encapsulation** is the act of restrict the access to the variables or methods of an object to the rest of the code in order to have more control over its access.
:::
Why restrict?
The idea of restricting the access to the data of the object is to make the object itself responsible to change those values and validate them.
This makes it easier to find "who to blame" of doing or not doing something in the code. For example the object "Client" maybe should be responsible for checking if the email of the client corresponds to the structure of an email
This is an example:
https://www.baeldung.com/java-email-validation-regex
```java=
public void testUsingSimpleRegex() {
emailAddress = "username@domain.com";
regexPattern = "^(.+)@(\\S+)$";
assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
}
```
*Note: you're not supposed to know regular expressions (regex) for this course!*
So the idea is that the program will be easier to debug.
### Access modifiers
More on this here:
https://www.baeldung.com/java-access-modifiers
https://www.geeksforgeeks.org/access-modifiers-java/
We are going to work mainly with 2
* private: Only the class itself can access to it
* public: Every part of the code can access to it.
Here you have more information:

This modifier should be before each class/attribute/method
## Instanciation
(page 292)
The concept of instanciation is how we have "blueprints" and "instances".
Each of the instances has or may have different attributes.
For example if we're drawing we can have diffent circles, each of them with one radius and one center point.
So for creating these instances we need to, ehem, instanciate them as a variable with the object type. In this case for example
```java=
Circle circle1 = new Circle();
```
What does this mean?
```Circle``` is the Object type that we have access to (Circle.java)
```Circle1``` is the identifier of that object
```new``` is the keyword to call constructors
```Circle()``` is a special method of the class Circle called constructor that is going to be executed when we create this instance.
#### Example for explaining instances (car)
We may have the object Vehicle that has the attributes such as color, model, year and so on and then the different instances that will be specific vehicles that are a Volvo, a Mercedes, a Dacia or a Toyota

_generic car that doesn't have a particular color or specifics_

_three instances of Car that have particular specifics from the idea of car_
#### Example for explaining instances (circle)
If we have a program that creates circles we may use the object "Circle"

_inkscape tool of creating circle_
But then we might have different circles done in that program (for example here in processing)

https://www.youtube.com/watch?v=uopj9qLI4m0
Each of those circles are instances of the object Circle.
### What is a constructor method
A constructor method is a method inside an object that has the same name of the object (even with caps) and is going to be executed every time that that object is instanciated.
Is always void implicitly (indirectly) and it can have parameters.
We can have more than one constructor defined in one class using method overloading (concept for later)
The **default constructor** is the one that doesn't have parameters.
Example:
### Data that is static and dynamic
:::danger
This is a very important concept that they ask almost every year in the exam. Is usually confused with final (that is constant)
:::
A static method or static variable is a variable that is defined in the blueprint (in the class) of the object and it is shared by all the instances. There is no need to instanciate an object to access a public static method/attribute.
Example:
We have Circles

Circles can have a static attribute named "numberOfCircles" that is updated each time that we create (o destroy) a circle that just count how many instances we have in our program.
This variable is going to change over time (when we instanciate all the circles) but is shared by all the circles.
We can even call it if we didn't instanciate any circle in our program. Its value should be 0 (if everything works as intended).
In the same case we can have PI as a constant to calculate the area of those circles inside the object Circle. In this case we also don't need to have it 30 times if we have 30 circles and also we're not going to change it. So it will be ```final static double PI = 3.1415...;```
In the case of methods this is usually for methods that are independent from the instanciation. We can access them calling the class (with capital letter) and then the method.
For example:
```java
System.out.println();
```
Also very common in Math
```java
Math.random();
```
### The typical object in Java
The typical object in java is this template (Also can be called POJO, Plain Old Java Object)
```java=
public class MyObject { //MyObject goes with PascalCase
private int variable1; //names with camelCase
private boolean adjetive1;
private String variable2;
//all variables private by default
//only use static or final if we need to.
public MyObject() {
this.variable1 = 2; //default value
this.adjetive1 = true; //default value
this.variable2 = "default"; //default value
}
//constructor with no parameters and set default value
public MyObject(int x, boolean y, String z) {
this.variable1 = x; //input value
this.adjetive1 = y; //input value
this.variable2 = z; //input value
}
// getters and setters methods
// accessor and mutators methods
// accessors
public int getVariable1() {
return this.variable1;
}
public boolean isAdjective1(){
return this.adjetive1;
}
public String getVariable2() {
return this.variable2;
}
// mutators
public void setVariable1(int x) {
this.variable1 = x;
}
public void setAdjetive1(boolean newAdjective1) {
this.adjetive1 = newAdjective1;
}
public void setVariable2(String x) {
this.variable2 = x;
}
}
```
There are other methods that are a little bit more interesting but depend on the context and they may not be held into what is a POJO.
Some of them are
toString()
equalsTo() or equals()
### When we don't want to have an accessor or mutator
For example if we have one of our variables that is an array (or a list). If we allow access to that list or array that array can be changed without control, if we just create access to a specific element (given the index or the value) we have more control over the array.
Also we may restrict the methods that change names if this program is not going to actually change the name (or the ID) of some object/person.
### Instance methods (or dynamic methods)
The instance methods are those that depend on the specific instance that we are working on. If we have a car that has a drive (or accelerate or brake) is going to be depending on the specifics of one of the instances of the car simulation.
If we have move() in Circle is going to probably change the specific attributes of the circle that has been called.
### Example with Circle
```java=
public class Circle {
double radius;
String color;
double centerX;
double centerY;
Circle() { // the implementation of the contructor }
//accessor
public double getRadius() { return this.radius;}
public String getColor() { return this.color;}
public double getArea() {return this.radius*this.radius*Math.PI;}
public double getCenterX() {
return this.centerX;
}
public double getCenterY() {
return this.centerY;
}
//mutators
public void setRadius(double radius) {
this.radius = radius;
}
public void setColor(String color) {
this.color = color;
}
// "other"
public void move(double deltaX, double deltaY) {
this.centerX = this.centerX + deltaX;
this.centerY = this.centerY + deltaY;
}
}
```
Comments on this:
We have some variables and some accessors and mutators. Take note that we don't have a mutator method for centerX or centerY because for that we're using "move"
Also there is no mutator for Area because if you want to change the area of the circle you need to change the radius.
### Create instances
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3a_OOPBasics.html
(2.4)
To create an instance we need to do it in other part of the code. Usually we have in OOP 2 classes. The "main" class where we have the public static void main(String[] args) method and the class that we want to instanciate (that we want to play with)
In the one that we have the main method we need to call the other in this way:
* Declare an instance identifier (instance name) of a particular class.
* Construct the instance (i.e., allocate storage for the instance and initialize the instance) using the **"new"** operator.
For examples, suppose that we have a class called Circle, we can create instances of Circle as follows:
```java!
// Declare 3 instances of the class Circle, c1, c2, and c3
Circle c1, c2, c3; // They hold a special value called null
// Construct the instances via new operator
c1 = new Circle();
c2 = new Circle(2.0);
c3 = new Circle(3.0, "red");
// You can Declare and Construct in the same statement
Circle c4 = new Circle();
```
This is why is common to write something like
```java!
Potato potato = new Potato();
```
In this sentence the first Potato is the declaration of the type of the variable (the class Potato), then the name of that instance (that could be potato or patata o pomme de terre or картофел) and last the construction of the instance using the new statement.
Remember that constructors can have (or not) several parameters depending on the context. For example if we have a parking lot and we want to model the traffic incoming one of the elements that we do want to know to make an instance of a vehicle is its plate.

So we can make a constructor that asks for it and create an instance of Vehicle with its plate.
So if they ask you "write the code to instanciate a vehicle with the plate `2312351X`"
you have to answer
```java!
Vehicle v = new Vehicle("2312351X");
```
In this case it would be also valid if we change the name of the variable to something else:
```java!
Vehicle potato = new Vehicle("2312351X");
```
### Exercise (simple)
Use the example class Circle to create some instances
Circle class in the spoiler
:::spoiler
```java!
/**
* The Circle class models a circle with a radius and color.
*/
public class Circle { // Save as "Circle.java"
// private instance variable, not accessible from outside this class
private double radius;
private String color;
// Constructors (overloaded)
/** Constructs a Circle instance with default value for radius and color */
public Circle() { // 1st (default) constructor
radius = 1.0;
color = "red";
}
/** Constructs a Circle instance with the given radius and default color */
public Circle(double r) { // 2nd constructor
radius = r;
color = "red";
}
public Circle (double r, String c){
radius = r;
color = c;
}
/** Returns the radius */
public double getRadius() {
return radius;
}
/** Returns the area of this Circle instance */
public double getArea() {
return radius*radius*Math.PI;
}
}
```
:::
Create 5 instances.
* The first called circle1 should be a circle with the default parameters
* The second called c2 should be a circle with radius 5
* The third called c3 should be a circle with radius 10 and colour "green"
* The forth called colinRobinson should be a circle with radius -2 and color "greenish"
* The fifth called circle5 is a circle with the default radius but the color "blue"
Answer in the spoiler:
:::spoiler
```java!
Circle circle1 = new Circle();
Circle c2 = new Circle(5.0);
Circle c3 = new Circle(10.0, "green");
Circle colinRobinson = new Circle(-2.0, "greenish");
Circle circle5 = new Circle(1.0, "blue");
```
Comments:
This class doesn't have implemented any kind of validation so we can have this types of negative radius (see colinRobinson)
In the last one we don't have access to a constructor that has only a default radius and choose the color so we have to either hardcode the default radius or use a default circle and change the attribute of the colour.
:::
### Exercise of creating and implementing a class
In this exercise we're going to model something simple like a Book and we're going to implement the accessors and mutators.
The variables that we are going to set depend on the context. It's not the same a library that a bookstore or a physics simulation. In a bookstore the price is relevant, in a library (personal or communal) you might find interesting how many times has been lended that specific book. In a physics modelling system, we need to know the specifics of the size and the material of the book.
In this "generic" case we're going to use some of this data. You need to understand which types of primitive variables do we need. Later we might have other objects as variables.
So, exercise: **implement the variables that we need to have a title, author number of pages, ISBN (International Serial Book Number) and if is written in Korean.**

(source and explanation in Spanish about ISBN https://kitzalet.com/editorial-digital/que-es-el-isbn-de-un-libro/)
Solution in the spoiler
:::spoiler
```java!
public class Book {
private String title;
private String author;
private int pages; //can be also called numberOfPages
private String ISBN; //this could be also a double maybe but better be saved in a string because is a long number
private boolean inKorean;
}
```
:::
Here we have the attributes but we're missing the actions. For this we need a couple of constructors and also the accessors and mutators (getters and setters)
Let's **code a constructor method that has some default values, another that has one parameter, and other that has 2 parameters. **
Solution in the spoiler (with the rest of the class)
:::spoiler
```java!
public class Book {
private String title;
private String author;
private int pages; //can be also called numberOfPages
private String ISBN; //this could be also a double maybe but better be saved in a string because is a long number
private boolean inKorean;
public Book() {
this.title = "untitled";
this.author = "anonimous";
this.pages = 0;
this.ISBN = "none";
this.inKorean = false;
}
public Book (String title) {
this.title = title;
this.author = "anonimous";
this.pages = 0;
this.ISBN = "none";
this.inKorean = false;
}
public Book (String title, int numberOfPages) {
this.title = title;
this.author = "anonimous";
this.pages = numberOfPages;
this.ISBN = "none";
this.inKorean = false;
}
}
```
:::
We can add also a constructor that accepts all the parameters (title, author, pages, ISBN and if it's in Korean). **Implement a constructor that accespts all 5 attributes as parameters.**
Solution in the spoiler. In this case we don't have to write all the class for do the solution (great because the exam is _short_)
:::spoiler
```java!
public Book (String title, String author, int numberOfPages, String ISBN, boolean inKorean) {
this.title=title;
this.author=author;
this.pages=numberOfPages;
this.ISBN=ISBN;
this.inKorean=inKorean;
}
```
:::
Now that we have covered all the constructors (you could be asked to do a Constructor with 3 or 4 parameters also) we can move on on the next thing:
Implement the accessors and the mutators for Book
Solution on the spoiler:
:::spoiler
Accessors:
```java=
public String getTitle() {
return this.title;
}
public String getAuthor() {
return this.author;
}
public int getPages() {
return this.pages;
}
public String getISBN() {
return this;
}
public boolean isInKorean() {
//here instead of getInKorean we use
//isInKorean because makes more sense when reading
return this.inKorean;
}
```
Mutators:
```java=
public void setTitle(String title) {
this.title = title;
}
public void setAuthor(String author) {
this.author = author;
}
public void setPages(int pages) {
this.pages = pages;
}
public void setISBN(String ISBN) {
this.ISBN = ISBN;
}
public void setInKorean(boolean inKorean) {
this.inKorean = inKorean;
}
```
:::
### The dot operator
The dot operator allows us to acces to methods (actions) or members (also called attributes or variables) that we have access to. To do that we use the dot operator.
For example using the Circle class we can instanciate one circle and then get access to getArea to get the Area of the circle
```java!
Circle c1 = new Circle();
double area = c1.getArea();
```
**Rules:**
We can access to things that we have access to. If a variable is private we cannot access to it unless we are writing in that class (And we usually call it from other class).
For example if we're using myObject from before in an instance we cannot access the attributes directly
```java!
MyObject instance = new MyObject();
int x = instance.variable1; //this raises an error in compiling time because you don't have access to the variable directly
```
That's why we usually have accessor methods so we would write something like this
```java!
MyObject instance = new MyObject();
int x = instance.getVariable1();
```
This is why we usually change the name of the accessors for booleans so they are easier to see what's happening
For example with the previous book
```java!
Book book1 = new Book();
if (book1.isInKorean()) {
Translator.translateFromKorean(book1);
}
```
In this case we are going to translate from Korean if the book is in Korean.
## UML diagrams
To summarize the concepts that we have inside a class without writting all them down we use a UML (Unified Modelling Language) diagrams.
They are several types depending on the level of detail. Like maps they can be just an overview or get in a lot of detail.
If we want to do the UML diagram of one object we make a box and divide it into the three elements that an object has.
| Object name |
| -------- |
| Object attributes |
| Object actions |
I suggest use diagrams.net to do these kind of stuff or just writting them down.
Here we have the example of the UML diagram of the sample class "MyObject"

How do we write them? Using this scheme:

(source: https://icarus.cs.weber.edu/~dab/cs1410/textbook/9.Classes_And_Objects/uml.html)
There are different flavours of UML diagrams. For example, using the book notation this would be the UML diagram of MyObject

Both options are fine but choose your fighter

and be consistent with it
Example of the class Dog UML diagram.

_Credit: M.Z_
Exercise:
Do the UML diagram of Book.
## Different contexts in modelling
::: info
This is not something that the exam asks directly but I think that gives a lot of context and understanding to the student about **why do we have these variables and not others**.
:::
When we create programs we _model reality_. This sounds like _The Matrix_ or something from science fiction but... it's true. The difference from the program to enroll students into a school and _The Matrix_ is that the former only cares about _some_ information of the student.

_the Matrix modeling the whole reality_
Depending on the context, in our modelling we're going to model only relevant information for our system. If we want to enroll people in our school, for example, we don't need to know how much do they weight.
### Example with Book
There is an example with book and the information about it was given. In this case we're going to dive a little bit in different context that they will have for modelling a book.
In a bookstore we care about the price of the book and if it's in promotion. In a library, however we care if it's lended or not and probably we're going to store in each book a lending history so we know how many times was lended, to who and how long.
If we're publishers (editors) we might need to know what is the printCost and probably we can set if the book is actually published of it's not yet published.
In a videogame (Such as Skyrim, minecraft of book of hours) a book will need more information becuse the book usually has an actual place in the virtual world that the program need to know.
The result of these would be something like this
In a library
| Book |
| -------- |
| String: title |
|String: author|
|String: ISBN|
|String: genre|
|boolean: lended|
|Lending[]: lendingHistory|
|Library: location|
In a bookshop
| Book |
| -------- |
|String: title |
|String: author |
|String: ISBN |
|String: genre |
|double: price |
|boolean: promotion |
|String: section //section of the bookstore|
In minecraft
| Book |
| -------- |
|Point: position //Point is a class to store a position X,Y,Z and posibly the rotation|
|String: title|
|String: content|
|MinecraftUser: author |
|int: pages |
### Example with Car
In an authorized dealer (car shop)
| Car |
| -------- |
|double: price |
|boolean: promotion|
|String: brand|
|boolean: secondHand|
|String[]: extras |
|String: category|
|int: consumption|
|int: power|
|String: colour|
In a car workshop
| Car |
| -------- |
|String: plate //registration plate|
|Client: owner |
|String: problems|
|String: brand|
|String: model|
|String: dateOfArrival|
In a videogame (such as GTA 5)
| Car |
| -------- |
|String: plate |
|String: model |
|Point: place |
|int: spawnRate|
|long: value|
|int: healthPoints|
Exercise about the Car
Write some variables that would make sense to the Car object in the context of a program of a Parking Area
Exercise:
Think of a object (Suitcase, person, student) and at least three different contexts (programs that need info from the Suitcases, people, students) and create these schemes about the different variables that these objects should have and what are the **types** of those variables (remember that java is a highly typed programming language)
## Dependencies
More info:
https://www.geeksforgeeks.org/association-composition-aggregation-java/
In OOP different objects have different relationships between each other thes are the studs, the "boops" in the lego and how they interact.
There are three (main) ways to 2 objects to interact
* Association (A uses B)
* Aggregation (A has a B)
* Inheritance (A is a B)
:::info
There is no consensus between the difference between dependency and association. In some sources I've found that the association is a type of dependency and in others dependency is a type of association.
:::
### Association
_Also called dependency_
Association in dependency is that the class A uses B, usually a (public) method from B. It's the lightest way of communication between classes. It's represented by a dashed arrow

This is common for example when we have a static library like "Math"
Also in representing UML diagrams we put in top of the line "uses" because this is "usage" of one class to the other

Dependency as the other associations is **directional**. That means that if ClassA uses ClassB doesn't mean that _necessarely_ ClassB uses classA. ClassB can be independent from classA
### Aggregation
In aggregation we are a step foward between the 2 classes and one of them is part of the attributes of the other. When this happen we have Objects as attributes (_members_)

Aggregation, as dependecy
### Example with IMDB
A typical example when modeling Databases (DB) is when we have an object that refers to another. For example in IMDB if we have a title (that refers to a movie title usually) it has references to complex objects of people (names in the IMBD context) for each of the crew that has done the movie.
If we go to the movie Dune for example
https://www.imdb.com/title/tt1160419/

We can see that the crew doesn't only show their names but also their photos, and, if we click on them we can see more information on that person (in this case Oscar Isaac)
https://www.imdb.com/name/nm1209966

:::warning
Here "title" doesn't only store the title of a movie but all the information that you can see in the webpage.
:::

### Inheritance
Also called in java "extension" because we use "class A extends B"
## Multiplicities
When we have objects that aggregate between each other we can have different numbers of "how many objects in A has a B" the short table is this:
### Common multiplicities
| Number | Meaning |
| -------- | -------- |
| 1 | Exactly one |
| 0...1 | Zero or one |
| * | many |
| 0...* | zero to many |
| 1... * | 1 to many |
Example of 1 in Spanish ID (DNI). In this case a person can only have one DNI (ID) and an ID can only have one owner.

:::success
What could be the context of this example?
:::
Example of 0...1 is passport in Spain since passports in Spain are optional.

Also in this example the multiplicities are also directional, one person may not have a passport but all the passports have owners.
Example of many (\*) can be the products of a store.

In this case Store has Products but Product in this context doesn't have a Store (maybe because is implicit, depends on the design).
Example of 0 to many is almost all the elements that can be empty or have a lot of information for example when we have a library that can be empty or have a lot of Books.

An example of 1 to many is a store that saves the customer information including addresses to send to the customers. One costumer needs to have one address when they register but they can add more if they please.

Reference for multiplicities
https://www.umlboard.com/docs/relations/multiplicity/
## Possible extra work
* Finding out the working of methods like toString(), compare, equals
* Implement the class Triangle with different constructors template here:
:::spoiler
public class Triangle {
int p1x;
int p1y;
int p2x;
int p2y;
int p3x;
int p3y;
public Triangle(int p1x, int p1y, int p2x, int p2y, int p3x, int p3y) {
//code missing
}
public Triangle(int p1x, int p1y, double alpha, int side1, double beta, int side2) {
//code missing
}
public Triangle(int side1, int side2, int side3) {
//code missing
//in this case it will assume default values for the p1x and p1y, probably 0,0
}
}
:::
* Presentation about regular expressions and how to (briefly, try to understand it).
### Use case of a UML
In the exams they usually ask for a (or even 2) UML diagrams. There are 2 types of UML diagrams asked in the exam
1) The ones that only describe one class in detail. These need to have the 3 boxes with name, members(attributes) and methods with their + for public and - for private
2) The ones that only describes the relationships between classes. In these cases you need to understand what are the relationship between the classes and draw accordingly. I suggest to remember the 3 different arrows AND write also "uses" "has a" or "is a" to be super clear for the person who marks. Here an example of those

### Reference that I need to check
https://nirajrules.wordpress.com/2011/07/15/association-vs-dependency-vs-aggregation-vs-composition/
## Example of coding with filling an array
We have a department of an university that has a small library with book related to Necromancy, Alchemy or other Hidden Arts. We're using a model where each department has their own array of books. In this first iteration we're asuming that they only have one of each.
```JAVA!
public class Department
{
private String name;
private Book[] library;
//constructor, getters and setters (not setter and getter for library)
}
```
Here we have a simplified version of the class Book
```JAVA!
public class Book
{
private String title;
private String isbn;
//constructor, getters and setters
}
```
### addBook(Book b)
**Statement:**
In this case we're going to implement the method `` addBook(Book b)`` that will add a book in the first empty position of the array library and return the position (ie the index of the array) at which the book has been added. If it's not possible to fit the book into the library, then it should return -1.
**Working**
To do that first we need to work on the **signature** of the method. This is to have clear
a) the access of the method. By default the methods are **public** unless stated otherwise.
b) the return type (or if there is not): **int** (since is the index of an array or -1)
c) the name of the method: **addBook**
d) the parameters (if any) of the method: **Book b**
:::info
Remember that java is a highly typed programming language so even Book b are 2 words, it refers to only one parameter that is called "b" and the type of the parameter is Book.
:::
With that we can construct or method, the first line
First with the access modifier `public`, then the return type `int`, then the name of the method `addBook` and in the parenthesis the parameters (if any), in this case `Book b`
Altogether combined like a megazord looks like this
```java!
public int addBook(Book b)
```
Now we can work _inside_ the method. For that, usually we need to know **where** is this method written to know which things does it have access to.
In this case the hint is that we're working with the array `library` that we know that is held in the object Department.
Once we know we need to loop throug the array.
#### How to loop through an array in java
To loop trough an array in java is with a for loop.
```java!
int[] numbers = {2,3,6,4,558,14,2}; //sample array of ints
for (int i =0; i < numbers.length; i ++){
//do something with numbers[i] to have each element
}
```
So in this case need to add this loop it would look like this
```java!
public int addBook(Book b) {
for (int i = 0; i < library.length ;i ++) {
}
}
```
The next step is finding when we don't have a book in the library. For that we need to know the context of null pointer.
The `null` is a special value that is "the pointer that doesn't point anywhere" and refers usually to empty spaces in an array or a list or something that is not instanciated yet.
So if we want to know the first index on the array that is free we need to know the first element which value is `null`
:::info
**null** and 0 are not the same thing!
:::
To access the element of the library we need to write `library[i]`
```java!
public int addBook(Book b) {
for (int i = 0; i < library.length ;i ++) {
if (library[i] == null) {
}
}
}
```
:::info
We're not using here any getters to get the information because we're in that class so we don't need them! (so no getLibrary nor anything like that)
:::
```java!
public int addBook(Book b) {
for (int i = 0; i < library.length ;i ++) {
if (library[i] == null) {
}
}
}
```
Now we need to add the book and return the position of that book
To add the book we just update the variable with `library[i]=b;`
And return the index is returning the variable i. This will terminate the method.
```java!
public int addBook(Book b) {
for (int i = 0; i < library.length ;i ++) {
if (library[i] == null) {
library[i]=b;
return i;
}
}
}
```
To finish we need to do the option where the array (the library) is full.
In this case we don't need a flag variable because if we find an empty spot we're going to fill it. So if the for loop ends, it means that there is no space.
So the return -1 would need to happen after the for loop
**Result**
```java!
public int addBook(Book b) {
for (int i = 0; i < library.length ;i ++) {
if (library[i] == null) {
library[i]=b;
return i;
}
}
return -1;
}
```
### findBookByISBN
Statement:
In this case we're going to implement the method `` findBookByISBN(String isbn)`` that will find a book in array of the library of the deparment. If it finds something that has the ISBN is going to retrieve the object. If there is no fit, it's going to return null.
Working:
Finding **signature** of the method (in order)
A) access modifier: **public** (by default)
B) return type: **Book** (it returns the pointer of a Book, null can be also a special value for a Book)
C) name of the method: **findBookByISBN** (given)
D) parameters and types of them if any: 1 parameter: **String ISBN**
Alltogeher comes as:
```java!
public Book findBookByISBN(String isbn)
```
Now we have to iterate through the array so let's do the for loop
```java!
public Book findBookByISBN(String isbn){
for (int i = 0; i < library.length ;i ++) {
}
}
```
In this case we need to check if the book itself has the correct ISBN to acces to that ISBN we need to use the getter from that specific book.
To access the specific book in the array (the ith element) we use `library[i]`, for accessing a method of the instance of that book we use the *dot operator* and we write `library[i].getISBN()` that is going to return the string of the ISBN.
So the condition would be `if(library[i].getISBN() == isbn)` since the isbn that we have as an input is called just isbn (is the isbn in `public Book findBookByISBN(String isbn)`)
so we have something like this:
```java!
public Book findBookByISBN(String isbn){
for (int i = 0; i < library.length ;i ++) {
if(library[i].getISBN() == isbn) {
}
}
}
```
The proper way though is using the **equals** method
```java!
public Book findBookByISBN(String isbn){
for (int i = 0; i < library.length ;i ++) {
if(library[i].getISBN().equals(isbn)) {
}
}
}
```
Also this one would work since the equals method has to be commutative.
```java!
public Book findBookByISBN(String isbn){
for (int i = 0; i < library.length ;i ++) {
if(isbn.equals(library[i].getISBN())) {
}
}
}
```
### The equals method
_more info here: https://hackmd.io/zfx3YkE9QD6-lnNz42kkbQ?view#Consecuences-of-referencing-and-objects-When-are-2-objects-equal_
*inhale*
**equals()** method:
In java objects (including strings) are usually reference (actually they are called reference variables) to other elements and in the case of strings they can be generated as a 'value' (`String a = "potato"`) or as a reference(pointer) to a value (`String b = new String("potato")`). If we compare values with the reference we're not going to have the expected result even if want to.
So for "good practice" in java we usually work with the method equals for anything that is an object and not a primitive.
Sometimes part of the marks is by using this method properly
More info here:
https://www.geeksforgeeks.org/difference-between-and-equals-method-in-java/
How to use it?
access the variable and then with the dot operator call the method equals and send as a parameter the object that you want to compare with.
```java!
String a = "potato";
a.equals("tomato"); //false
String b = new String ("tabacco");
b.equals(a); //also false
```
Here the full program from geeks for geeks with the options of comparasion
```java!
// Java program to understand
// the concept of == operator
public class Test {
public static void main(String[] args)
{
String s1 = "HELLO";
String s2 = "HELLO";
String s3 = new String("HELLO");
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false
System.out.println(s1.equals(s2)); // true
System.out.println(s1.equals(s3)); // true
}
}
//source https://www.geeksforgeeks.org/difference-between-and-equals-method-in-java/
```
:::success
*TL; DR:*
If it's not a primitive, better compare using equals() method
:::
Back to the show. We're with this:
```java!
public Book findBookByISBN(String isbn){
for (int i = 0; i < library.length ;i ++) {
if(library[i].getISBN().equals(isbn)) {
}
}
}
```
Now the statement told us that we have to return the reference of that book and else we return null. So let's add those 2 returns. First the return in the case that we find the book with that ISBN:
```java!
public Book findBookByISBN(String isbn){
for (int i = 0; i < library.length ;i ++) {
if(library[i].getISBN().equals(isbn)) {
return library[i];
}
}
}
```
Since return statement is going to *terminate* the method, we can write the other return just after the for loop because that means that we haven't found the book with that ISBN. We only have to write `return null`
**Result**
```java!
public Book findBookByISBN(String isbn){
for (int i = 0; i < library.length ;i ++) {
if(library[i].getISBN().equals(isbn)) {
return library[i];
}
}
return null;
}
```
### Exercise: findBookByTitle
Do the same thing but finding the book by title. We're assuming that titles don't repeat themselves.
**Statement**
Construct the method findBookByTitle (String title) that will return the reference of the first book that is in the library that has the same title. It will return null if there was no book with that title.
Solution in the spoiler
:::spoiler

_credit J.A_
:::
### Exercise: findAuthorInLibrary
In this case we're going to implement the method `` findAuthorInLibrary`` that will find a book in array of the library of the deparment with the author as a parameter. If it finds something that has the author is going to return true, if not it's going to return false.
```java!
public boolean findAuthorInLibrary (String author){
for (int i = 0; i < library.length ;i ++) {
if (library[i].getAuthor().equals(author))){
return true;
}
}
return false;
}
```
### Exercise: findStartingAuthor
:::success
The IB likes to do this kind of thing of introduce a method, how it works and then make the student use the method described. This is one example of this.
:::
In this case we're going to get introduced to a method that you will need to use in the final method.
In this case startsWith(string test) is a method that will return true if the string starts with that test string and false otherwise.
```java!
String myStr = "Hello";
System.out.println(myStr.startsWith("Hel")); // true
System.out.println(myStr.startsWith("llo")); // false
System.out.println(myStr.startsWith("o")); // false
```
_reference: https://www.w3schools.com/java/ref_string_startswith.asp_
`findStartingAuthor` is a method that is going to return if there is at least one book with the name or the start of the name that you wrote as a parameter.
You should use the method startsWith in your solution.
:::warning
Remember that you don't need to **implement** the method startsWith, you only need to **use** it
:::
Soolution after the spoilers
:::spoiler
```java=
public boolean StartsWithAuthor(String au){
for (int=0; int < library.length; i++){
if (library[i].getAuthor().startsWith(au)){
return true;
}
}
return false;
}
```
_credit K.B._
:::
## Another context. The retailers
A company that sells cars is using an OOP approach creating a program to manage its administration.
We have the class SalesPerson
```java!
class SalesPerson // each object contains details of one salesperson
{
private String name;
private String id;
private Sales[] salesHistory; // details of the different sales
private int count = 0; // number of sales made
//constructor for a new salesperson
public SalesPerson(String id)
{
// code missing
}
// constructor for a salesperson transferred (together with
// their sales details) from another branch
public SalesPerson(String id, Sales[] s, int c)
{
// code missing
}
public int getCount(){return count;}
public String getId() {return id;}
public void setSalesHistory(Sales s)
{
salesHistory[count] = s;
count = count +1;
}
public double calcTotalSales() // calculates total sales for the
// salesperson
{
}
public Sales largestSale() // calculates the sale with the largest
// value
{
// code missing
}
}
```
Then we have the object Sale
```java!
public class Sale {
private int productCode;
private double quantity;
private double price;
//constructor, accessors and mutators not shown
}
```
### Find the largest x in an array
**Statement**
Construct the code that implements the method *largestSale*, a method that returns the Sale objects that was the largest sale. To be the biggest sale has to be the more amount of money transfered.
**Process**
:::info
We have covered already in arrays how to find a maximum. The idea is
a) set the first as the maximum
b) iterate through the array with a loop
c) in that loop check if the conditions to change the maximum changes
d) in that case, update the maximum and/or the maximum index (this depends on context)
e) after the loop act accordingly to the context (output, return, etc)
:::
First remember that we need to know the **context** of the method. Where it's written. *Look into the statement and the context*. This is important to know what other elements do we have access to.
In this case the method *largestSale* is in the object SalesPerson.
The next thing is to know where do we have to iterate through. In this case we have to iterate through an array of *sales*, then name of that array is *salesHistory*. A variable that is in SalesPerson.
With this information we can start writing. First the method itself
```java!
//written in SalesPerson
public Sales largestSale() {
}
```
The step a is to define the maximum as the first element. The array has a first element that we can access trough 0
```java!
//written in SalesPerson
public Sales largestSale() {
Sale maxSale = salesHistory[0];
int maxSaleIndex = 0;
}
```
Do we need to also store the index? Depending on the context. If you only need the value, we don't need the index. But if you need either the order or the object itself we actually need it because is what we want to return.
The next step is to make the iteration through the array. From what I saw they are 2 types of arrays in IB exams. The arrays that have a counter and the arrays that don't have a counter.
To know it we need to look into the context. The name of the variable should be to count how many elements do we have. Remember that the name can be "counter" or can be "totalSales" or something different but they have the same purpose.
```java!
//written in SalesPerson
public Sales largestSale() {
Sale maxSale = salesHistory[0];
int maxSaleIndex = 0;
for(int i=0; i<counter; i++){
}
}
```
:::info
If we did't have a counter, the loop would look like this using length.
```java!
//written in SalesPerson
public Sales largestSale() {
Sale maxSale = salesHistory[0];
int maxSaleIndex = 0;
for(int i=0; i<salesHistory.length; i++){
}
}
```
:::
The next step is to calculate how much is the sale. So we need to do calculations with the elements that are inside Sale. How do we do it? We need to find this information in the object Sales. The members (the data) that we have is productCode, quantity and price. To calculate the sale we need to multiply quantity and price.
We use double here because quantity and price are doubles already.
```java!
//written in SalesPerson
public Sales largestSale() {
Sale maxSale = salesHistory[0];
int maxSaleIndex = 0;
for(int i=0; i<counter; i++){
double currentSaleTotal = salesHistory[i].getQuantity() * salesHistory[i].getPrice();
}
}
```
Now we compare the currentSaleTotal with the maxSale total in an if. If the current is bigger, it will mean that we need to change the maximum.
```java!
//written in SalesPerson
public Sales largestSale() {
Sale maxSale = salesHistory[0];
int maxSaleIndex = 0;
for(int i=0; i<counter; i++){
double currentSaleTotal = salesHistory[i].getQuantity() * salesHistory[i].getPrice();
if (currentSaleTotal > maxSale.getQuantity() *maxSale.getPrice()) {
maxSale = salesHistory[i];
maxSaleIndex = i;
}
}
}
```
Then after the loop we have to return (because the statment says so) the Sale that was the biggest.
```java!
//written in SalesPerson
public Sales largestSale() {
Sale maxSale = salesHistory[0];
int maxSaleIndex = 0;
for(int i=0; i<counter; i++){
double currentSaleTotal = salesHistory[i].getQuantity() * salesHistory[i].getPrice();
if (currentSaleTotal > maxSale.getQuantity() *maxSale.getPrice()) {
maxSale = salesHistory[i];
maxSaleIndex = i;
}
}
return maxSale;
}
```
In this case we don't need the maxSaleIndex AND the max sale. This one works also.
```java!
//written in SalesPerson
public Sales largestSale() {
Sale maxSale = salesHistory[0];
for(int i=0; i<counter; i++){
double currentSaleTotal = salesHistory[i].getQuantity() * salesHistory[i].getPrice();
if (currentSaleTotal > maxSale.getQuantity() *maxSale.getPrice()) {
maxSale = salesHistory[i];
}
}
return maxSale;
}
```
Another version
```java!
//written in SalesPerson
public Sales largestSale() {
Sale maxSaleI = 0;
for(int i=1; i<counter; i++){
double currentSaleTotal = salesHistory[i].getQuantity() * salesHistory[i].getPrice();
if (currentSaleTotal > salesHistory[maxSaleI].getQuantity() *salesHistory[maxSaleI].getPrice()) {
maxSaleI = i;
}
}
return salesHistory[maxSaleI];
}
```
#### Exercise. The most amount of products
**Statement**
Construct the code for the method "productMostSoldAtOnce" that finds the sale that had most elements of sold in one sale (quantity) and returns the productCode of that sale.
**Solution**
:::spoiler
```java=
public int productMostSoldAtOnce(){
double max = salesHistory[0].getQuantity();
int MSI= 0;
for (int i = 1; i<salesHistory.lenth; i++){
if max<salesHistory[i].getQuantity(){
max = salesHistory[i].getQuantity();
MSI=i;
}
}
return salesHistory[MSI].getproductCode();
}
:::
## Features
If we want to summarize the **features** of OOP we can go with
* Encapsulation. (already discussed) This enhances modularity.
* Inheritance. Allows new classes to be derived from an existing class. So we can save time. (has it's nuances, though)
* Polymorphism (method overload)
### Polymorphism (method overload)
In a class we can define more than one method with the same **name**. But to distinguish from one method from other, they need to have different parameters.
Classic example 1:
If we have the class Calculator we can have a mehtod `public double multiply(double a, double b)`, and a method to multiply 3 numbers `public double multiply(double a, double b, double c)` or even an array `public double multiply(double[] array)`.
:::warning
Remember that here we're talking about the **signature** of the method, not the **implementation**
:::
The compiler would tell which one to use from how many parameters (and types are send to the method)
#### Advantages of polymorphism
* Same name but diffent parameter list
* We can have unique actions in subclasses (child classes)
* Provides *decoupling*. We can have a common interfce and hides the implementation.
### Adavantadges of inheritance:
#### Lexicon of inheritance
Using this context of UML diagrams

In this context the dependency of Person and Professor (or student) is _inheritance_ and also, like all the dependencies is directional. All Professor instances are Person but not the other way around. Person is called the **parent class** and Professor the **child class**.
Another name to the child class is *subclass*.
Also we can say that class Professor *extends* the class Person. It's also what we have to write in java to mark this.
```java!
public class Professor extends Person {
private int salary;
// constructor not written
public int getSalary() {
return this.salary;
}
public void setSalary(int salary){
this.salary = salary;
}
}
```
(page 315)
* Extensibility. We can add new data or actions that doesn't exist in the parent class. In the case of Professor we can implement new methods "giveClass()" that doesn't exist in the parent class (Person).
* Reusability. This means that child classes can use private methods and elements from parent classes.
In the example of Professor we can write in a Main class this code
```java!
Professor professor = new Professor(/*Parameters */);
professor.getName(); //this will return a name
```
The method getName works even if we didn't define it in Professor because already exists.
* Information hiding
We can state in the parent class what are the methods available to the child classes.
* Overriding of actions
In some cases we can also override methods from the parent class. The example is with Animals

In this context a animal can Sound but a Dog and a Parrot will sound differently. They can have _different implementations_ of the method sound.
Reference:
https://www.w3schools.in/java/method-overriding
### Method signature
Method signature is the combination of
2) name
3) list of parameters (with types)

In this example with this snippet (snippet is a small fragment of code)
```java=
public boolean StartsWithAuthor(String au){
for (int=0; int < library.length; i++){
if (library[i].getAuthor().startsWith(au)){
return true;
}
}
return false;
}
```
the method signature would be:
```java!
StartsWithAuthor(String au)
```
:::warning
In some other contexts signature of a method is informally called to all the line of the _definition_ of a function (so it includes the return type, access modifier and such). But for this purpose this is **not** what we have to rlearn.
:::
### Implementation of a method
The implementation of a method is what is written between the curly braces `{}`
In the last example it would be
```java=
for (int=0; int < library.length; i++){
if (library[i].getAuthor().startsWith(au)){
return true;
}
}
return false;
```
## Disadvandages of OOP
OOP is very complex. For fast prototyping is way too much. It increases complexity so is usually better suited for long projects.
## Example of adding elements in an array
We are in a context of Department and Book
## Recipee example
### Construct the basics of a POJO
:::info
Remember that a POJO is a Plain Old Java Object, an object with attributes, accessors, mutators and the constructor
:::
One example is that given some context you need to create the classes, the accessors, the constructor and the mutators.
This is the context
We have a cooking application that models recipes. In order to do that, we are using 2 classes.
The class Recipe has the following variables:
+ `minutesToPrepare`, a variable that stores how many minutes need the recipee to be prepared
+ `instructions`, a chain of charactes that holds the (short) instructions for the recipee
+ `name` that holds the name of the recipe
+ `ingredients` that holds several objects of the type Ingredient, up to 25.
+ `numberOfIngredients` a number that holds how many ingredients has the particular recipee.
The class Ingredient has the following variables
+ `name` that holds the name of the ingredient
+ `quantity` a number that holds the quantity that is necessary for that particular recipee
+ `units` a name of the units of the quantity because it can be in mililiters or grams.
+ `vegan` a variable that can specify if the specific ingredient is vegan or not.
These 2 classes also have one constructor each. In the case of Recipe it's going to ask for the minutesToPrepare, the name and the instructions. In the case of Ingredient it's going to ask for the 4 attributes.
Construct both classes with their constructors, accessor methods and mutator methods.
Solution
:::spoiler
Recipe
```java=
public class Recipe {
//start with the attributes
private int minutesToPrepare;
private String name;
private int numberOfIngredients;
private Ingredient[] ingredients = new Ingredient[25];
// why the brackets: because it's an array
// why not String[]: because the statement says that is a object of the type Ingredient
// why the initialization: because it has to be up to 25 (also in the statment)
private String instructions;
//constructor
public Recipe(String name, int minutesToPrepare, String instructions)
{
//why this 3 parametes: because the statement says so
this.name = name;
this.minutesToPrepare = minutesToPrepare;
this.instructions = instructions;
//why the use of this keyword?
//because we need to differenciate the instance attribute and the parameter variable.
}
//accessors
public String getName(){
return this.name;
}
public int getMinutesToPrepare(){
return this.minutesToPrepare;
}
public String getInstructions(){
return this.instructions;
}
public int getNumberOfIngredients(){
return this.numberOfIngredients;
}
public Ingredient[] getIngredients() {
return this.ingredients;
}
//mutators
public void setName(String i){
this.name = i;
}
public void setMinutesToPrepare(int y) {
this.minutesToPrepare = y;
}
public void setInstructions(int z) {
this.instructions = z;
}
public void setNumberOfIngredients(int numberOfIngredients){
this.numberOfIngredients = numberOfIngredients;
}
}
```
Ingredient
_credit M.Z and K.B._
```java=
public class Ingredient {
private String name;
private int quantity;
private String units;
private boolean vegan;
public Ingredient(String name, double quantity, String units, boolean vegan) {
this.name = name;
this.quantity = quantity;
this.units = units;
this.vegan = vegan;
}
public String getName() {
return name;
}
public double getQuantity() {
return quantity;
}
public String getUnits() {
return units;
}
public boolean isVegan() {
return vegan;
}
//mutators Setters
public void setName(String name){
this.name = name;
}
public void setQuantity(int y) {
this.quantity = y;
}
public void setUnits(String z) {
this.units = z;
}
public void setVegan(Boolean w) {
this.vegan = w;
}
```
:::
:::warning
Usually in the exams these solutions with arrays don't allow other classes to access to the array directly, they use a couple of methods that in this case would be getIngredient (in singular) and addIngredient.
:::
### Construct method that evaluates the whole object
Let's have a method in the class Recipe that is going to return if that recipe is vegan or not.
Construct a method isVegan in the class Recipe that is going to return if the recipe is vegan or not.
Solution:
:::spoiler
```java=
public boolean isVegan() {
boolean vegan = true;
for (int x = 0; x < this.numberOfIngredients; x++){
if (this.Ingredients[x].isVegan()==false) {
vegan = false;
break;
}
}
return vegan;
}
```
:::
## Algorithms that you need to know how to implement in java
(From Paper1 topic 4)
### Binary search
//TO-DO by the students
### Bubble sort
Let's say that we have a couple of POJOs, one is Car and the othere is Parking. Parking has an array of Cars and for some reason we want to order them by... plate (that it's a String) using a method called "sortCars()" implemented in the Parking class.
```java=
public void sortCars(){
//in this case I guess that the array of cars has the original name of cars
for (int i = 0; i< cars.length -1; i++) {
for (int j = i; j < cars.length; j ++){
//check adjacent
if (cars[j].getPlate() > cars[j+1].getPlate()) {
//swap
Car temp = cars[j];
cars[j] = cars [j+1];
cars[j+1] = temp;
}
}
}
}
```
### Selection sort
//TO-DO by the students