Topics
Important Points
Java Casting
Regarding the casting, CS2030S has introduced two very useful rules on deciding the Run Time Error and Compile Time Error. The tricky problem in CS2113 also gives you a glimpse of how to apply the rules.
From the topics, there are some important rules
RunTime Behavior
Due to polymorphism, the behavior of the object will reflect the actual type of the object irrespective of the type of the variable holding a reference to it. For example,
// Some codeAnimal a = new DomesticCat(); //implicit upcast
a.speak();
Cat c = (Cat)a; //downcast
c.speak();
DomesticCat dc = (DomesticCat)a; //downcast
dc.speak();
// Output
// I'm a DomesticCat
// I'm a DomesticCat
// I'm a DomesticCatCasting error only in run-time
As we have seen in CS2030S, exceptions are always triggered at run-time!
Casting to an incompatible type can result in a ClassCastException at runtime. If the casting is incompatible at the compile time, a compile time error (not exception) will be given.
Java Abstract Classes
In CS2030S, I have provided a quite solid motivation for Java Abstract Class, feel free to go back and take a look.
Here, there are some importants points regarding Java Abstract Class,
Subclass of an abstract class
There are two possibilities for the subclasse of an abstract class, it can be
another abstract class
For example,
public abstract class Feline extends Animal {
public Feline(String name) {
super(name);
}
}
public class DomesticCat extends Feline {
public DomesticCat(String name) {
super(name);
}
@Override
public String speak() {
return "Meow";
}
}Code Explanation
The
Felineclass below inherits from the abstract classAnimalbut it does not provide an implementation for the abstract methodspeak. As a result, theFelineclass needs to be abstract too.The
DomesticCatclass inherits the abstractFelineclass and provides the implementation for the abstract methodspeak. As a result, it need not be (but can be) declared as abstract.Thus,
Animal a = new Feline("Mittens");will generate a compile-error whileAnimal a = new DomesticCat("Mittens");is okay!
Java Interfaces
Again, the motivation for Java Intefaces has been given in CS2030S in detail! Strongly advised to go visit them again!
Here, only some extra points are noted,
Interface inherits from other interfaces
Interfaces can inherit from other interfaces using the extends keyword, similar to a class inheriting another. For example,
public interface SelfDrivableVehicle extends DrivableVehicle {
void goToAutoPilotMode();
}Multiple inheritance among interfaces
A Java interface can inherit multiple other interfaces. A Java class can implement multiple interfaces (and inherit from one class).
An interface cannot extend from another class!
Interfaces can also contain constants and static methods.
All the fields in the interface are implicitly declared to be public static final (constants). For example,
public interface DrivableVehicle {
int MAX_SPEED = 150; // A constant
static boolean isSpeedAllowed(int speed){
return speed <= MAX_SPEED;
}
void turn(Direction direction);
void changeLanes(Direction direction);
void signalTurn(Direction direction, boolean signalOn);
// more method signatures
}Java Packages
You can organize your types (i.e., classes, interfaces, enumerations, etc.) into packages for easier management. However, the package of a type should match the folder path of the source file. For example,
Code Explanation
The Formatter class below (in <source folder>/seedu/tojava/util/Formatter.java file) is in the package seedu.tojava.util. When it is compiled, the Formatter.class file will be in the location <compiler output folder>/seedu/tojava/util:
Java Access Modifiers
Access level modifiers determine whether other classes can use a particular field or invoke a particular method. And there are two levels of access control:
At the class level:
public: the class is visible to all classes everywhereno modifier (the default, also known as package-private): it is visible only within its own package
At the member level:
publicor no modifier (package-private): same meaning as when used with top-level classesprivate: the member can only be accessed in its own classprotected: the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package
The following table shows the access to members permitted by each modifier.
public
✅
✅
✅
✅
protected
✅
✅
✅
❌
no modifier
✅
✅
❌
❌
private
✅
❌
❌
❌
Java Exceptions
Java, like most languages, allows code that encountered an "exceptional" situation to encapsulate details of the situation in an Exception object and throw/raise that object so that another piece of code can catch it and deal with it.
Below is a very clear extract from Oracle explaining how exceptions are typically handled.
When an error occurs at some point in the execution, the code being executed creates an exception object and hands it off to the runtime system. The exception object contains information about the error, including its type and the state of the program when the error occurred. Creating an exception object and handing it to the runtime system is called throwing an exception.
This aligns with our knowledge in CS2030S that exceptions only happen at run-time!
After a method throws an exception, the runtime system attempts to find something to handle it in the call stack. The runtime system searches the call stack for a method that contains a block of code that can handle the exception. This block of code is called an exception handler. The search begins with the method in which the error occurred and proceeds through the call stack in the reverse order in which the methods were called. When an appropriate handler is found, the runtime system passes the exception to the handler. An exception handler is considered appropriate if the type of the exception object thrown matches the type that can be handled by the handler.
The exception handler chosen is said to catch the exception. If the runtime system exhaustively searches all the methods on the call stack without finding an appropriate exception handler, the program terminates.
Advantages of exception handling in this way:
The ability to propagate error information through the call stack.
The separation of code that deals with 'unusual' situations from the code that does the 'usual' work.
Types of Exceptions
In Java, there are two types of exceptions:
Checked Exceptions
Uncheckted Exceptions
The definitions are introduced in CS2030S! Also pay attention to the exception hierarchy appeared in the CS2030S Diagnostic Quiz too!
Handle Exceptions
Again, this part has appeared in CS2030S! But, here is a very useful requirement called Catch or Specify Requirement for handling exceptions in Java!
A
trystatement that catches the exception. Thetrymust provide a handler for the exception.A method that specifies that it can throw the exception. The method must provide a
throwsclause that lists the exception immediately after the method declaration.
This requirement must be followed for checkted exceptions. But unchecked exceptions can apply this requirement also!
SWE User Story
The format for writing user story is:
As a {user type/role} I can {function} so that {benefit}
RCS Branching
Target Usage: To make use of multiple timelines of work in a local repository.
Motivation: At times, you need to do multiple parallel changes to files (e.g., to try two alternative implementations of the same feature).
The working flow will be summarised as follows:
To work in parallel timelines, you can use Git branches.
Most work done in branches eventually gets merged together.
When merging branches, you need to guide Git on how to resolve conflicting changes in different branches.
Branches can be renamed, for example, to fix a mistake in the branch name.
Branches can be deleted to get rid of them when they are no longer needed.
Creating Branches
Git branches let you develop multiple versions of your work in parallel — effectively creating diverged timelines of your repository’s history. For example, one team member can create a new branch to experiment with a change, while the rest of the team continues working on another branch. Branches can have meaningful names, such as master, release, or draft.
A Git branch is simply a ref (a named label) that points to a commit and automatically moves forward as you add new commits to that branch. As you’ve seen before, the HEAD ref indicates which branch you’re currently working on, by pointing to the corresponding branch ref. When you add a commit, it goes into the branch you are currently on, and the branch ref (together with the HEAD ref) moves to the new commit.
Git creates a branch named master by default (Git can be configured to use a different name e.g., main).
Given below is an illustration of how branch refs move as branches evolve.

Imgae Explanation
As you can see, the
fix1andmasterare just two labels that points to the two branches namedfix1andmaster.Headalways points to the commit you are currently working on.
Below are some hands-on practice on Git CLI
Create a branch on earlier commit
Always remember to switch back to the master branch before creating a new branch! If not, your new branch will be created on top of the current branch.
You can also start a branch from an earlier commit, instead of the latest commit in the current branch. For that, simply check out the commit you wish to start from. The steps are:
Switch to the
masterbranch.Checkout the commit that is at which the
feature1branch diverged from themasterbranch (e.g.git checkout HEAD~1). This will create a detachedHEAD.Create a new branch called
feature1-alt. TheHEADwill now point to this new branch (i.e., no longer 'detached').Add a commit on the new branch.
Merging Branches
Merging combines the changes from one branch into another, bringing their diverged timelines back together.
When you merge, Git looks at the two branches and figures out how their histories have diverged since their merge base (i.e., the most recent common ancestor commit of two branches). It then applies the changes from the other branch onto your current branch, creating a new commit. The new commit created when merging is called a merge commit — it records the result of combining both sets of changes.
Given below is an illustration of how such a merge looks like in the revision graph:

Below are some hands-on practice on Git CLI
Fast-forward merge
When the branch you're merging into hasn't diverged — meaning it hasn't had any new commits since the merge base — Git simply moves the branch pointer forward to include all the new commits, keeping the history clean and linear. This is called a fast-forward merge because Git simply "fast-forwards" the branch pointer to the tip of the other branch. The result looks as if all the changes had been made directly on one branch, without any branching at all.

Image Explanation
In the example above, the master branch has not changed since the merge base (i.e., m2). Hence, merging the branch bug-fix onto master can be done by fast-forwarding the master branch ref to the tip of the bug-fix branch (i.e., b2).
To do so in Git CLI, it follows the exactly same method as merge branches. Except that, if you force Git to create a merge commit even if fast forwarding is possible, you can use
Squash merge
A squash merge combines all the changes from a branch into a single commit on the receiving branch, without preserving the full commit history of the branch being merged.
To do it in Git CLI, you can sue --squash flag.
Then, you will see the following messages printed by the Git CLI
After that, you must make the commit yourself, for example,
Now your sourceBranch history will show only one commit for all the work done in targetBranch, instead of 5, 10, or however many commits it had.
Resolving Merge Conflicts
The conflicts may happen when you merge your targetBranch into your sourceBranch. To understand the conflict notation, we will go through the following examples,
Try to merge the fix1 branch onto the master branch.
Now, suppose you get a merge conflict shown as follows,
Notation to mark the conflict parts
Observe how the conflicted part is marked between a line starting with <<<<<< and a line starting with >>>>>>, separated by another line starting with =======.
Highlighted below is the conflicting part that is coming from the master branch:
This is the conflicting part that is coming from the fix1 branch:
Resolve the conflict by editing the file
This is usually done in the vim if you don't use an IDE.
Let us assume you want to keep both lines in the merged version. You can modify the file to be like this:
Stage the changes, and commit.
Use git add and then git commit. You have now successfully resolved the merge conflict.
Renaming Branches
To rename a local branch can be easily done by using the following Git CLI command,
Deleting Branches
Deleting branches will merely delete the branch ref. This can be done using the following Git CLI command,
Keep Branches in Sync
While working on one branch, you might want to have access to changes introduced in another branch (e.g., to synchronize the newly-made changes from the master branch while developing the new features).
To do so, there are three wasy to keep your developing branches in sync,
Rebasing
As we know, merging will create merge commits, so if you want to keep the commit history cleaner and more linear, you can use rebasing. This basically moves the base of your branch to the tip of the other branch (e.g., it 're-bases' it — hence the name), as if you had started your work from there in the first place.
Rebasing will change the entire commit history in your developer branch (in our example, it's the feature1 branch)
Working with Remote Branches
Playing with branches locally sounds not interesting enough, thus, we introduce how to interact with the remote branches on GitHub.
Put it all together
After learning so much stuff about RCS branching, I believe you can't help practicing on your own. And if you are curious, the tP requirement in Week 7 actually sets a very good standard for collaborating using Git in a big project.
Classic Questions
User Story
Which of these are true about user stories?
Explanation:
a. Wrong, the reason: Despite the name, user stories are not related to 'stories' about the software.
b. Correct.
c. Wrong, the reason: It is possible to use software to record user stories. When the team members are not co-located this may be the only option.
Choose the correct statements
Explanation: Only d is correct. User stories are short and written in natural language, NOT in a formal language. They are used for estimation and scheduling purposes but do not contain enough details to form a complete system specification.
Last updated