Java
Skipped: Recursion
Lecture Notes
Lecture Notes
Source Code: '.java' files you write source code in.
Java is a statically-typed language (must assign type to variable in declaration; variables can't switch types)
Portable 'byte' Code: the compiler (javac) generates byte code in a ‘.class’ file which can be run on any Java Virtual Machine (JVM). JVM efficiently interprets* byte code in the .class file into native machine code (binary) and executes it.
The Java Platform consists of 2 parts:
JVM
Java API (huge library of handy software packages that programmers can use)
When running Java Programs:
javac filename.java
= compile code.The compiler (javac) generates the '.class' file which contains instructions for the JVM.
'.class' files contain 'byte code' which you can't edit
java filename.java
= execute code
Create 1 Folder per program as to organize and group the .class files to their corresponding .java files.
In Java, every statement must end in a semicolon.
Integer Division and Remainder
When integers divide into each other, the result is an integer.
Integer division loses all fractional parts of the result and does not round.
The Main Method
The
main()
method is required and you will see it in every Java program. Any code inside themain()
method will be executed.Remember that every Java program has a
class
name which must match the filename, and that every program must contain themain()
method.
Comments
Single-line: // comment
Multi-line: /* comment */
Formatting with printf()
neat shortcut in printing instead of print() and println()
Syntax
Formatters: %d - int %f - double %.2f - 2 decimals places after period (3.141592653589 -> 3.14) %c - char %s - string %b - boolean %n - newline
Variables
Variables are containers for storing data values, and there are different types of variables:
Variable Declaration
declaring a variable means specifying a
variable name
and itsdata type
.
Variable Initialization
initializing a variable means assigning a value to the variable.
(Note that if you assign a new value to an existing variable, it will overwrite the previous value.)
Final
Variable Types
When a variable is defined with the reserved word
final
, its value can never be changed.It is customary (not required) to use all UPPER_CASE letters for constants (easy to pick out constants in the code)
Variable Scope
Local Scope - variables declared and only existing inside methods ie. formal parameter variables.
Block Scope - variables decalred and only existing within their parent { }'s.
Global Scope - variables which can be used and changed by code anywhere.
General rules for variable naming:
can contain letters, digits, underscores, and dollar signs
must begin with a letter
snakeCase
can also begin with $ and _
are case sensitive
Reserved words cannot be used as names
Data Types
Data types are divided into two groups:
Primitive data types
specifies the size & type of variable values, and has no additional methods.
int
whole numbers between -2,147,483,647 (Integer.MIN_VALUE) and +2,147,483,647 (Integer.MAX_VALUE). Use long/short outside this range.
Whole number
float
The single-precision floating-point type with about 7 decimal digits and a range of about +/- 1e38.
double
The double-precision floating-point type, with about 15 decimal digits and a range of about +/- 1e308.
short
The short integer type with range -32,768 ... +32767.
Whole number
long
The long integer type with about 19 decimal digits.
Whole number
byte
The type describing a byte consisting of 8 bits, with range -128 ... 127
Whole number
char
The character type representing code units in Unicode
Characters (no math)
boolean
True or False
Reference data types
are called reference types because they refer to objects.
Class
,object
,array
,string
, andinterface
The main differences between the two:
Primitive types are predefined in Java. Non-primitive types are created by the programmer and is not defined by Java (except for
String
).Non-primitive types can be used to call methods to perform certain operations, while primitive types cannot.
A primitive type has always a value, while non-primitive types can be
null
.A primitive type starts with a lowercase letter, while non-primitive types starts with an uppercase letter.
The size of a primitive type depends on the data type, while non-primitive types have all the same size.
Note:
Strings use "" and chars use ''
Max and Min value for an int is +2,147,483,647 and -2,147,483,647, respectively (for any values above max or below min, use the long , short, or double data type). This value is found in
Integer.MAX_VALUE
andInteger.MIN_VALUE
.
Number Literals
Sometimes when you just type a number in an expression, the compiler has to ‘guess’what type it is:
Type-Casting
Variable Conversion:
Ex.
Operators
Arithmetic Operators: +
, -
, *
, /
, %
, ++
, --
Note: comparison operators have lower precedence than arithmetic operators so:
Assignment Operators
Comparison Operators: ==
, !=
, >
, >=
,<
, <=
most of these comparison operators ( >, <, >=, and <=) can be applied only to primitives. Two (== , !=) can be used for any object but when applied to reference types, they test if they point to same object rather than have same value.
Logical Operators: &&
, ||
, !
Methods
Creating and Calling Methods
Method Parameters
Formal Parameters: parameters in function signature
Actual Parameters: actual values passed to function call
Return
Code underneath a
return
call is unreachable code.The type of the value returned must match the return-type specified in a method's signature.
A method can use multiple
return
statements.Methods are not required to return a value. In this case, the return-type in the method signature should be
void
Method Overloading
multiple methods can have the same name with different parameters. It will call the function whose actual parameters match the formal parameters types and positions in the function call.
Method Comments
To write a Javadoc comment above each method:
/**
Note the purpose of the method
@param - describe each parameter variable
@return - describe the return value
*/
String Methods
toLowerCase()
- converts a string to lower case letters.
toUpperCase()
- converts a string to upper case letters.
length()
- returns int value of the number of characters in string. The length of an empty string is 0
contains()
- finds out if a string contains a sequence of chars. Returns true if the chars exist; false if not.
equals()
- compares two strings, and returns true if the strings are equal, and false if not.
equalsIgnoreCase()
- compare strings to find out if they are equal AND IGNORE CASE DIFFERENCES
Don't compare strings using the == operator since it will check if the two Strings point to the same object since Strings are reference types.
compareTo()
, compareToIgnoreCase()
- returns An int value:
0 if the string is equal to the other string.
< 0 if the string is lexicographically less than the other string.
> 0 if the string is lexicographically greater than the other string (more characters).
indexOf()
- returns the index of the first occurrence of specified char(s) in a string
lastIndexOf()
- returns the index of the last occurrence of specified char(s) in a string
concat()
- appends/concatenates a string to the end of another string
replace()
- searches string for specified char(s), and returns new string where specified char(s) are replaced
trim()
- removes whitespace from both ends of a string. This method does not change the original string
startsWith()
- checks whether a string starts with the specified char(s).
endsWith()
- checks whether a string ends with the specified char(s).
charAt()
- returns the char at the specified index in a string
split()
- splits a string at a specified char and creates an array; parameter is what's being removed.
If you split a string and an int, they both become strings so convert using Integer.valueOf()
subString()
- returns a substring of this string; from the first index to the second (exclusive); otherwise extends to the end of this string
copyValueOf()
- returns a String that contains the characters of the character array
Math Methods import java.lang.Math;
import java.lang.Math;
xxxValue()
- returns the primitive data type that is given in the signature.
parseXXX()
- used to get the primitive data type of a certain String.
abs()
- gives the absolute value of the argument.
ceil()
- returns the smallest integer that is greater than or equal to the argument.
floor()
- returns the largest integer that is less than or equal to the argument.
rint()
returns the integer (double.0) that is closest in value to the argument. Parameter must be double
round()
- returns the closest long or int to the argument. Parameter must be double or float
min()
- gives the smaller of the two arguments
max()
- gives the larger of the two arguments
pow()
- returns the value of the first argument raised to the power of the second argument.
sqrt()
- returns the square root of the argument.
cbrt()
- returns the cube root of the argument.
Math.PI
- returns the value of pi to the 15th decimal.
random()
used to generate a random number between 0.0 and 1.0
Conditionals
If
If-Else
Else-If
For
For-Each
(arrays)
While
Do-While
Continue
- breaks out of the inner loop and goes to the top of the outer loop.
Break
- breaks out of the current loop
Switch-Case
Modulo
Try-Catch
Ternary Operator
The Java ternary operator functions like a simplified Java if statement.
The ternary operator consists of a condition that evaluates to either true or false, plus a value that is returned if the condition is true and another value that is returned if the condition is false.
Format
System.out.println( expression ? "true" : "false");
System.out.println( expression ? "true" : expression2 ? "false" : "maybe");
Here are some simple Java ternary operator examples:
? checks if statement is true; if yes, print what follows the question mark
: separates the "arguements". If the first one is false, it goes to second argument
Misc
Swapping Values;
Import Keyword
The import keyword is used to import a package, class or interface.
Input
The
Scanner
class allows you to read keyboard inputs from the user.Reading certain variables:
Escape Sequences
allows us to use special characters inside strings as visual components rather than functional ones. Ex. using quotes "" inside a String which has ""s already gives some funky errors.
Preface the special character with a \
does a newline in a string
Use of Epsilon
Use a very small value to compare the difference if floating-point values are ‘close enough’
The magnitude of their difference should be less than some threshold.
Enum
Enum is short for "enumerations", which means "specifically listed".
Use
enums
when you have values that you know aren't going to change.An
enum
is a special "class" that represents a group of constants.To create an
enum
, use theenum
keyword and separate the constants with a comma.You can access
enum
constants with dot notationEnum iteration
The enum type has a
values()
method, which returns an array of all enum constants. This method is useful when you want to loop through the constants of an enum:
Sentinel Values
Sentinel values are often used when you don't know how many things you're going to get from input.
A Sentinel value is simply a value which when picked up by the Scanner, will stop reading the input and do something else.
A Sentinel value denotes the end of a data set, but it's not apart of the data!
But sometimes you might even have -1 in the dataset, so instead you can use a non-numeric sentinel (entering a non-numeric value as input would end the input)
Static Blocks
A block of code which is executed before the main method at the time of classloading.
Wrapper Classes
Java provides wrapper classes for primitive types
Conversions are automatic using auto-boxing:
Primitives and their Wrapper-Equals:
byte=Byte
,boolean=Boolean
,char=Character
,double=Double
,float=Float
,int=Integer
,long=Long
,short=Short
.
You cannot use primitive types in an ArrayList, but you can use their wrapper classes
Data Structures
¬ Arrays
Arrays are used to store multiple values in a single variable, instead of declaring separate variables for each value.
You don't need to import any packages for Arrays (you do though for Arraylists)
With arrays, the size cannot be modified. If you wanted to add or remove elements from an array, you'd have to create a new one.
Use an Array if: The size of the array never changes, You have a long list of primitive values (efficiency reasons), Your instructor wants you to.
Use an ArrayList if: For just about all other cases, Especially if you have an unknown number of input values.
Declaration
- define the variable type with square brackets:
Initialization
- use an Array literal to insert values; place the values inside curly braces:
Printing
- import java.util.Arrays;
Accessing Elements
- access an array element by referring to the index number (arrays start at 0)
Make sure the index you provided is exists or else you'll get a IndexOutOfBoundsError
Empty arrays hold
null
values by default
Changing Array Elements
- to change the value of a specific element, refer to the index number
Arrays are mutable
Array Length
- find out how many elements an array has, use the .length
property
Iterating over an Array
Iterating using For-Each loop
For-each loops are used exclusively to loop through elements in arrays. This loop goes through the array 1 by 1 and assigns it to the variable.
Common Array Algorithms:
Sum and Average Values
Find the Maximum or Minimum
Linear Search
Removing an Element and maintaining order
Inserting an Element and maintaining order
Growing an Array
Copying Arrays
- Not the same as copying only the reference; Copying creates two set of contents!Reading Input
Case A: Known number of values to expect - Make an array that size and fill it one-by-one
Case B: Unknown number of values - Make maximum sized array, maintain as partially filled array
¬ 2D Arrays
You don't need to import any packages for 2D Arrays.
2D Arrays have Rows & Columns and is aka ''Matrix'.
Declaration
Use two ‘pairs’ of square braces:
<type>[][] <name> = new <type>[#rows][#cols]
#rows is basically the number of arrays in the the 2d array
#cols is basically the size of each array in 2d array (given they are all the same size)
Accessing
Use two index values:
int value = counts[3][1];
gets element at index-3 ROW & index-1 COL.
Iteration
Use nested for loops where Outer row(i) , inner column(j):
Locating Neighbouring Elements
![Screen Shot 2022-01-31 at 1.04.36 PM](/Users/dev/Library/Application Support/typora-user-images/Screen Shot 2022-01-31 at 1.04.36 PM.png)
¬ ArrayLists
(import java.util.ArrayList
)
The ArrayList is a resizable array where elements can be added and removed from an ArrayList whenever you want.
Recall that arrays' size cannot be modified (if you wanted to add/remove elements, you'd have to create a new one)
Declaration
Creating an ArrayList object:
ArrayList<TYPE> NAME = new ArrayList<TYPE>();
Initialization
- you can pass an iterable in the declaration using the Arrays.asList( item1 , ... , itemN )
Add Items
- add()
Printing Lists
- unlike arrays, you can simply println arraylists:
Getting Index of Items
- indexOf()
indexOf()
returns the first occurence of the specified item in the list, otherwise returns -1:
Checking for Item
- contains()
To check the existence of an item in a list, use the
contains()
method, which returns true/false:
Accessing Items
- get()
To access an element in the list, use the
get()
method and refer to the index number:
Changing Items
- set()
To modify an element, use the
set()
method and refer to the index number and the new element:
Removing Items
- remove() , clear()
To remove an element, use the
remove()
method and refer to the index number:To remove all elements in the list, use the
clear()
method:
Size
- size()
To find out how many elements an ArrayList have, use the
size()
method
Sorting List (+reverse)
import java.util.Collections;
use the 'Collections' class to
sort()
lists alphabetically (uppercase take priority over lowercase) or numerically (least to greatest)To sort in reverse order {greatest to least} and {descending alphabetical order}, add Collections.reverseOrder() to the Collections.sort() call as a second argument:
Iterating Through List
There are two ways of looping through a list: a for-loop, and a for-each loop:
¬ Stacks
(import java.util.Stack
)
Stacks are an abstract data type with a bounded(predefined) capacity.
To help visualize Stacks, parallel it to a stack of video games, where the first element added to the stack is at the bottom. Every time you add a video game, it gets added ontop of the stack.
Declaration
Adding to Stack
Accessing Values
Removing from Stack
Peeking
Check for Element
Check If Empty
Size
¬ Queues
(import java.util.Queue
| java.util.LinkedList
)
Java Queues order elements in a FIFO (First In First Out) manner. In FIFO, first element is removed first and last element is removed at last.
To help visualize Queues, parallel it to a line at backyard bbq (or anything where people line up for something), where you give bbq to the person infront of the line. After, they've been served, they leave the line. Queues work in just that way!
Declaration
Adding to Queue
Removing from Queue
Peeking
Size of Queue
Check for Element
Convert to Array
Iterating Queue
¬ HashMaps
(import java.util.HashMap
)
Hashmaps store items in key/value pairs (equivalent of Python's Dictionaries)
HashMap is known as HashMap because it uses a technique called Hashing - technique of converting a large String to a small String that represents the same String. A shorter value helps in indexing and faster searches
In ArrayLists, you learned that Arrays store items as an ordered collection, and you have to access them with an index number. A Hashmap however, stores items in "key/value" pairs where you can access the 'value' if you provide the 'key'.
Hashmaps can store different types:
(String keys && Integer values) or the same type (String keys && String values)
Creating a Hashmap
Adding to Hashmap
Accessing Items
Removing Items
Replacing Values
Retrieving
Checking for Key/Value
Size
Looping over HashMap
OOP
OOP stands for Object-Oriented Programming.
Procedural Programming - writing procedures or methods that perform operations on the data.
Object-Oriented Programming - creating objects that contain both data and methods
Container Class vs. Definition Class
Container Class vs. Definition Class
Container Class - a collection of static methods that aren't bound to any particular object. These static methods usually have something in common.
The
Math
class is an example of a container class. It's essentially a container for math utility methods. Notice that you call these static methods with dot notation:<ContainerClass>.<StaticMethod
ie.Math.sqrt()
However, for even moderately complex programs a large collection of methods can quickly becomes difficult to manage
Definition Class - these classes define new objects. THIS IS THE FOCUS IN CPS209
Classes & Objects
¬ Class
used to define a new data type aka a blueprint for creating objects.
Each class contains fields / attributes (variables) and behaviours (methods).
The ClassName should always start with an uppercase first letter and match the name of the java file.
To create a class, use the
class
keyword:CLASS - an abstract view
We usually begin by creating an abstraction of a Class:
What does an object of this class represent?
What's the interface (methods) of this class?
The class interface is realized via methods
What's the internal state of the class?
We use variables/fields to represent the internal state.
EX. Consider the Abstract view of a Clock Class
A
Clock
class object represents a 12-hr clockIt's interface (methods) allow telling the clock that a second has elapsed (one method for this), and querying the clock to retrieve the time (one for this).
¬ Object
a specific instance of a class with defined attributes.
the
new
keyword is used to create an object instance of a class. [ClassName objName = new ClassName(params)
]To create an object:
Object References
Object reference variables store the location of an object in memory, not the object itself. That is, the
new
operator returns the location (a memory address) of the new object and stores this location in the reference variable.Multiple reference variables can refer to the same object:
In memory, the addresses of clock1 & clock2 reference variables hold the same address of the Clock Object (ie. 0x7104).
Null Reference
A reference variable may be set to point to no object at all (null)
You can't call methods of an objcet using a refernce variable that's pointing to null; Causes a run-time error
Garbage Reference
Reference vars. that's aren't initialized refer to random locations in memory; You can only call methods using the Reference var. if it is referring to a valid object
Constructors
special method that's used to initialize objects.
The constructor is called when an object of a class is created, and is used to initialize the attributes in a newly created object.
The line of code which defines the constructor name and other info is called the constructor signature.
Rules for creating constructors:
must have the same name as the class
cannot have a return type (void)*
cannot be abstract, static, or final
(can still be private, protected, public or default)
Default (No-Argument) Constructor
- created by default by the java compiler at the time of class creation if no other constructor is declared in the class. Doesn't contain any parametersParameterized Constructor
- contains one or more parameters used to initialize attributes
Overloading Parameterized Constructors
You can overload parameterized constructors
Basically: multiple constructors with same name but different parameters; different ones get called when creating an object depending on which parameters are passed
Constructors vs. Normal Methods
Instance Variables
A variable which is created inside the class but outside constructors/methods is known as an instance variable.
You can acess and update instance variables (which aren't 'final') using
dot notation
:Ways to Initialize Objects
via assigning values to instance variables manually with dot notation:
via setter methods:
via constructor (most common)
Static Methods
methods which have the
static
keyword in their signature belong to a class rather than an instance of a class.Static methods can only reference static variables or local variables (within the method)
Static methods can't read/set instance variables because they can't refer to this or instance variables since they're called with the CLASSNAME, not an OBJECT.
You can call it without creating an object; They are called by the class name itself:
<className>.<staticMethod>();
. If you're referencing static variables/methods in the same class, treat them with global scope.
Instance Methods
The method of the class is known as an instance method.
It's a non-static method defined in the class.
Unlike static methods, instance methods can access static variables.
Before calling or invoking the instance method, it is necessary to create an object of its class
There are 2 types of instance method:
Accessor Method (GETTER)
Methods used to get instance variables
Usually prefixed with 'get'
Asks the object for info and normally returns a value of some variable
Mutator Method (SETTER)
Methods used to update values of instance variables usually prefixed with 'set'
Return type is normally
void
.Usually take a parameter that will change an instance variable.
this
The keyword this can be used in a class to refer to the current calling object
'this' is used in the constructor to set the instance variables.
Static methods cannot refer to this or instance variables because they are called with the classname, not an object, so there is no this object.
You may invoke the method of the current class by using the this keyword:
4 Pillars of OOP
1. Encapsulation
process of wrapping code and data together into a single unit.
The goal is to make sure that "sensitive" data is hidden from users.
This is achieved via:
Packages
A java package is a group of similar types of classes, interfaces and sub-packages. (Think of it as a folder in a file directory)
We use packages to avoid name conflicts, and to write a better maintainable code (modularize code).
Packages are divided into two categories:
Built-in
Packages (packages from the Java API)User-defined
Packages (create your own packages)
To create a package:
use the
package
keyword:The package name should be written in lower case to avoid conflict with class names
Save the file as MyPackageClass.java, and compile the file:
Compile the package:
This forces the compiler to create the "mypack" package.
The
-d
keyword specifies the destination for where to save the class file (. is current working directory)
When we compiled the package above, a new folder was created, called "mypack".
Access Modifiers
access modifiers specify the scope of a field (variable), method, constructor, or class.
There are many non-access modifiers, such as static, abstract, synchronized, native, volatile, transient, etc
A
member
is a variable/method/constructor of a class; members of a class can be declared the following 4 access modifiers (listed st. first is most restrictive, and last, the least):Private
private scope is only within the class; it cannot be accessed from outside the class.
If you make any constructor private, you cannot create the instance of that class from outside the class.
With Private, we perform data-hiding; hide the internal implementation of the class by declaring its state variables and auxiliary methods as private. (Encapsulation)
Default
default scope is only within the package; it cannot be accessed from outside the package.
If you do not specify any access level, it will be the default.
Protected
protected scope is within the package and outside the package through child class.
If you do not make the child class, it cannot be accessed from outside the package.
Public
public scope is everywhere; it can be accessed from within the class, outside the class, within the package and outside the package.
If you don't want to reveal the internal state of the object’s data don't declare its state variables as public. (Encapsulation)
Note: If you are overriding any method, the overridden method (ie. declared in subclass) must not be more restrictive
ie. you can't override a protected (#3 restrictive) method with a default (#2 restrictive) method since #2 is more restrictive than #3. This causes a compile-time error.
Providing GETTER(s) & SETTER(s)
By providing only a getter / only a setter method, you can make the class read-only / write-only.
This allows for: more control over the data , data hiding , and easy testing.
2. Inheritance
Inheritance is a mechanism in which one class can inherit all attributes (variables) & behaviours (methods) of a parent class.
parent class | | superclass - class being inherited from.
child class | | subclass - class that is inheriting.
Inheritance represents the IS-A relationship which is also known as a parent-child relationship
Inheritence is great because it allows: code reusability & runtime polymorphism.
Code reusability = when you inherit from an existing class, you can reuse attributes and behaviours of the parent class. Moreover, you can add new attributes and behaviours in your current class.
Types of Inheritence
Single - when a class inherits another class. (a -> b)
Multilevel - when there is a chain of inheritance. (a -> b -> c)
Hierarchical Inheritance - when two or more classes inherits a single class. (a, b -> c)
IS-A vs. HAS-A
IS-A
:
An IS-A relationship is inheritance. The child class is a type of parent class.
static (compile time) binding.
HAS-A
:
A HAS-A relationship is composition; meaning creating instances which have references to other objects.
dynamic (run time) binding.
To make a subclass inherit from a superclass, use the
extends
keyword:
While a person can have two parents, a Java class can only inherit from one parent class. If you don't specify a superclass with 'extends', the class will default-inherit from the
Object
class.
Substitution Principle
You can always use a
subclass object
when asuperclass object
is expected as a parameter to a method.
Super()
Subclasses inherit public methods from the superclass that they extend, but they cannot access the private instance variables of the superclass directly and must use the public GETTERs & SETTERs.
Subclasses do not inherit constructors from the superclass
super() solves the quesiton of: "how do you initialize the superclass’ private variables if you don’t have direct access to them in the subclass?"
The superclass constructor can be called from the first line of a subclass constructor by using the special keyword super() and passing appropriate parameters
If a subclass doesn't call the superclass' constructor with
super()
as the first line in a subclass constructor then the compiler will automatically add asuper()
call as the first line in a constructor.The keyword super can be used to call a superclass’s constructors and force-use its methods.
You want to still execute the superclass method, but you also want to override the method to do something else. But, since you have overridden the parent method how can you still call it? There are two uses of the keyword
super
:super(); or super(arguments); - calls just the super constructor if put in as the first line of a subclass constructor.
super.method(); - calls a superclass’ method (not constructors).
Overriding Methods
We also usually add more methods or instance variables to the subclass.
overriding inherited methods - providing a public method in a subclass with the same method signature (name, parameter type list, and return type) as a public method in the superclass.
The method in the subclass will be called instead of the method in the superclass.
You may see the
@Override
annotation above a method. This is optional but it provides an extra compiler check that you have matched the method signature exactly:NOTE: YOU SHOULD NEVER OVERRIDE VARIABLES. Each object would have two instance fields of the same name. ("Shadow Variable")
Overloading methods
Overloading inherited methods - when several methods have the same name but the parameter types, order, or number are different.
So with overriding, the method signatures look identical but they are in different classes, but in overloading, only the method names are identical and they have different parameters.
Superclass References
A superclass reference variable can hold an object of that superclass or of any of its subclasses.
This is a type of polymorphism.
Passing subclass objects as parameters
We can write methods with parameters of the superclass type and pass in subclass objects to them.
Similar for arraylists:
3. Polymorphism
Poly = many, morphism = forms; so Polymorphism = many forms
Polymorphism in Java is the ability of an object to take many forms; allows us to perform the same action in many different ways.
Any Java object that can pass more than one IS-A test is considered to be polymorphic (really all objects in Java which have even just one IS-A, are polymorphic since all Java objects by default, inherit from
Object
)JVM looks at type of object the reference variable is pointing to (i.e at run time)and executes the correct method for that object.
It's always OK to convert subclass reference to superclass reference but not other way around.
If you want to convert
superclass ref. variable
tosubclass
, you mustcast
:Make sure superclass ref. variable is referring to a subclass object using the
instanceof
keyword:
Object: The superclass of all classes
All classes etend Object
most useful methods in class Object:
String toString()
Returns a string representation of the object
Useful for debugging
ie. toString() in class Rectangle returns something like:
java.awt.Rectangle[x=5,y=10,width=20,height=30]
toString() is used by concatenation operator
toString() in class Object returns class name and object address:
ie. Employee@d2460bj
It's common to OVERRIDE the toString() method
boolean equals(otherObj)
equals() tests for
equal contents
note: == tests for
equal memory locations
of objectsMust cast the "otherObj" parameter to subclass
clone()
Abstract Methods and Classes
When you extend a class, you have the choice to override a method (or not)
Sometimes want to force the subclass creator to override a method
method might be common to all subclasses so should define it in superclass but there is no good default implementation
You can make the method abstract (just signature, no body)
ie. abstract public double area();
Now subclass can implement method area();
If a class has >= 1 abstract method, whole class must be made abstract
ie. class is made abstract by: abstract public class BankAccount
You can’t create objects of abstract classes; abstract classes are used to define a common interface and behavior for all subclasses.
Abstract classes can have instance variables, abstract methods, concrete methods.
A subclass inherits said instance variables and methods. It must then implement abstract methods. If the subclass doesn't implement the abstract method(s), it too becomes abstract
You can also prevent others from creating subclasses and overriding methods using the
final
keyword.
Interfaces
In general terms, an interface is a container that stores the signatures of the methods to be implemented in code segments. (it's an outline for a class)
An interface can be thought of as a 'connector' b/n the general methods in the container and your code segments.
$ Defining
An Interface can only have method signatures, fields and default methods (skeleton code). You have to write the code for these methods inside your class.
To define an interface, use the
interface
keyword:
$ Implementing
The interface alone is not of much use, but they're used along with Classes which help further define them.
Use the
implements
keyword to indicate that a class implements an interface type.A class can implement > 1 interface.
There are ground rules:
The Class must implement ALL of the methods in the interface
The methods must have the exact same signature as described in the interface
The class doesn't need to declare the fields; only the methods.
An interface can't contain a constructor method. Therefore, you can't create instances of the Interface itself.
Interfaces vs. Classes
An interface type is similar to a class, but there're some important differences:
All methods listed in an interface type are abstract;
i.e. they don't have any code!!
All methods listed in an interface type are automatically public
An interface type does not have instance variables!
Inheritance (Class) defines a is-a relationship
Strong relationship b/n super and cubclass
Interface defines a has-a relationship:
Share some behaviour, but that's all
Converting b/n Class & Interface types
You can convert an instance variable from a class type --> interface type, provided the class implements the interface.
To convert the instance variable from a interface type --> back to --> class type, use (casting):
Polymorphism & Interfaces
Interface reference variable holds reference to object of a class that implements the interface:
Note:
the object to which m points to is not of type Measurable. It's type is the class that implements the Measurable interface (BankAccount).
The variable m itself is of type Measurable
Say two classes BankAccount & Clock both implement Measurable interface. Each class will have their own implementation of the getMeasure().
How will we know whose getMeasure() is being called?
Polymorphism says that it depends on the actual object.
So if m refers to a BankAccount, it'll call BankAccount's getMeasure(). If it refers to a Clock, then it'll call Clock's getMeasure().
Polymorphism
- behaviour (methods) can vary depending on the type of the object calling it."Binding" is the association of a method call with the method definition. There are 2 types of binding:
late-binding
- happens at compile time.early-binding
- happens at run time.
Polymorphism vs. Overloading:
Similarity: both describe a situation where one method name can denote multiple methods.
Difference:
overloading is resolved early by the compiler, by looking at the types of the parameter variables.
Polymorphism is resolved late, by looking at the type of the implicit parameter object just before making the call
Exception Handling & IO
> Throwing Exceptions
Throwing exceptions is the solution to the problem of erroneous functions which may or may not throw errors.
Exceptions can't be overlooked/ignored and are sent directly to an exception handler (not just to the caller of the failed method)
You THROW an EXCEPTION OBJECT to signal an exceptional condition; there's no need to store this object in a variable.
When an exception is thrown:
Method terminated immediately (kinda like 'return')
Excecution continues in an exception handler
> Checked & Unchecked Exceptions
There are 2 types of exceptions:
Checked - compiler checks that you don't ignore them
they're due to external circumstances that the programmer can't prevent ie. User I/O
ie.
IOException
Unchecked - extends the class RuntimeException or Error
they're typically the programmer's fault
Examples of runtime exceptions:
NullPointerException
Examples of errors:
OutOfMemoryError
> Exception Handlers
exception handlers are created with try/catch blocks
try - contains statement that may cause an exception
catch - contains handler code to deal w/ particular exception type
I/O
To read a local file, construct a file object, then use the file object to construct a scanner object:
To write to a file, construct a
PrintWriter
objectYou must close a file after you're done processing it:
Handling FileNotFoundException
When a FileNotFoundException occurs (thrown by the File constructor), you have 2 choices:
Handle the exception inside the method (with a try-catch)
Tell the compiler that you want the method to be terminated when the exception occurs.
The throws keyword indicates that the method will [potentially] throw a CHECKED EXCEPTION. For multiple exceptions, just separate with comma:
Keep in mind the INHERITANCE HIERARCHY for exceptions; if a method can throw IOException & FileNotFoundException, we know that FileNotFound inherets from IO therefore, only use IOException.
Catching Exceptions
Creating Custom Exception Types
You can design your own exception types (subclasses of Exception or RuntimeException)
Make it an UNCHECKED exception
Extend RuntimeException or one of its subclasses
Supply 2 constructors:
default constructor
constructor that accepts a message string describing reason for exception
Collections
A collection is simply an object that represents a group of objects into a single unit.
Collection Framework
- a unified architecture or a set of classes and interfaces for representing and manipulating collections. i.e. collection framework is used to store, retrieve and manipulate collections.
> Lists & Sets
A list is a collection that maintains the order of its elements
Ordered Lists:
ArrayList –– stores a list of items in a dynamically sized array
LinkedList –– allows speedy insertion and removal of items from the list
A set is an unordered collection of unique elements.
Unordered Sets:
HashSet –– uses hashtables to speed up finding/adding/removing elements
TreeSet –– uses a binary tree to speed up finding, adding, and removing elements
> Stack & Queues & PriorityQueues
Another way of gaining efficiency in a collection is to reduce the number of operations available. 2 examples are:
Stack –– remembers the order of its elements, but it does not allow you to insert elements in every position. You can only add and remove elements at the top.
Queue –– add items to one end (the tail), remove them from the other end (the head).
PriorityQueues –– collects elements, each of which has a priority. Remove lowest number first
> Maps
A map stores keys, values, and the associations between them
Keys –– provides an easy way to represent an object
Values –– actual object associated with the key
> LinkedList
use references to maintain an ordered lists of nodes.
The head of the list references the first node.
Each node has a value and a reference to the next node.
Efficient Operations
Insertion of a node –– Find the elements it goes between. Remap the references.
Removal of a node –– Find the element to remove. Remap neighbor’s references
Visiting all elements in order
Inefficient Operations
Random access.
Iterators
List Iterators
When traversing a LinkedList, use a ListIterator to:
keep track of where you are in the list.
access elements inside a linked list.
visit other than the first and the last nodes.
Note:
When calling .add(...) ,
the new node is added AFTER the Iterator.
the Iterator is moved past the new node.
When calling .remove() ,
it removes the object that was returned with the last call to next or previous.
it can be called only once after next or previous.
You cannot call it immediately after a call to add.
Last updated