Java For Humans-Learn To Code Life
Java For Humans-Learn To Code Life
1
2
Dedication
3
4
Java for Humans
ModernNerd
Teaching coding in more
human relatable ways.
5
Java for Humans
Contents
Dedication ………………………..………..............................
………………………..………... 3
Preface ….………………………..………..............................
………………………..……….... 8
About the Author ………………………..
………..............................………………... 9
Motivation ………………………..
………..............................………………………... 9
Audience ………………………..
………..............................………………….. 9
Learning Goals ...……...................................
………………………..………..... 9
Overlying Project ………………………..
………..............................……….. 10
Contents
Dedication ………………………..………..............................
………………………..………... 3
Preface ….………………………..………..............................
………………………..……….... 8
About the Author ………………………..
………..............................………………... 9
Motivation ………………………..
………..............................………………………... 9
Audience ………………………..
………..............................………………….. 9
Learning Goals ...……...................................
………………………..………..... 9
Overlying Project ………………………..
………..............................……….. 10
Preface
String author = "Lincoln W Daniel";
String bookTitle = "Java for Humans";
System.out.printf("Hello, World! My name is %s,
author of %s.", author, bookTitle);
Motivation
Audience
Who is this book for? For the beginner who has never
heard of Java before today, this book will get you started on
the road to building your first Java application by walking
you through the essential components step by step.
For those who have dipped their toes in a little bit but
are feeling the coding life is a little too cold for them, too
unlike what they are use to, or simply too boring to
continue learning, this book is here to slowly pull you in
deep. Java for Humans will help you relate coding to your
life experiences so you don't feel lost. Your current
knowledge will be reinforced through clearer and more
thorough explanations.
10
Introduction
Chapter 1
Introduction
About Java
Put simply, Java, named after coffee, runs the world. There
are more than three billion devices running Java today,
according to Oracle. This is only possible because Java is a
portable language thanks to the Java Virtual Machine
(JVM). The JVM allows Java developers to write code and
compile it on one platform and run it on many other
platforms unlike other languages. This has allowed Java to
become a powerhouse in the programming world. Google
caught on to this and swiftly made Java the language that
runs your Android phone. Java is in everything and you've
been using it since you were surfing the web in the good ole
America Online dial up internet days.
Java for Humans will help you learn how to build the
cool tools you use everyday. With knowledge of
programming in Java, you can start building Android
applications and games for phones, televisions, and tablets.
Furthermore, not only will you be able to build with Java,
you will be better prepared to learn more programming
languages to increase the range of applications you can
build from car to drone software.
11
If you need more motivation to learn Java, read the
Applying Knowledge chapter to learn more about what
you can do with Java, how much you stand to gain from
being a Java programmer, and how Java for Humans can get
you started on the path to a promising career in Java
software development.
Supporting Code
Side Notes
12
Note!
This is a side note which explains an aside. An aside is used to
indicate that one is shifting from one topic or tone of discussion
to another.
Inline Code
Learning to Read and
Write
Chapter 2
Learning to Read and Write
Variables
Datatypes
int id = 1234567828;
double balance = 1301.41;
int passCode = 9889;
boolean isActive = true;
String ownerName = "Lincoln W Daniel";
String ownerAddress = "325 JavaPlace,
UnitedJavas 19081";
int ownerBirthYear = 1993;
String ownerBirthMonth = "May";
int ownerBirthDay = 26;
16 Output
Our account's balance: $1301.41
Now we have our bank account and all of it’s data is stored
in variables with their appropriate datatypes. Given our
new setup, we can manipulate parts of our account more
easily without having to deal with parts we don’t want to.
The bank teller can find our account by looking up it’s id,
which is 123456782, and ask us to verify the ownerBirthday
on the account to make sure we are the owner of the
account before telling us our balance. Later we can go to
the ATM use our passCode to view our account’s balance.
We can even change our balance by adding money to it or
taking money out.
Learning to Read and
Write
Comments
Multi-line Comments
Single line comments are great for commenting little bits of
code when there’s not much to explain. However, when you
write larger code, it’s best to use multi-line comments.
Multi-line comments allow you to write long comments
that can span for multiple lines by starting with “/*” and
ending with “*/”.
/*
While the user does not want to exit,
let them continue making transactions
on our ATM.
*/
while(!input.equalsIgnoreCase("EXIT")){
//let the user make transaction on our ATM
//then ask the user what they want to do
next.
System.out.println("Enter EXIT to exit or
another action");
//get user's input from scanner
input = scanner.nextLine();
}
Naming Conventions
Remember when you were in the first grade and you had to
write your first sentence? The teacher said your sentences
must include a subject and a verb. Earlier, she made sure to19
teach everyone what a subject is and what a verb is so that
she could later use it to communicate new ideas, like
sentences, with confidence that everyone would understand
her. At this point, she was able to tell you how to structure
your sentences:
“All sentences must start with a capital letter and end with
a punctuation.”
Class Naming
We'll only discuss the conventions for this one because as
far as we are concerned, other methods of naming classes
are evil and should be avoided. We haven’t talked much
about classes, but I will go over them more later. For now,
just know that when naming classes, you should use whole
words like in variables. However, class names should 21
employ upper camel case: the first letter of every word in
the name of a class should be capitalized. Take a class that
holds information and functions of a human for example.
We should name such a class Human because that is
descriptive of what the class is for and what kind of objects
can be created from it.Another class may hold information
and functions of a game character, say a fire archer; we
should name it FireArcher:
Method Naming
Java for Humans
Operators
Now that we understand how to make variables, the
different datatypes available to us in Java, and how to write
code others can understand, let’s try to manipulate some
data with Java operators.
Java Operators
Learning to Read and
Write
Additive
Additive operators enable us to do addition and subtraction
much like you learned in the first or second grade of school.
The only difference is you don’t have to do any of the hard
work like carrying numbers because Java does it for you.
You will often use the addition + operator to add numbers
or connect data and the subtraction - operator to subtract
numbers. Another use of the plus symbol is for
concatenating, or connecting, data:
Output
Lincoln Daniel has 110 fruits.
Multiplicative
Multiplicative operators let us do multiplication and
division on numbers like we learned after first grade. The
computer handles all of the long division and carrying for
us. You can make use of the multiplication * operator to
multiply and the division / operator to divide numbers:
Java for Humans
Equality Operators
We often want to know if two things are equal to or not
equal to one another. A classic example is checking if an
apple is equal to an orange. We can evaluate equality
relationships by use of Java’s equality operators: == lets us
check if two things are equal while != lets us check if two
things are not equal. Let’s try our apples and oranges
example by using numbers to represent the two:
int apple = 1;
int orange = 2;
Output
Apple does not equal orange: true
Relational Operators
Like in math, we can use relational operators to compare,
or gauge the relation between two data points in Java. We
can check if one data point is greater than or less than
another by using the> or < operators respectively:
int one = 1;
int two = 2;
int three = 3;
int twenty = 20;
Output
Two is less than or equal to one: false
Combining Operators
We can combine operators to make more powerful
operators, too. With combined operators, we can clean up
and optimize our code. We can increase or decrease the
value of a variable by doing the following: 25
int count = 0;
Others
There are a few others that are useful, but they require
more explanation than is within the scope of this chapter. In
later chapters, you will learn how to logically check
conditions of data by combining relational and equality
operators with logical operators in order to make decisions
with control flow statements (decision-making statements
and looping statements). These are powerful tools that
allow our code to do some things sometimes and other
things other times.
Learning by Googling
How to Google
Often, when you have a question, you simply visit Google
and type it in the same way it popped up in your mind:
That query may return some good results, but the results
will vary largely. If you want to make sure you get the
answer you want or get close enough, you need to provide
Google a bit more information. May be instead of the
previous wording of your query, you can try this:
Code Queries
Sometimes, you forget something when you are coding.
Sometimes you don’t know how to code something. Let’s
say you wanted to learn more about how to make variables.
You could ask Google the following query:
Use the minimal amount of words as you can and forget the
question mark. Google is smart enough to know that you
want results surrounding String variables in the Java
programming language. Now, let’s take a look at the results
returned.
Code Results
At its core, Google is a software company. They built a
good deal of the code bases that we all use today, so it
makes sense for them to understand that we want to get the
best code search results as possible. Aside from Google’s
possible bias towards good code results, so many people are
programming today that many of the questions you will
have will already be answered many times and discussed in
depth on forums like StackOverflow. With that said, let’s
digest the types of results you’ll receive and which are best
in particular situations.
In the case of Java, the official documentation will
come from Oracle.com. Oracle maintains the Java language
and has the final say on what is right or wrong. Although
these guys have the ultimate say on what is right, they don’t
have a good way of laying it out for beginners. It’s
organized well, but as a beginner, you may be a little
intimidated by its layout because it contains more jargon
than you may be comfortable with. Nonetheless, if you
want a definitive answer to your Java questions, Oracle’s
Java documentations is your best bet. This is the case for
28
any other language, too: the official documentations will
provide you the most accurate answers. If it’s accuracy you
seek, use this search result. If it is comprehension you care
for, forums like StackOverflow will serve you well.
StackOverflow.com is the most popular forum for
software development related discussions. On here, users
can ask questions and receive answers from other users.
Those answering questions, have likely ran into the issues
of the questions they answer and are experienced in the
fields of the questions. Moderators maintain the forum to
make sure people are asking relevant questions and
receiving the best answers. Users vote on the answers
Learning to Read and
Write
29
Java for Humans
Chapter 3
Learning to Classify Data
section.
The constructor has no explicit return type because it’s
a factory method, which means it creates a new instance of
the class and returns the new instance to the caller. The
constructor of a class must have the same name as the class
and is case sensitive. Finally, the constructor can accept
information from the caller as parameters that will be
assigned to the instance fields of the instance being created.
We can create a constructor for our Human class that asks
the caller to provide the name, age, and the height of the
new Human instance like so:
Instance Methods
Remember that nouns perform actions with verbs in
sentences and objects in Java programs perform actions by
use of their methods. A class defines methods any object
constructed from the class can perform. These methods are
referred to as instance methods because they can only be
performed by an instance of the class. We are all instances
of the Human class, so we share functionality, or methods.
We speak, run, jump, sleep, walk, wave, work, and so much
more. All of these actions are predefined by our human
biology and anatomy— our class.
The opening and closing curly braces define a scope:
the opening starts the scope and the closing ends it. Classes
and methods, among others, have scope, and the class scope
is the highest level scope in a class. While we can start new
method scopes in the class scope, we cannot start new
method scopes in a method’s scope.
We can add methods to our classes in Java by declaring
them between the opening and closing curly braces, or
scope, of the class. Let’s add a few methods to our Human
class to make our Human objects more functional:
Static Fields
Because static fields can be accessed without an instance of
the class, they are good means of storing information that is
universal to a class, such as a count of how many instances
of the class have been created. To make a static field, you
simply place the static keyword before the declaration of a
class’s member variable, or field:
Once that static field exists, you can access it from outside
or inside of the class without an instance of the class. When
accessing it, you can simply get or change its value as you
wish. The public modifier means that it can be accessed
from anywhere in your program that the class can be
accessed from. We will learn more about access modifiers
soon. Whenever we make a new instance of the Human
class, we could have the numHumans static fieldincreased
by one so that our whole program knows there’s a new
human in town to work with. Because the Human class is
public and so is the static field, any part of our program can
access that static field by doing the following:
The way we accessed the field from the class is called dot 35
notation, and we will learn more about this in the Dot
Notation section.
Static Methods
Classes have three main types of methods: the factory
(constructor) method, instance methods, and static
methods. A static method of a class can be called without
an instance of that class. As a result, static methods don’t
have any access to instance variables, or instance fields,
because instance variables store information about an
instance of a class. Likewise, static methods do not have
access to the this keyword in Java because this refers to the
Java for Humans
36
That will return the value of the static numHumans field in
the Human class and store it in the
localnumHumansInWorld variable for later use.
Output
There are now 1 Human instances in society.
There are now 2 Human instances in society.
Java for Humans
Decision-Making Statements
If-Then Statements
if(player1.passedGo()) {
player1.collect200Dollars();
}
//...
the next player gets to roll the dice, and the process repeats
until the game ends.
If-Then-Else Statements
If-then-else statements are a little more powerful than
simple if-thenstatements because they let us do things if a
condition is satisfied and other things otherwise. You can
think of it like so:
if this is true, then do that. Otherwise, do something else.
Let’s say we want to explore the Amazon rainforest. In
planning, we check the weather forecast to see if it will be
raining on the day we go. We only want to pack our
Java for Humans
Nesting Decisions
Java allows you to nest decision-statements to make
multiple decisions before doing something. Let’s take our
rain example from earlier for example. If it is raining
outside we want to use the umbrella. However, we only
want to use the umbrella if it is raining outside and we are
outside. We don’t want to use the umbrella if we are inside.
We can write this in code by using nested if statements.
The following code snippet demonstrates how we use
nested if statements to make decisions in sequence. First,
we check if it’s raining: if it’s not raining, that’s it, don’t use
the umbrella. If it is raining, we use another if statement to
40
if(haveHomework) {
activityToDo = "do homework";
} else if (haveChores) {
activityToDo = "wash dishes.";
} else if(friendsAreFreeToPlay) {
activityToDo = "go play with friends.";
} else {
if(haveTV) {
activityToDo = "watch favorite TV show.";
} else {
activityToDo = "do nothing";
}
}
Others
We have one more notable option for how we can make
decisions in Java. The switch statement is powerful and can
be used in special cases where you have many choices to
choose from and each choice leads to a different code
execution path. In some ways, the switch statement is an
optimized version of what I call the if-then-else if-then-else
statement. It is more of a matching statement than a
decision-making statement. This is something you should
research more because it can be handy in bigger projects as
you become more experienced.
42
Methods
/**
* Your code is executed in order,
* top to bottom, starting from here.
* @param args arguments the computer
* provides to this method when it calls it.
*/
public static void main(String[] args){
System.out.println("Hello, World!");
}
Java for Humans
Method Signature
First, we need to provide an access modifier to tell the
compiler that executes our code where our method can be
accessed from. Next, we need to say whether or not it’s
static; by default, methods are not static, so we can simply
omit the static keyword. After that, we need to tell the
compiler what kind of data, or the datatype, our method
returns; most of the time, this is either going to be a class
type or a primitive type, and other times we can return data
44
structures. Then, we need to give our method a lower camel
case name that is usually unique — you’ll learn when it’s
not unique later. Finally, we need to declare a list of
theparameters that must be provided to our method as
arguments when it’s called. When we provide all of that
information, we can start the body of our method with a
opening curly bracket { and end it with a closing closing
curly bracket }:
Method Parameters
Remember that methods are powerful in that they can
manipulate data available in our class or instances of our
class, but sometimes we need them to do more. Sometimes
they need some data from outside of our class or instances
of our class to complete the job. A good example of this is
when you are in gym class and the instructor asks you to
jump. Some people would start jumping mindlessly, but the
wise thing to do would be to ask the instructor how high he
wants you to jump and for how long. Next time the
instructor invokes, or calls, your jump method, he will
know he has to provide you a height to jump to and the
amount of time to continue jumping for. Soon, we will use45
that same idea to teach our new pet dog how to jump.
We can provide as many parameters as we want to our
methods, and when someone calls one of our methods, they
will have to pass in all of the parameters we require as
arguments. Our methods can then use the parameters as
variables in their body. It is often wise to check if the
parameter provided to our method is not empty by
checking that it’s notnull because users may misuse our
methods.
A null object is one that has no data in it and, therefore,
has no type. Such an object cannot be used. Consequently,
if we try to call a method on a null object, our program will
Java for Humans
id = ++numCoolDogs;
}
Note!
We have once again left some of the code out of this code snippet,
and that is denoted by the ellipses (…).
person.getPetDog().jump(10, 10);
Access Modifiers
Encapsulation in Java would not be as effective as it is
today without access modifiers. Access modifiers allow us
to decide how parts of our classes can be accessed by other
classes in other parts of our program. If we want a field or
method to be accessible from anywhere, by any class, we
can mark it as public. By default fields, method, and classes
are public to all other classes in their package. If we only
50
want a field or method in our class to be accessed from
within our class, we can mark them private.Finally, if we
want to explicitly constrain the access of a field or method
to subclasses of their class or other classes the same
package, we can mark them as protected. Nonetheless, as a
beginner, your focus is on public andprivate until you begin
building larger programs.
In Java, by default fields, method, and classes are
package-private, which means they cannot be accessed from
outside of their package. That is only the case when we do
not specify an access modifier. In this book, we only focus
on public, private, and protected but it would be good to
Learning to Classify
Data
52
Learning to Manipulate
Data
Chapter 4
Learning to Manipulate Data
As a kid, you may have played many games to fill your day
with some fun and excitement. In some cases, the most
exciting games may have been the ones that employed some
bit of randomness and unpredictability. Board games like
monopoly use a dice to create randomness in the outcome
of the game. The series of random numbers you roll
determine how successful you are in the game. Computer
games, on the other hand, don’t have access to a physical
dice, so there must be another way for them to create
randomness. For that reason, Java and other programming
languages have random number generators we can use to
create randomness in our programs.
Possible Output
Random whole number as int: -2131209878
Random whole number as long: 3349792078338628742
Random floating point number as double: 0.59413166337279
Random boolean: false
Another random whole number as int: 78474926
int randomIntWithBound =
randomNumberGenerator.nextInt(10);
Possible Output
I'm staying in.
Java for Humans
Possible Output
I'm going out!
Why
56 Loops are Important & Useful
Loops in Java allow us to repeat some of our code a fixed
number of times or so long as a condition remains true.
There are three basic forms of loops in Java, but we will
only be focusing on two of them here because they are
the most important and useful ones for beginners. We will
learn about the for statement and the whilestatement.
Both statements allow us to loop over blocks of code so
long as a condition is true, but they do so a little
differently from one another.
For Loop
The for statement allows us to loop over a block of code
Learning to Manipulate
Data
Output
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
Let’s take a look at the first line of the for loop and the
three parts necessary to make it work. There is an
initialization expression,termination expression, and a
increment expression in that order.
int count;
for(count = 4; count < 10; count++) {
System.out.print(count + " | ");
}
Output
4 | 5 | 6 | 7 | 8 | 9 |
The next number would be 10.
Note!
Although we named our initialization variable “count”, you will
usually see it named “i”, “j”, or “k” as a convention.
While Loop
The while statement is often referred to as the while loop
because it continually loops over and executes a block of
code statements while a given condition, or a set of
Learning to Manipulate
Data
int number = 0;
while(number < 10) {
System.out.println("Current number = " +
number);
//increment the number to move to the next
number++;
}
Output
Current number = 0
Current number = 1
Current number = 2
Current number = 3
Current number = 4
Current number = 5
Current number = 6
Current number = 7
Current number = 8
Current number = 9
Again, that may seem trivial, but imagine the things you
could do with loops. A loop may be used to keep your
television on until you push the “off” button. Think about
your microwave; much like a timer, it likely uses a loop to
continue heating up your food until the time you set runs
out. If you play video games, you may notice that the game
continues to run until you turn off your game console or
your computer. That’s a while loop at work:
Note!
Java for Humans
int numCookiesEaten = 0;
int cookiesNeededToBeFull = 10;
int numCookiesLeftInCookieJar = 8;
int numCompletedIterations = 0;
while(numCookiesEaten < cookiesNeededToBeFull)
{
numCookiesToEatThisTime =
randomCookiesGenerator
.nextInt(numCookiesLeftInCookieJar)
+ 1;
numCookiesEaten += numCookiesToEatThisTime;
numCookiesLeftInCookieJar -=
numCookiesToEatThisTime;
if(numCookiesLeftInCookieJar < 1) {
System.out.println("\n#No cookies left to
eat :(");
break;
}
Learning to Manipulate
Data
else {
System.out.println("> " +
numCookiesLeftInCookieJar + "
cookies left in jar");
}
System.out.println("Completed " +
numCompletedIterations + "
iterations.");
Output
< Eating 4 cookies this time.
> 4 cookies left in jar
< Eating 2 cookies this time.
> 2 cookies left in jar
< Eating 2 cookies this time.
There, you can see we need to eat ten cookies before we are
full, but there are only eight cookies in the cookie jar to eat.
During each iteration of the loop, we eat a random number
of cookies from the cookie jar. At the end of each iteration,
we increment the value of thenumCompletedIterations int
variable by one. At some point, we will definitely run out
of cookies to eat before our stomach is full. At that point,
we use the break keyword to break out of the loop.
Notice that after invoking break, we print how many
full iterations we made through the whileloop. It says we 61
only completed two iterations because on the third
iteration, we broke out of the loop before increasing the
value ofnumCompletedIterations a third time.
Play around with the supporting code and find other
ways to use the break statement with both the while and
for loops.
Java for Humans
String Manipulation
Comparing Strings
A operation you will run many times in your programs is a
operation to compare two String instances to one
another. If you have a Facebook account, you will be
62
asked for your username and password when you try to
log in. Behind the scenes, Facebook will compare the
username and password you provide to the username
and password they have stored in their database for your
account. If the comparisons are successful, you can log
in, but if they fail, you will have to try again.
The String class has convenient comparison instance
methods for us to compare two instances. We can use
equals() to compare two strings case sensitively or
equalsIgnoreCase() to compare without considering the
case of the strings. Both of these methods return a
boolean — true if the comparisons succeed and
Learning to Manipulate
Data
if(providedUsername.equalsIgnoreCase(usernameInDatabase))
{
//successful username comparison
//check the provided password
if(providedUsername.equalsIgnoreCase(usernameInDatabase))
{
//successful username comparison
//check the provided password
String alphabet =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int indexOfLetterD = alphabet.indexOf("D");
Output
Index of letter 'D' is 3
String alphabet =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int beginningOfTheEnd =
64
alphabet.indexOf("XYZ");
System.out.println("Value of
beginningOfTheEnd: " +
beginningOfTheEnd);
Output
Value of beginningOfTheEnd: 22
The letter “X” is the 24th letter in the alphabet, but it’s at
the 23rd index in the String instance. The substring “XYZ”
of the alphabet String instance starts with “X”, so that
substring begins at the 23rd index; that is what indexOf()
returns here.
Learning to Manipulate
Data
method:
String secondHalfOfAlphabet =
alphabet.substring(13);
System.out.println(secondHalfOfAlphabet);
Output
NOPQRSTUVWXYZ
String secondHalfOfAlphabet =
alphabet.substring(alphabet.length() / 2);
System.out.println(secondHalfOfAlphabet);
Output
NOPQRSTUVWXYZ
Now imagine your friend asks you for your street address
and city, but you only have the entire string of your house
address which contains the street address, city, state, zip
code, and country. You may not want to send her your
entire address because she only cares about your street
address and city. In this case, you would need to manipulate
the String containing your full address to get only the part
containing your street address and city and store it in a new
65
variable to send to her.
Knowing that the street address and the city come before
the comma in your full address, you can use the substring()
method along with the indexOf()method to get that part of
the string containing your street address:
Output
123 JavaStreet JavaCity
Output
Lowercase name: lincoln daniel
Uppercase name: LINCOLN DANIEL
66
Note!
Bonus: Figure out how to capitalize the string; only make the first
letter in a String uppercase. You may need to use the substring()
instance method.
String Replacement
Another useful tool provided to us in the String class is a
method to replace a substring in a string with another
string. If you want to change your last name, you can call
the the replace() instance method on the string storing your
full name. The replace() method takes two arguments — the
substring you want to replace and the string to replace it
Learning to Manipulate
Data
Output
Modern Nerd
Lincoln Daniel
name = newName2;
System.out.println(name);
Output
Modern Nerd 67
Output
Word Count: 8
Note!
We will learn more about Java arrays soon, but know that they
simply store a collection of data of the same datatype and every
array has a handylength field that holds an integer representing
the amount of elements in the array.
Note!
The “System” is the current system your program is running on.
System is a class provided by Java. Notice that we didn’t need to
create a new instance of System in order to access its in static
InputStream field. This is a prime example of the utility of static
fields.
if(scanner.hasNextLine()) {
//new line of data is available in input
stream
//read from the scanner
} else {
//no line of data available in input stream
//don't read from the scanner
}
if(scanner.hasNextInt()){
//read the int from the scanner
} else {
//scanner does not have an int ready for
reading
}
if(scanner.hasNextLine()) {
String nextLineOfData = scanner.nextLine();
}
System.out.println("Game over!");
if(scanner.hasNext()) {
userInput = scanner.next().toLowerCase();
}
} else {
System.out.print("\n\nYou're too young to
play this game.
Ending...");
break;
}
}
Notice that we take in the user’s name and age to begin the
game. Before we start, we let the user know what’s expected
of them and what’s going on throughout the game by
creating output when necessary through System.out.
Input and output are necessary for many programs and
they allow us to add more interactivity our programs. You
are now equipped with all you need to know about input
and output to begin making your programs more dynamic.
Play around with the code to see what else you can do with
input and output.
Inheritance Primer
Earlier in this chapter, I said that out is an OutputStream
and a PrintStream instance at the same time. By that, I
meant that out is an instance of the PrintStream which
inherits fields and methods from its super class, the
OutputStream class. We will learn more about inheritance
72
and class extension soon, but for now, just know that a
PrintStream is an Outputstream. If you had some trouble at
that point, don’t worry, we’ll touch on it again soon.
Learning to Build
Chapter 5
Learning to Build
Class Inheritance
Method Overriding
All classes that extend our Human class will share the same
attack method. That means that every subclass of our
Human class will attack the same way as the other
subclasses of our Human class. This wouldn’t be such a
good design because a user is expecting a Warrior to attack
with a sword and an Archer to attack with a bow and
arrow. Method overriding in Java allows us to accomplish
such a design.
A subclass can override the methods of its superclass to
implement its own behavior if it is necessary. Method
overriding allows a subclass to decide how to implement
behavior expected by the user through the inheritance
contract. In our game, a user will expect that all classes can
attack other classes, but they also expect that each class
attacks in a unique way. Therefore, each subclass of our
Human class should override the attack() instance method
to implement its own attack behavior. This is easy in Java.
All we have to do to override a method from a superclass is
to add the @Override annotation above the method in the
subclass:
76
@Override
public void attack(Human opponent) {
System.out.println("Attacking " +
opponent.getName() + "
with fire arrows!");
opponent.decreaseHealth(attackPower +
firePower);
}
}
Note!
Notice that the FireArcher class extends the Archer class which
extends the Human class. This is an example of a class hierarchy
from bottom to top:
FireArcher → Archer → Human.
human.attack(fireArcher);
archer.attack(warrior);
warrior.attack(archer);
78 fireArcher.attack(human);
}
}
Abstract Class
An abstract class is much like a regular class in that it can
have fields and methods. What makes it special is its
methods may or may not have bodies. That means an
abstract class can have method signatures that are declared
as abstract as well as full methods as usual.
An abstract method is a method that has no body and
requires subclasses of the abstract class its in to implement
its body. This is useful when you have a method that you
want all subclasses to have but you want to leave it up to
the different subclasses to implement the method how they
want. Further, a subclass of an abstract class must
implement all of its abstract methods.
Take the Human class’s attack() instance method from
the Class Inheritance chapter for example. We want every
subclass of the Human class to have a method of attacking
another Human opponent, but we expect each subclass to
have a different way of attacking. We should make our
attack() method abstract instead of implementing it in the
Human class as well as every subclass. That way, we won’t
be able to forget to implement it in every subclass and we
will keep our code clean by not writing expectantly useless
code in our superclass. There are a couple methods of the
Human class that we should make abstract, but in order to
do that, we must make the Human class an abstract class.
To do that, we simply add the abstract keyword to the
class’s signature before the class keyword.
79
In that code snippet, you can see that we have our Human
class and its attack(), defend(), jump(), andheal() instance
methods are abstract. This is because they are all functions
that should be unique to each class that implements them;
Taoist instances — magical characters — won’t heal the
same way as Warrior instances, so they should implement
theheal() method differently. You’ve seen the rest of the
class before, so those parts have been omitted.
Note!
At this point, it is important to note that static methods cannot be
abstract because in simplest terms, abstract means that a method
implements no functionality and static means there is definitely
functionality available in the method or field even without an
instance of the class. Thus, having a static abstract method would
be would be a logical contradiction which Java does not allow.
Interfaces
An interface is a bit different than anything we’ve seen thus
80
far. A Java interface is more like an abstract class than a
regular class. An interface can only contain method
signatures and static finalfields. An interface is merely a
contract between the interface and classes that implement
it. Like with abstract classes, classes that implement an
interface must implement its methods’ bodies to provide
functionality.
Interfaces are best for creating a contract that will
ensure that all classes that implement it behave similarly by
abiding by the contract. This will allow users to safely
expect parts of your program to behave similarly much like
you would expect all characters in a fighting game to
Learning to Build
void defend();
void jump();
int heal();
void attack(Character opponent);
double decreaseHealth(int
opponentAttackPower);
long gainExperience(long experience);
}
Note!
A top-level interface cannot be private. Also, all methods of an
interface are intuitively public, so don’t include any methods you
think should beprivate or protected.
Note!
From bottom to top, the hierarchy of concrete classes, abstract
classes, and interface goes like so:
concrete class → abstract class → interface.
If a class extends a superclass — concrete or abstract — that
implements an interface, you can declare the necessary methods
from the interface in the superclass. Doing this will fulfill the
subclass’s duty to abide by the contract between it and the
interface because your subclass will inherit the necessary
methods of the contract from its superclass. Alternatively, the
class can implement the interface methods on its own.
Java for Humans
@Override
public void attack(Character opponent) {...}
@Override
public void defend() {...}
@Override
public void jump() {...}
@Override
public int heal() { return 0; }
}
@Override
public void attack(Character opponent) {...}
@Override
public void defend() {...}
@Override
public void jump() {...}
@Override
public int heal() { return 0; }
}
The Dog concrete class and the Pet abstract class work
similarly with our Character interface:
System.out.println("\nStart Game\n");
modernArcher.attack(niceArcher);
niceArcher.getPet().attack(modernArcher);
modernArcher.attack(niceArcher.getPet());
modernDog.attack(petDog.getOwner());
petDog.attack(modernArcher.getPet());
}
}
Learning to Build
Output
Tom: Found 6 arrows ...
Stacy: Found 4 arrows ...
Stacy: I have a new pet. Hi Hunter!
Hunter: Wolf Wolf!
Tom: I have a new pet. Hi Buddy!
Buddy: Wolf Wolf!
Start Game
Chapter 6
Learning to Organize
Data Structures
Arrays
In your phone, you have a phone book filled with names
and numbers of family and friends. The good thing about
your phone book is it holds many contacts, but the bad is
that it is limited, although you may not know it. Your
phone book can only hold a predetermined number of
contacts. You can add new contacts, update contacts, and
86
delete contacts. With that said, your phone book is a data
structure. More specifically, it is an array. We will learn
how to make a phone book with an array in this section.
Note!
The number of elements an array instance can hold is stored in its
final int field called length. A final field cannot be changed after it
is set, and therefore, a final field is often referred to as aconstant
field. This length property of the array is what allows it to be of a
fixed size.
friends[0] = "Imani";
friends[1] = "Andres";
friends[2] = "Keith";
friends[3] = "Sasha";
friends[4] = "Tabitha";
friends[0] = null;
friends[1] = "Alejandro";
Output
First friend is now null
Second friend changed name to Alejandro
Now our first friend equals null and our second friend,
Andres, changed his name to Alejandro. Let’s make another
array to hold the corresponding phone numbers of all our
friends as integers:
Note!
Notice that some of the phone numbers have underscores in
them. Using underscores in long numbers, like commas on paper,
make them easier to read. You can add underscores between
Learning to Organize
Output
Friend 0: null
Friend 1: Alejandro
Friend 2: Keith
Friend 3: Sasha
Friend 4: Tabitha
Output
#Alert: No friend at index 0
Index 1: Alejandro's phone number is 5554448
Index 2: Keith's phone number is 5554311 89
Index 3: Sasha's phone number is 5557898
Index 4: Tabitha's phone number is 5556710
...
@Override
public String toString() {
return String.format("Name: %s | Phone
Number: (%d)-%d",
name, areaCode, phoneNumber);
}
}
Note!
In that snippet, we used the format() staticmethod of the String
class to map values to placeholders in our String.
Output
Friend 0 -> Name: Imani | Phone Number: (215)-5558000
Friend 1 -> Name: Andres | Phone Number: (484)-5554448
Friend 2 -> Name: Keith | Phone Number: (319)-5554311
Friend 3 -> Name: Sasha | Phone Number: (212)-5557898
Friend 4 -> Name: Tabitha | Phone Number: (212)-5556710
System.out.println(friend2);
Output
Name: Alejandro | Phone Number: (484)-5554448
phoneBook[0] = null;
System.out.println(phoneBook[0]);
Output
null
That’s it. We now have a phone book we can add to, update
the elements of when a friend changes his or her contact
information, and delete elements from when we lose a
friend. It is clear that arrays are useful when you want to
store a collection of values — objects or primitives — of
Java for Humans
Lists
Our phone book from the Arrays chapter could only hold a
fixed number of our friends’ contact information because it
was made with an array. We bounded our phone book by
implementing it as an array because it makes sense: your
phone only has a limited amount of storage space, so we
can only store a limited amount of contacts. Arrays are best
when you know how many elements you will be collecting,
but there are other situations where it doesn’t make sense
to bound the capacity of our collection. For those
situations, dynamically expanding lists are best.
Why Lists are Important & Useful
Unlike arrays, lists in Java can expand without bounds. You
may use a list to accumulate and collect things you don’t
know the bounds of, such as the people you meet in your
life time, the places you’ve been, the skills you learn, the
movies you want to watch. If you’ve ever heard of a
“Bucket List”, it is the best application of a list: toss
everything you want to do into the bucket and mark them
as done as you accomplish them.
The Java List class is an interface from which we can
implement any kind of list subclass we’d like. Java provides
us two popular implementations of the List interface —
LinkedList and ArrayList — but we will focus on the
LinkedList in this chapter because you already know much
of how an ArrayList works; an ArrayList is simply an array
with convenient instance methods and a dynamically
92
expanding capacity.
LinkedLists
A LinkedList is a special type of data structure that allows
us to link elements together in a line without bounds.
Elements of a LinkedList are referred to as nodes and each
node has a pointerfield pointing to its left neighbor and
another pointing to its right neighbor.
A node has a minimum of three instance fields: its two
pointers which are int values, and its datafield which holds
the actual data. The datatype of a LinkedList, or any data
structure for that matter, is the datatype of its elements and
Learning to Organize
@Override
public String toString() {
if(done) { return name + " is done.";}
else { return name + " is not done";}
}
}
LinkedList<Thing> bucketList = new
LinkedList<Thing>();
Our Thing class has only two instance fields: a String name
and a boolean done. We can get the name of a Thing
instance by calling thegetName() instance method and we
can mark a Thing as done by calling the
markDone()instance method. We can check if a Thing is
done by calling its isDone() instance method. Finally, our
Thing class overrides the toString() instance method of its
implicit superclass, Object. Let’s add some things to do to
our bucket list:
To get the first or last element of the list, we could also call
its getFirst() or getLast() instance methods respectively.
Java for Humans
Output
Thing at position 0: Bungee Jump is done.
Thing at position 1: Learn Java is not done
Thing at position 2: Build an Android Application is not
done
Thing at position 3: Travel to the Bermuda Triangle is not
done
bucketList.getLast().markDone();
for(int position = 0; position <
bucketList.size(); position++){
Thing thingToDo = bucketList.get(position);
if(thingToDo.isDone()) {
bucketList.remove(thingToDo);
}
}
94
System.out.println("Things left to do: " +
bucketList.size());
Output
Things left to do: 2
Now we only have two things left in our bucket list. Let’s
imagine we have read all the way through Java for Humans
and developed an Android application. That would mean
we can mark those two things as done on our list. Given
that we only have those two things left, instead of removing
them one at a time, we can simply empty our entire bucket
list by clearing our LinkedList:
Learning to Organize
System.out.println(bucketList.contains(learnJava));
bucketList.add(learnJava);
System.out.println(bucketList.contains(learnJava));
System.out.println(bucketList.contains(new
Thing("Learn Java")));
Output
false
true
false
Note!
The contains method only returns true if the provided object is a
reference to an object in the list. Although the two Thing
instances with a name value of “Learn Java” appear to be the
same, they are not because they don’t reference one another. This
is something you should do some more research on because its
beyond the scope of this book.
HashMaps
Arrays let you collect a fixed amount of elements in one
data structure, and Lists can do the same but without
bounds. The only thing they both don’t allow you to do is
store objects and retrieve them by a specific, unique key.
This is where theHashMap comes into play. If we want to
make a dictionary of all the words in the English language
alongside their meanings, our best bet would be to use a
HashMap.
Java for Humans
System.out.println("Double: " +
meaningOfDouble);
System.out.println("0: " + meaningOf0);
System.out.println("zero: " +
dictionary.get("zero"));
Output
double: A primitive datatype for representing floating
point numbers.
Double: A class for wrapping a double in an Object with
convenient methods.
0: The number zero. The first index in arrays and the
first position in lists.
zero: 0
if(stringDictionary.containsKey("Class")) {
stringDictionary.replace("Class", "A better
definition.");
} else {
stringDictionary.put("Class", "A descriptive
definition");
}
String meaningOfClass =
stringDictionary.get("Class");
System.out.println("Class: " +
meaningOfClass);
Output
Class: A better definition.
String valueOfRemovedPair =
stringDictionary.remove("Class");
System.out.println("Value of removed 'Class':
" + valueOfRemovedPair);
Output
98 Value of removed pair with key 'Class': A better
definition.
stringDictionary.clear();
System.out.println("Pairs in our string
dictionary: " + stringDictionary.size());
Output
Pairs in our string dictionary: 0
Learning to Organize
Polymorphism
Output
Current user has 4 friends.
Human ourFriendTomTheHuman =
currentUserFriendsList.get(0);
Output
Our friend Tom is an instance of the Archer class.
Tom: Found 5 arrows!
Tom: I now have 8 arrows.
Java for Humans
Type Casting
If we want to turn Tom back into an Archer, we must cast
him to one. Type casting in Java is the act of casting, or
converting, one type, a class or interface, into another type.
As usual, we should check to make sure Tom is actually an
Archer disguised as a Human before we try to cast him
back to an Archer. We do the check in the next line of code
by using the instanceof operator in an if-thenstatement. The
instanceof operator returns true if the object on the left is
an instance of the class on the right, and it returns false
otherwise. In this case, it returns true because Tom is
indeed an instance of the Archer class as we already knew.
Now we are inside the first block of the if-then statement.
After printing that Tom is an instance of the Archer
class, on the next line, we cast theourFriendTomTheHuman
object to an Archer and save this new copy of Tom to a new
Archer variable called ourFriendTomTheArcher. As you
can see, totype cast an object, we simply put the class of
type we want to cast our object to inside of a set of opening
102
and closing parenthesis to the left of the variable holding
the object.
Note!
You can type cast primitive values like ints and doubles, too. Do
some more research on type casting because it is a handy tool.
103
Java for Humans
Chapter 7
Applying Knowledge
GameGUI
The GUI is what allows a Game instance to display real
time information about the state of the game and its players
to the user; our GameGUI class is used by the Game class
to achieve that purpose. As noted before, each Game
instance must have an instance of our GameGUI class in
order to run. The GameGUI makes use of JavaFX, which
allows developers to create desktop, mobile, and web
applications nicer than ever before, to display information
from an associated Game instance to the user in its views.
Our GameGUI is currently designed with
threeTextAreas for displaying information about the game
and ongoing battles in the game, one TextField for
capturing user input, one ListView for displaying the
standings of all the characters in the game, a Button to stat
the game, and two more buttons to advance through the
game. Setting all of that up is a bit more involved, but
you’ll be able to understand each part as you read the
documentation in the code.
JavaFX Application
Our application runs on JavaFX components for its GUI
and a nice abstract Application class provided by JavaFX
for easily launching and starting a application program.
Our GUIGameApplication class extends the JavaFX
Application class and is at the root of our project. Its only
duty is to hold the main method of our program. Its main
106
method has a simple duty of calling the launch() instance
method from the Application class. When that method is
called, it will call the abstract start() instance method from
the Application class to start our application. Our
GUIGameApplication must implement that start()method
which gives us access to the primaryStageStage field of the
application. We must provide theprimaryStage reference to
our Game, which will provide its instance of our
GameGUI class to display the JavaFX GUI for our game.
Finishing Up
And just like that, we are finished. You have learned so
Applying Knowledge
Fun Projects
Console Applications: Easy
108