Transcripts
1. Introduction: Hi there. My name is Derek and welcome
to my course on Java. You probably have your
reasons for being here. Maybe you've been
job Clinton recently only to scroll down to the
qualifications section and realized that they require
you to know Java and other programming languages
as a basic prerequisite. Maybe you've been looking
at compensation bands and realize that software engineers
are paid very generously. Or maybe you just want
to learn something interesting to kick
off the new year. Regardless of why
you ended up here, java is a great skill to learn. But what is Java? Java is a performance and
popular programming language, meaning that you'll be able
to write fast programs. You'll be in high
demand for your skills. Java's also easy to pick
up and transferable, meaning that once
you learn Java, it will make learning other programming languages
even easier. Now that all sounds great, but there are tons of other programming classes out there. Why should they choose this one? Well, we've got lots
in store for you. Firstly, we have all
the source code in this course ready to go for
you in an online environment, meaning that all you gotta do is press the green Run button. No need to spend hours
banging your head against your computer trying to figure out what's wrong with
your local setup. With one click of a button, you're ready to see the
output of your programs. We also have a very visual resume ready
project for YouTube, meaning that at the
end of this course, you'll have something
to show off to your friends and
put on your resume. We have concrete
example code samples in every lesson so that
you don't get confused by abstract concepts
are concepts are introduced with an easy to follow and visual walk-through. Finally, I will be actively
maintained in this course. So feel free to post questions
if things are not clear. Before I let you loose
into the course content, I should probably first
introduce myself. I am a professional
software engineer and for my entire career, I have worked at some
of the most famous and valuable tech companies
in the world. I have real-world experience delivering concrete
technical products, some of which you may
have encountered. Before I was a
software engineer. I taught undergraduate
Computer Science at the University of California, Berkeley, where we regularly solve thousands of
students this semester. Course was named one of the top five in the nation by Bloomberg. And I'm currently
one of the most popular instructors under 61, a departmental YouTube
channel where we've amassed about 900,000
views as of 2022. During my time at Berkeley, I also want multiple
teaching awards and was given the distinguished
GSA Award in 2020, which was given to the
top 13 instructors and the entire computer science department out of
several hundred. Finally, I hold a
graduate degree in computer science
also from Brooklyn. As you can see, I love all things tech and
I love teaching. I'm super excited to have you guys along for the ride with me. One last thing before
we start the course, I ask that you please
create an account on repl it.com and verify your e-mail
once you have done so. Now, I know I know. Maybe you just made a
Skillshare account and you're probably not in the
mood to make another account. Well, as I alluded to earlier, we have an online
environment setup for you to play around with and
to build your project. And believe me, the alternative
is much, much worse. The alternative to the
online environment would be setting up a local dev
environment on your computer. There are 1 million
ways that could go wrong and it could take
hours to troubleshoot. So I ask that you spare
a couple of minutes right now to please make
an account right here. That's it for me in this video, I'll see you in the next one. If you'd like to
access the slides. The link will be posted in
the course description.
3. Methods: Welcome friends. In this video, we're going
to talk about methods. First of all, what is a method? A method is pretty
much anything that performs an action
within a class. And the definition for
inaction is pretty broad. It could be anything. It
could be simple arithmetic. There could be running a
machine learning algorithm. It could be rendering a frame. Classes contain methods, and methods contain all the
logic within a program. Now, methods must be declared before we can start
writing logic in them. There are four components
to this declaration. First, we have the
access modifier. We have four types, public, private,
private, and protected. Access modifier
on a mirth method works exactly the same
way it works for classes. If the axis is not
explicitly stated, the method defaults
to package private, just like a class would. A public method is one that can be referenced from any class. Panda package private method is one that can only be
accessed if it is referenced from a method of a class within the same package. Also recall that
previously promised, I will explain private and protected once we started
talking about methods, well, it turns out we need
to know even more about Java before we can
talk about protected. So we'll leave that
one out for now. However, we can talk about
private code that is marked private can only be accessed
within the same class. So e.g. if I declared
method X to be private, that means that only
other methods within the same class would be
allowed to reference method X. Methods of other classes
regardless of their package, wouldn't be allowed to
reference a private method. Next, we have static. We can choose to omit the word
static in our Declaration, in which case the method
will default to non-static. Now, don't worry about what static actually means just yet. Unfortunately, you'll
need more context on Java before you'll be
able to understand it. So for now, just be aware
that the static keyword exists and it comes after
the access modifier. Next we have the return type which must always be present. The return type is, as the name suggests, the type of the value that
is returned by a method. In this case, nothing is
returned by this method. So we say its return
type is void. Now, you may be a bit
confused about what it means for a method
to return something. The return value of a
method is the value output. E.g. imagine we have
a method called add and all it does is it
adds two integers together. So e.g. add of 1.2 gives us three. In programming, we
will call this three the returned value
of the function add. Return value is synonymous
with the output value. And in this camp and
in our ad example, the type of the return
value would be an integer, since three is an integer. Finally, we have
the method name. Names generally can be
whatever you want them to be. The only restriction,
I believe is that the first character of the
method name must be a letter. Now, let's talk
about types in Java. Like we said in the
previous slide, every method needs
to return type. So it's important that we understand what some
of those types may be. First, we have a string, which is a doubly quoted
human readable piece of text. Recall in the previous slide, we had Hello World, right here, right here. This is a doubly quota
human-readable text. It is an example of a string. Next, we have an integer, an int, which is Java
speak for integer. We also have floats, which is Java's way of
saying a number with a decimal point, like 1.3 e.g. we have booleans which are values that can only
be true or false. We also have array types, which looked like int bracket, bracket or Boolean
bracket bracket. An array of items is basically just an ordered collection
of elements of the type. So e.g. if we specify
int bracket bracket, then that means that
that value is going to be an ordered
collection of integers. And if we have Boolean
bracket, bracket, then that is going
to be a collection of true or false values. Java has a lot more
types than justice, but these are some of the
most common types will see. And they'll serve as
a good foundation for the remainder
of this course. Next, we need to talk
about method arguments. A method argument is just
a formal way of saying the inputs or
parameters of a method. The arguments of the
method are specified in parentheses after the
name of the method. And the Java type
of the arguments must be explicitly specified. E.g. here we have a string array type and we're given the name
of the argument args. This means that when
we call this method, we must give it an input
of type string array. Otherwise, Java will refuse to compile the code
and will not run. There are a couple of subtle points you should be aware of. The first is that this method main over here is very special. Typically a Java application, we will have several files and we would need to
specify an entry point. Otherwise, Java
would have no way of knowing which piece of code
just start running first. So in this case, we
would specify that we want the helloworld class
to be our entry point. At which point java
would then look for a main method that has
exactly this signature, public static, void main with one argument that has
type string array. It will run this
method if it exists as the initial entry point
into the program. Otherwise, Java
will throw an error saying that there's no
main method defined. Second, if you want to have a method taken
multiple arguments, we will need to
explicitly type each of those arguments and
separate them with a comma. In this ad example, we have two arguments, x and y, and we specify the
types Int for both of them. And this function
add simply returns the result of adding these
two numbers return x plus y. As a side note, note
that when we specify a return type and the
method signature, e.g. over here, we must
include a line inside this method that explicitly
says return in Maine, e.g. we have a void, which
means we return nothing. Note that there is no line in this method that says return. Third, it's totally fine
to have zero arguments to. You would simply
put an empty set of parentheses after
the method name. Now, you may be thinking that
this requirement explicitly type everything
in Java is really burdensome and only
exists to slow you down. But if that were true,
Java wouldn't be one of the most popular
programming languages and the software industry today. The reason we have these
requirements is that these allow Java to perform something we
call compile-time checking. Before you run a Java program, your computer must first convert the code into something
called byte code. We call this process
compilation. When there's
compilation is complete and you run the program, you're actually running the
bytecode that is produced. Now the advantage
of having a compile step before running
the code is that the Java compiler
is able to analyze your code and perform
some basic sanity checks. One of those sanity
checks is that all the specified types in
your logic are consistent. E.g. as we mentioned earlier at here, expects two integers. Imagine if I tried
passing the number two, a string, hello world
as arguments into ad. Well that would make no sense. How do you add the number two to a piece of text Hello World. So Java's advantage is that it will run these
sanity checks at compile time and notify you of any errors before
the code is run. In other languages without
compile-time checking, there may be an issue
in your code that you wouldn't know about
until the code is run. And that could be
very devastating if your code is deployed in say, a bank or maybe on Google, which is used by 1
billion people every day. Now, let's talk about
the method body. First. The method body is simply all the code within
these brackets. There's not really any
restriction on what you can do in the body and the method body
can be as long as you want. Regardless of whatever logic
you decide to perform. The main thing you
need to ensure is that the type of
the return value needs to match the
specified return in the method declaration. Here, we're returning some, which is a variable
we declared and initialized with
the value x plus y. Since x and y are both ints, the addition of two
is also an int. Therefore, returning
sum is compliant with our requirement to
return an int in this method. The next point I
want to emphasize is that the return
line is terminal. Java compilation will
fail if you try to put any code after the
return line in a method, which makes sense since the return value is the
output value of the method. Why perform additional logic after you've already
output a final value? We also need to talk
a bit about variables that you create and
use within a method. Just like method arguments, variables you defined
within the method must be explicitly typed
when you create them. And you can name them
anything you want as long as the first character of
the name is a letter. After declaring the variable
sum as an int, e.g. we can no longer change its
type within the same method. So I cannot do something like
int sum equals x plus y. And then in the next line do string sum equals hello world. Although you can't
change the type of sum, you can change its value. And when you do so, you do not need to explicitly type it. So after the mine int
sum equals x plus y, I can do something like sum
equals one without the, without the explicit
type declaration. And by the way, these
three statements are only true within
the same method. I could have an entirely different method
called Subtract. And subtract, I could declare sum to be a
string if I want it to. That variable would have to stay a string
within that method. Method variables
in one method are independent of method
variables in another method. Now that we know how
to define methods, Let's look at how we use them. We call this a method call. When we referenced
the method name and passing arguments
in parenthesis, as you can probably guess, out of 12 will cause the code return x plus
y to be executed. And that returned
value is now going to be bound to X in Maine. By the way, this thing
we've been using all along, system dot out, dot print
LN is also a method. It consists of a reference
to a method name and has parentheses in which we pass an argument for our travel
to print out to the screen. In this case, the value
of x, which is three. The reason we need
all these dots is going to make more
sense in the future video. Pop quiz. How does Java know to print out the value three, in this case, instead of the literal character x that we
passed into print, go ahead and pause the video. I will reveal the answer in 321. The reason java
knows to print three is that this x is not, WE quoted at the X had
double-quotes around it. Java would treat x as
a literal character x, since it does not have
double quotes around it, java understands that x is a variable name with a
value attached to it. So it will first
evaluate what x is and then print out the
result of that evaluation. Here are the links to the code
samples using this video. Since we've covered quite a
bit of content in this video, I ask that you please
visit these links. Click, Fork, ripple, and
tinker with the code. It doesn't have to
be anything fancy. Just experiment with adding
variables to method bodies or maybe change the return type and the method declaration. And by the way, remember
to add semi-colons. Java lines must
end in a semicolon unless you're opening up a new code block with
squiggly brackets.
4. Replit Demo: In this video, I
want to give you a quick overview of the
ripple environment. And what I mean when I say I encourage you to
tinker with the code. First, make sure you have made
an account on repl it.com. I know it's kind of annoying
to set up another account, but the alternative
to this is to set up a local programming
environment on your computer. The problem, that is, I don't know what
computer you have. I don't know what OS
you're running and I don't know what
environment variables are, aliases you have setup
on your computer. When I used to teach
at UC Berkeley because sometimes take
me more than an hour just to get a local
environment setup for a small group of
maybe ten students. And given that
skill share classes basically have
unlimited capacity, the overhead
associated with setup alone would take
prohibitively long time. This is a class about Java, not about computers and repl, it has already set
up Java for you. I think this is an extremely valuable resource
that you can use, plus it's free for
our use cases. Now, if we visit these
links in the slides, Here's what it
looks like when we visit the link in the slide. Once you've made a REPL account, go ahead and click this for
grappled button over here. Now we have a copy of the
project in your account. This is the code from the
video on programming anatomy. The sidebar over here
is where you can explore the file
structure of the project. We can click into the folder to expand its contents
and we click, Insert a file names to
display their contents here. In this example, the main method here just prints Hello World. So let's sanity check. Go ahead and click
the green button. You can ignore the
cryptic texts over here. This is just REPL its
system under the hood, issuing build, and run commands. Now let's try forking another ripple and
make changes to it. Here's the code from
the methods video. Let's go ahead and try
doing the same thing. So here's the link. Again. Let's click Fork ripple, and fork it to our account. Now let's see what we can do. First, just sanity check with the green button and
ensure that this, these values in the main
method are printed out. Okay, so we can now see that we printed out
the number three. And if you take a
look at the code, this should, this
should make sense. We have out of 12 and
we're printing out the result of adding
1.2, which is three. Now let's see if we're able to add two method calls together. So this would be the first example of
tinkering with the code. So let's say we did
add one to plus one. Since calling one will
return a number one. Sounds reasonable
that perhaps one can be added to the
result of adding 1.2. Let's go ahead and run this. Now, you see that
we get an error. It says we have 21
says not a statement, do other ones as
expected, a semicolon. So as you may have noticed, all Java lines end
with a semicolon, other than the ones that's open, a new code blocks such
as method declarations. So perhaps it would
be prudent for us to add a semicolon
at the end here. Now let's go ahead and
run this code again. Okay, So we still have this, not a statement error, but at least we got rid
of the semicolon error. So not a statement is
a pretty big error. So let's go ahead
and Google that. Let's go ahead and
copy and paste this. Go to Google and go Java. Not a statement. We click on the
first result Stack. Overflow is an extremely helpful resource for
most programmers. And we can scroll down to
the answer right here. And notice what
they say. They say. Java restricts the types
of expressions that are allowed and so-called
expression statements. It disallows semantically
meaningless statements like zero or a plus b.
Hey, guess what? Isn't this exactly what
we were doing earlier. We're doing add one to
plus one semicolon, which is basically the same
for as a plus b semi-colon. If we scroll down some more, you'll see that they
have a quote from the Java language specification. Certain kinds of
expressions may be used as statements by following
them with semi-colons. And then we take a look
at the list right here. Well, we have an
assignment that is listed as one example
of a valid expression. So let's go back to our
code and turn this into an assignment expression
that would look like this. Y equals add one to plus one. Let's go ahead and run
this one more time. And now the code compiles
and runs successfully. We don't see the
result of adding 12.1 because we
didn't print it out. So let's go ahead and add
that line and run again. Okay, and now we got a four, which makes sense because
we've added one to two and then add a one more
one to that, which is four. Now let's try to
finding a method, another method
that does not have the static keyword
and see what happens. So perhaps this call this
public to return to. And again, note that I have
omitted the static keyword. Now let's try seeing
what happens if we do 12 plus one plus two. Let's go ahead and
run this code. Interesting. We have another Java
error this time. Non-static method cannot be referenced from a
static context. So they even have this even point directly to the non-static method
that is causing the air. So this is one of Java error that is actually
slightly more helpful. They tell you that non-static methods cannot be referenced from static methods. And two is our
non-static method. Now we haven't actually talked
about what static means. So don't worry about it. We're going to
talk about that in a future video and this error message
will make more sense. Then the key takeaway is the importance of
tinkering with code. Even though we broke the
code multiple times, we learn things about Java that will help us later
down the line. It's best that you
make these mistakes now on many projects
associated with these videos so that
you don't get confused later when working
on larger projects.
5. Control: Welcome friends. In this video, we're going to talk
about control. In order to perform more
complex logic flow in Java, we need to first understand
some common operators. First, we have some basic
arithmetic operators that are pretty
self-explanatory. These are the symbols of plus, minus and times, and they work exactly
as you might expect. They add, subtract, and
multiply respectively. The slash symbol is
Java's division operator. But one thing you should note is that division on
integers in Java, a floor divide operation, meaning that it rounds down
to the nearest integer, e.g. 3/2, and normal parlance is 1.5. However, in Java three, Florida by two is one. Since we round down from 1.5% symbol is called
modulo or mod for short. It returns the remainder
of a division, e.g. 14 mod four is two. Why? Because four goes into 143 times and we're left with
the remainder of two. If you're unfamiliar
with what a remainder is, I recommend you look it up, then come back to this video and replay the last
couple of seconds to confirm that 14 mod
four indeed equals two. The equals sign here
is how we assign values to variables
which we saw earlier, like int x equals one. We also have some
Boolean operators, as the name suggests, these are operators that returns
true or false. First, we have some pretty self-explanatory
operators greater than, less than, greater
than or equal to, and less than or equal to. This exclamation mark flips true to false and false to true. We'll see you in
the next slide how the precise syntax
of this works. Now we have double equals. This means return true if equal, return false if not equal. Remember this, since
it's kinda tricky, double equals sign is
used to compare equality. Single equal sign is
used to assign values. Double ampersand
means return true if both conditions are true,
otherwise return false. And this double straight-line
means to return true if either condition is true,
otherwise return false. This operator might not be
familiar to most people. So here's where it is.
On a Logitech keyboard. It's usually next to
the bracket keys. Let's look at some
example usage. First, one plus two is obviously 3.1 minus two is
obviously negative one. Nothing tricky there. Now, for quotient
where we have 3/2, recall that Java division
on integers is for division 3/2 is one. Since we're rounding
down from 1.5, product is equal to six. Nothing tricky there.
Three times two is six, and Java doesn't do
anything special with that. The remainder is equal to
one because two goes into five twice and we have a
one leftover after getting, after multiplying two-by-two,
this boolean true, true underscore zero
is equal to true because we added this
exclamation mark right before a false. So the exclamation mark
flips the false expressions to true expressions and true expressions to
false expressions. So therefore, this is true, true underscore one is also true because three is indeed
greater than negative one. True underscore two
is also true because we are negating zero
equals equals one. Well, zero does not equal one. So this expression
in parentheses, it's going to return false. Then the inversion of
that is going to be true. So true underscore
two becomes true. False underscore zero
is equal to false. Because remember,
double ampersand only returns true if both
expressions are true. True underscore zero is true. However, the inversion of true underscore one
is going to be false. So therefore, it is not
true that both are true, and so therefore the
result is false. Finally, true underscore
three is going to be equal to true because we call this
double straight-line thing, it returns true if either
of the conditions is true. In this case, false
underscore zero is false. However, true underscore
zero is true. And so therefore, because one
of the conditions was true, the entire expression
evaluates to true. Now that we've covered
basic operators, Let's look at how we can control the flow of logic
within a program. First up, we have
the if-else pattern. We place a Boolean
expression within parentheses immediately
following the IF operator. If this expression here
evaluates to true, then we will perform
all logic within the curly braces that immediately follow the
Boolean expression. In this case, return x plus y. This expression
evaluates to false. Then we would skip all the code enclosing the
curly braces right here, and instead execute
the code within the curly braces of the
else case right here, in this case returns zero. Recall from an earlier video that I mentioned that return is terminal and we shouldn't have any lines of code
after a return line. So why is it that here we have multiple return
lines right here? Think about it and I'll
reveal the answer in 321. The reason is that only one of these Code Blocks is ever run each time the method is called. These code blocks are mutually exclusive 100% of the time. The subtle point about return mines being
terminal is that they are terminal only for
the given block of code in which they exist. And this makes sense
if you think about it. This method example one has been declared to
return an integer. Imagine if we only wrote
this return x plus y line, but we did not have
this return zero line. Then further imagine
that we pass in an x such that this expression
evaluates to false. Then we would skip over this
return line and come to the else block where we do not have a return
zero anymore, then this method
will return nothing. And then this method
would be breaking this promise that it
will return an integer. So this would lead to a
Java compilation failure. Here's another if-else pattern, but this time utilizing some operators that we
talked about earlier. Once again, we enclose the entire boolean
expression in parenthesis. If x mod two is equal to one, or y mm R2 is equal to zero. Then we execute this entire
code block returned X plus Y. Otherwise, if both conditions
are false, we return zero. Here's another example, this time introducing a new operator. Else if the name of the
operator is pretty intuitive, and it does what
you might expect if this Boolean expression
were to evaluate to false. It would skip over the return x plus y line and then try to evaluate the Boolean expression contained in the else-if line. If this expression x mod
three is equal to one, evaluates to true,
then we return x. Otherwise, if this
expression were false, we would skip over return x
and come to the else case, in which case we return y. Now, let's talk about
the wild pattern. Sometimes you may
find it helpful to run a certain code
block multiple times. E.g. say you want to print out numbers from
one-to-one thousand. One way to do so
would be to write out system.out.print
LAN 1,000 times. But another way to
do so would be to write a single system
dot out dot print LN, and enclose it within
a wild code block. So here's an example. The way this works is we first evaluate the
expression here. And while n is
greater than zero, if this is true, then we run all the code within
this code block. At the end of the code block, we returned to the start and evaluate this
expression again. Is n greater than zero? If so, we run the
code block again. And then we repeat,
returning back to this Boolean expression over and over again until it is false. This syntax here might be a
little unfamiliar to you. Let's break it down
starting with this line, n equals n minus one. Recall, the equals operator means to assign a
value to a variable n. But before we can
assign a value to n, we need to first
understand what is the value of this
expression, n minus one. So basically what this does is it first subtracts
one from n, and then once it does so,
assign this value back to n. So effectively, we're just decreasing the
value of n by one. So if n comes in as a five, we evaluate five minus 15, minus one is four, and then we assign the
value four back to n. So n is now for these
other two lines and minus, minus and minus equals one, they're actually both
shorthand for the same thing, n equals n minus one. So this entire code
block is effectively decrementing n by three
every single time it is run. Similar syntax exist if you want to increase
the value of n, we could simply do
n plus plus and plus equals one and
n equals n plus one. I'd also like to
impart a warning. Java performs many sanity
checks at compile time. But one thing that
does not check is whether your loop
will terminate. E.g. imagine that these three lines were
all incrementing. We're increasing the
value of n. So n plus plus and plus equals
one and n equals n plus one. Now imagine we also
pass in a value of n that is already
larger than zero, then this code block will
increase n even more. And this expression right here, and greater than zero
will never be false. And so therefore, this block of code is going to run forever. If this happens, your code won't error and the compiler
also won't error. It'll just keep running forever until you recognize the
issue and stop the code. So be mindful when
you write loops and make sure your condition
will terminate eventually. Here is our final
control pattern for this video. Here's an example. We have four followed
by three expressions enclosed within parenthesis and delimited with semi-colons. The first expression is
in initialization step. The variable i does not
exist yet in this method, so we both declare and
assign it to a value zero. Next, we have the
Boolean expression, similar to the Boolean
expression in the while loop. This is a Boolean
expression that is going to be evaluated before
the code block is run. If it is true, we
run the code block. If it is false, we break out of the code block and run any code that comes
after this for-loop. Finally, we changed the state. This I plus plus is run
after the code block is run. So since we're starting from zero and running
until I is no longer less than n and I is increasing by one on
every single iteration. We're effectively
just printing numbers from zero to n minus one. Here are a couple of more
examples of for-loops. Note here that we
can initialize i, an entirely separate
line of code. If no initialization is
needed for the for-loop. Let me just put a
semicolon and leave the first initialization
expression empty. Here we have another example. I want you to take
particular note of the initialization here. Recall from our previous lesson that once a variable
has been declared, future references
to that variable do not need to type
to be specified. That is the reason that here
we only say I equals three, but not int I equals three. The same rules apply to both the initialization
expression and standalone
expressions outside the for loop parentheses. Now, you may be
wondering to yourself, What's the difference
between a for loop and a while loop other than the fact that there's syntax
is different? Well, the answer is they're actually effectively
the same thing. Really, the only major
difference is their syntax. So don't think too hard about what the differences
between these two might be. Here's the link to the
code used in this video. As always, please
click the link, click for grapple and
experimental at the code. One thing I'd like
for you to try this time is if you run into
any Java errors that you might find kinda
cryptic and encourage you to copy and paste that
error message into Google. The root cause of error messages is usually pretty similar. And often you'll find
really helpful results from programming forums
that Google direct C2.
6. Objects Part 1: Welcome friends. Today we're going to
talk about objects. Now, I realized that, that sounds really dumb, that we're going to
talk about objects. But I promise you that
you're gonna learn something valuable by
the end of this lesson. Now, before we get into
the content of this video, let me try to
convince you why you should care about
objects at all. So far, we've only been dealing with the functional
aspect of Java, such as methods
and control logic. However, Java is
actually what we call an object
oriented language. This means that we view our
programs as objects with behaviors rather than as a
collection of functions. This may be a bit
difficult to grasp. One analogy you might think of is how you view a video game. Let's say Mario, e.g. in case you're not
familiar with Mario. Here's a screenshot from
one of the Mario games. This guy here is Mario. And the premise of the
game is yet to get past a bunch of obstacles
to reach a princess. And these funny-looking
mushroom things over here, they usually move and that they touch you,
you lose a life. Now, a Mario game is obviously
a piece of code, right? There's probably some piece of code that checks the distance
from the mushroom to Mario. And at the distance is
less than some threshold. Then we subtract one
from Mario's lives. But that's not how we
think of this game. We don't think of these
mushrooms as methods that are constantly checking
for distance to Mario. And we don't think a Mario as a bunch of methods
that are constantly calculating his vertical
and horizontal velocity. We just think of Mario as a single entity that exhibits jumping and
running behavior. And we think of these
mushrooms as entities that are actively trying to stop us
from saving the princess. That paradigm shift is the same one we
have toward Java as a functional language versus Java as an object oriented one. Even if we're not
coding a video game, developers find it
useful to think of their code as discrete objects exhibiting behavior instead of as a collection of
abstract functions. As you work on larger and
larger Java projects, it becomes significantly easier to understand the
program as a whole. If you have a solid
object oriented design, because that's the
way humans perceive the world as a
collection of objects. Here's an example
of a class that exhibits object
oriented programming, as well as a main method that utilizes this class
as an object. First, I'd like
to point out that despite some unfamiliar syntax, there is actually
a lot here that we've already covered. Here. We have packages, we
have public classes. We have a main method that serves as the entry
point to the program. And we have method
declarations here. And we have an if else block here with a Boolean expression. So the amount of stuff
we need to know to understand object
oriented programming is not too bad at all. Let's talk about this
code block here. This is something we
call a constructor. One way you can
tell that this is a constructor is that there
is no return type and the method declaration
and the name of this code block matches
the name of the class. But other than the fact
that the declaration of this code block is different
from that of a method. Basically acts like a method. And this code block is
executed upon instantiation. Instantiation is when we create a new instance
of an object. It might be a bit difficult
to understand when instances in terms
of this Dog class. Let's instead recall
our previous examples. When we create an
integer variables. Imagine we have two integer
variables, x and y. Maybe x is equal to one
and y is equal to two. Since both x and y are integers, you can think of them as two instances of
the integer type. Only they have different values. Similarly, you can imagine we might have two
variables, x and y, both of which have
typed Dog and have different values for
their name and age. An instance of an object is
exactly what it sounds like. It's a version of an object. We'll talk about
how to instantiate an object in the next video. For now, all you need to know is that when
instantiation does occur, this code block will be the
first thing that is executed. And we'll also talk about
what this actually means. This.name equals name and
this dot age equals age. These right here are examples of what we call instance variables. To be more specific, they are declaring
instance variables, but not initializing them
to any particular value. We could give these
variables and initial value upon declaration, such as private string
name equals Bob, right here in this line. However, usually we delegate the variable initialization
to the constructor, since the constructor
is going to be the first thing that
is called anyway. And perhaps it's not a smart idea to name
all of our dogs, bob. That would be
extremely confusing for all of our puppy friends. As you can see, just like
any other variable in Java, these instance variables must have an explicitly
declared type. They also need access modifiers, just like classes and methods. There are two
important differences between method variables,
instance variables. The first difference is that instance variables persist
across method calls. A method variable only exists for as long as the
method is still running. Once a method returns all its variable values
are cleared from memory. For objects, these instance variable values will persist as long as the object
instance exists. This will make more
sense when we see an example of object
instantiation in the next video. The second difference
is their access rules. Method variables are
only accessible within the innermost code block
in which they are created. E.g. if we had a while loop
inside the method getName. And inside that while loop, we created a variable. Variable would
only be accessible within the code block
of the while loop. However, instance
variables are accessible from all the non-static
methods within the same class. We're going to talk
about what static actually means in
the next video. But for now, all you
need to know is that a non-static method
is one that does not have static before they're declared return type and
the method declaration. As you can see here, we can return the value of name and age from
these methods here. These instance variables
are accessible to these methods since these
methods are non-static, the prefix this dot tells Java that we're referring to an
instance variable called name. Now, you might
think that this is a ridiculous requirement that we had to add even
more language rules to refer to instance variables. But there's a good
reason for this. Can you tell what it
is? Pause the video and I'll reveal
the answer in 321. The reason is that we might
have naming conflicts between instance variables
and methods variables. One example of this is actually right here in the constructor. We have the variable name declared in the arguments
of the constructor. If I were to omit the, this prefix in this line,
this.name equals name, then we would basically
just have name equals name, which does nothing because
name is already equal to name. So the, this prefix
is important for disambiguating between instance variables and
methods variables. If there is no this
prefix and there is a method variable
with the same name as the instance variable, then Java will assume you're referring to the
method variable. Here's the code
used in this video. As always, please
click the link, click Fork ripple,
and experiment. If you encounter any
cryptic error messages, please try pasting your
error message into Google and see what other
people have to say. Otherwise, feel free to post
questions in this course.
7. Objects Part 2: Welcome friends. In this video, we're going to wrap up our discussion
of objects. We mentioned object instantiation
in the previous video. Let's see how it works. First, recall that the dog
constructor looks like this. It has two arguments,
name and age. In our main class, we create two instances of
the dark class like so. First, as per the
Java tradition, we explicitly specify the type of the variable we are creating, which is the dark type. The next part over here, it looks almost
like a method call, except that we have
this keyword, new. The new keyword paired with the constructor call tells Java to first allocate memory for
a copy of the dog object. And once that memory
has been allocated, it calls the constructor. Running whatever code is in
the constructor definition. After running these
two lines of code, Bobby and Sam now have
their name and age data saved inside the first dog
and second dog instances. Since we save that data into their instance variables
which are persisted. Now, let's talk about static. Here's the dog class
from the last video, but with a few add-ons. We've added the static keyword between the access modifier and the type in the method
and variable declaration. Recall that variables
and methods without the static
keyword or non-static, also known as instance
variables and instance methods. As the name suggests, instance variables and
instance methods are specific to instances
of an object. However, static variables and static methods are the opposite. They cannot be bound to a
specific instance of an object. This dark example might
help you understand. If you want to know the
number of legs on a dog, do you need a specific dog
to answer that question? Of course not. You know that dogs in
general have four legs. The number of legs
on a dog is not specific to a particular
instance of a dog. On the other hand,
if you want to know the name or the age of the dog, we need a very specific dog
to answer that question. So instance methods
and variables are specific to particular
instances of the class. Static methods and
variables apply to all instances of the class. Let's take a look
at how we query static methods versus
instance methods. Since non legs is a public
and static attribute, we can ask access it directly
with dog dot non legs. Note that dog is not a specific instance
of the dog class. The dog class itself
has no name or age. We can also access
get numb tails directly to the dot class
without an instance. However, for get age, we need to access it through
a specific instance. Second dog, since only
specific instances of dogs have age data
associated with them. Also, note that we
can still access static methods and variables from an instance of an object. And again, if you think about
it, it's pretty intuitive. I can't tell you the age of the dog without a specific dog, but I can't tell you
how many legs and tails dogs have in general, if I give you a
specific Dr. reference. Here's the code
used in this video. As always, please
click the link for the ripple and tinker with the code to see what
works and what doesn't.
8. Comments: Welcome friends. In this video, we're going
to talk about comments. Sometimes Java code
can be very confusing, especially if you have
a code block that calls other methods and those methods
called even more methods. This causes problems later down the line as you'll
find that sometimes you have trouble understanding your code just after a few days. And if you ever plan on
collaborating with other people, you'll need to make sure
that your collaborators are able to understand
your code to. In order to assist
with code readability, Java has a way for
developers to add human-readable notes to their
code. Here's one example. Inline comments
are prefaced with double slash and
they're usually added either after the code in the same line or on the line
immediately above the code, the comment is describing
the texts that falls. The double slash is a
human readable piece of text that is not
executable by Java. It exists solely to
assist the human reader, the program with understanding with the adjacent code is doing. Here's another example. This is what we call
a Java doc comment. There are tools out there that will generate documentation for your code by scanning files for comments that
follow this format. We're not going to use a Java
doc tool in this course, but it's good for you
to know how to write neat and pretty
method descriptions. Java, doc, comments,
or multiline. They begin with a slash
star star, and star slash. Lines in-between should have a single asterisk
at the beginning. Typically, java
dot comments have a high-level description of
the method like we have here, followed by Program
and at return tags. If we had multiple arguments, we would have multiple
app per m tags. Each one would firstName the
perimeter it is describing, followed by a description
of what the argument is. The return tag is present for a non-void methods and it contains a description
of what is returned. It's not necessary to adhere
strictly to this format if you're not generating
documentation with the Java doc tool. But even if you aren't, it's generally good practice to follow this format
whenever you can. Here's the code
used in this video. Please visit the link, click, Fork, ripple, and
tinker with the code.
9. Arrays and ArrayLists: Welcome friends.
Congratulations on making it this far
in the course. In this video,
we're going to talk about arrays and ArrayLists. A couple of videos ago. When we first
covered Java types, we mentioned the array type, but we didn't really go into too much detail
about what it is. Today. We're going to revisit arrays in much greater detail. Recall that we first
saw a string array in the method signature
of the main method. Here's one way we
can create an array. If you already know
what values we want to use to initialize, we can populate it directly like so by specifying the
type of the array, in this case an integer array, and by including the values
and curly braces like so. If you don't know what values
you want to use just yet, we can first initialize
an array of zeros with the new keyword and by specifying the length of
the array in brackets. Then when we're ready
to populate the array, we can set the elements
directly like so. A couple of things to note here. First, an array's length is fixed and cannot be
changed once it's created. So both array one and array two are going to be length
three and they will always be. So. Second, array indices
begin at zero. In many languages
including Java, almost all indexing
across data structures, we'll start from zero as well. Now, if you want to print out all the elements in
the array one by one, we create a variable I to refer to the
index of the array. And we increment this value I by one until we reach the
length of the array, which we can look up by
using this attribute length. We can access an individual
element in the array with these brackets and
index from 01 or two, which referred to the first, second and third elements
respectively in the array. So those are arrays. Next up we have ArrayLists, which are a more flexible
version of arrays. Similar to arrays. Arraylists are also ordered
collections of items. However, one important
conceptual distinction is that ArrayLists are re-sizable and ArrayLists also have
different syntax. Let's explore these differences. The first is that ArrayList
are initialized like so. The thing in the angle
brackets specifies the type of element in
the ordered collection. And we only need to
explicitly provide the type on the left side of
the initialization. This line would instantiate an ArrayList with length zero. Also noticed that we use capital integer here
instead of lowercase int. This is something we call
a box to type in Java. It's not super relevant
for this course, so we don't need to spend
too much time on it. We call the int type
a primitive type, and the integer type with a
capital I, a reference type. Ints and integers are generally interconvertible and map
one-to-one to each other. E.g. an int value of one would map to an
integer value of one. All you really need to know is that the reference
type integer with a capital I is needed for some data structures
such as ArrayLists. Since ArrayLists can only accept reference types as its elements. This is just the way
java was designed. So don't dwell on it too much. Just keep it in mind. If
you ever tried to use an array list the next time
you go grocery shopping. Next, Here's how you add
elements to the list. So one is at index
012 is at index one, negative seven is at index
2.19 is at index three. We can also remove
elements from the list, which will delete the element at the specified index and
decrease the list size by one. In this case, we're going
to be removing index two, which in our example is going to be the value
of negative seven. So after running this line, we will have the value
one at index zero, the value 12 at index one, and devalue 19 at index two. Since all values after index two are going to be shifted by one to account for the deletion. Another difference is the way we get the length of the array. While I erase had a
public attribute length. Arraylists have a public
method called size. We also have list dot get here instead of brackets
to access elements. We're introducing a lot
of methods and attributes specific to erase an
ArrayList in this video, which might be a
bit overwhelming. If you feel this way. Don't worry. Computer science is not a discipline-based
on memorization. If you ever forget
something small, or if you're trying to find
some extra functionality to these data structures,
just Google it. Google results for basic
programming questions are usually very relevant since many people before
you likely had the same questions to ask when
they started programming. Finally, I'd like to show you a shorthand way of
iterating through the list. This code block does exactly the same thing
as this code block above the int element
tells Java that we're treating each item
in the list as a variable called element with type int and colon list tells Java that this is the
list we want to iterate over. As a side note, we
could have also written the type as integer
with a capital a here. Remember, int and integer are
generally interconvertible. We only needed to use
integer with a capital I when we declare the type of the ArrayList initially appear. Anyhow on the first iteration
of this code block, element is going to
be bound to one. On the second iteration, it's going to be bound to 12. You get the idea. Java just handles
the incrementing of the index variable for you
with this simplified syntax. Now, you may be asking yourself, ArrayList can do everything
that arrays can. And ArrayLists even have extra functionalities
since they can be resized. So why didn't the Java developers just removed or
erased from the language? Pause the video and I'll
reveal the answer in 321. The reason is that there is
a performance trade-offs involved when using an
ArrayList instead of an array. Arraylist with
reference types are generally a bit slower than arrays that use primitive types. For most use cases, though, the performance
trade-off isn't really noticeable enough to
make a difference. But it's something to keep in
mind if you ever happen to be working on something that
is sensitive to latency, like if you're programming and ultra high precision laser, or you're trying to build an
ultra-fast stock trading. But here's the code
using this video. Please visit the
link, click Fork, ripple, and tinker
with the code.
10. Sudoku: Hello friends. Congratulations on finishing all the instructional
videos in this course. Today, we get to use what
we've learned to build an interactive visual game that you can share it on my
resume and with your friends. I've linked a fairly
comprehensive document in the projects
and resources tab. Go ahead and click this link. And it should take
you to this document. I'll let you read
the majority of this document on your own time, but I'm going to go through
it briefly right now, just so you at least have a general idea of
what's going on. I'd like to preface
this by saying that this project is not
meant to be super-duper, easy, or finished within 10 min. I know some of the
other courses on this platform are dead simple, like write a class that
has three methods in it. But I don't really think you're
going to learn that much if that's all you're doing after going through
these videos. So this project may
require more thinking than other projects if you've done other Java courses
on this platform, but don't be discouraged. It was designed that way. So you can get experienced with a real coding assignment that actually encourages you to understand object
oriented programming. Be sure to read this
entire document. It is likely that you'll have many questions about
the project that are already answered here.
Before you begin. Make sure that you have created an account on repl it.com, and also makes sure that you
have verified your email. Otherwise you won't be able to fork and make changes
to the files. Once you've done so, visit
this link and fork the raffle. This project that we've linked
here is called a skeleton. What this means is that some of the code has
been done for you. Many methods have been left blank and have a comment to do blocks of code that have the todo comment means that you had to fill in the
code for that section. In this project, you're
going to be implementing Sudoku in case
you're not familiar. I've written a description of this game in the
overview section here. Here, I've written
a brief description of each of the files
in this project. The order in which
these are listed is the order in which you
should complete the project. You should do self first, then row, then
block, then board. Main has already
been done for you. Here, I've written out what
I just told you explicitly. After you complete each class, you should run all
the unit tests and ensure that the unit tests related to the class you
just finished our passing. First. After you complete cell, you should make sure that all the units has
related to sell pass. After you complete row, you should make sure
that all the unit tests associated with cell and
row pass, so on so forth. The next section here tells you how to actually
run the test. In the left panel of the
tools section on repl it, you'll be able to access tools. Tools. And after you
click on the Tools tab, you should be able
to see unit tests. Once you click on unit tests, you should be able to
see this window pop up, which has a Run Test button. Even though we haven't
started coding yet. Let's just run the unit
test and see what happens. Let's come back to
our Sudoku skeleton. Let's, again, we go
to the Tools tab. We click on unit tests
and we click Run tests. After we click Run tests, we can go over to
the console tab. I already have it open here, but in case you don't, you can find it in the
tools section. So in tools, you go to console. And now we can see the output. In this case we had zero out of 20 tests pass see errors above. So this is good. This means that all of our
tests are actually meaningful. Think about it. If any of our tests passed when no code has
even been written, that would be a very bad sign. That would mean
that the test isn't really testing anything at all. So after you complete
the project, all of these tests should pass. The next section here, I've written some debugging tips in case you have some trouble. However, since you are
likely new to programming, it's totally okay if you're unable to solve the issue alone. If you run into any issues,
you have two options. Option one is to take a
quick peek at the solution, which I posted at the very
bottom of this document. Option two is to post a question on the Skillshare
course under the, under the discussion tab. And I'll get back to
you as soon as I can. Finally, after you've
passed all the unit tests, you can click the
big green button. Playing the game
should look like this. Here's my solution. So you click the green button. After it's done compiling, it runs the program
and it prints out this Sudoku board that has
some values filled in. Now we can play with this game. So let's say e.g. that we would like
to put the number, let's say two in dislocation. So this is going to
be row number one, since this row of
periods, row zero. So this is row one, and this is column one, because this one right
here is column zero. Let's say set 11 to be two. And you can see that two has now been populated in dislocation. If we want to undo that, we can do clear 11 because
11 is the coordinate that we're clearing and we'll
get that to be empty again. Now, let's try to
put in a nine here, which shouldn't work because we already have a nine
in this block. We set 11 to B9. It's kinda tell
you block zero has multiple names and it will
not let you put a nine there. If you get frustrated
and you don't want to finish a Sudoku puzzle anymore, you can just type solve. And now it will solve the
entire board for you. And it will exit
the program telling you that you need to run
the run button again, if you want a new puzzle, There's a possibility
that the unit tests I wrote or
not comprehensive. I'm fairly certain that
if you pass a unit test, you should be able to run
the game successfully. However, if you pass all the unit tests and you're still unable to run
the game properly. I'd recommend you
just cross compare your solution with
the one I posted. When you find the discrepancy, please post a note in the
Skillshare course so I can fix the skeleton or unit test
if they need to be fixed. Once again, remember to
read this document in its entirety and refer
back to it frequently. And that's all I had
to say for this video. Have fun on your first
real coding assignment.