---
title: Computer Programming II Pre-Lab 3
---
<h1 style='border: none'><center>Computer Programming II Pre-Lab 3</center></h1>
<h2 style='border: none'><center>Introduction to Inheritance</center></h2>
<h5><center>The Islamic University of Gaza<br>Engineering Faculty<br>Department of Computer Engineering</center></h5>
<h6>Authors: Usama R. Al Zayan<span style="float:right">2023/02/17</span></h6>
<h6>Parts of this Lab were adapted from work done by Mohammed Nafiz ALMadhoun and Mohammed AlBanna</h6>
---
## Introduction
<p style='text-align:justify'>
In this lab, we are going to explore the concepts of inheritance, and how you could create a new class from an existing class, which will allow you to modify a certain class, and to change some behaviour in classes without fully understanding or reimplementing them.
</p>
## Superclasses & Subclasses
You should know that every class in Java extends the `Object` class, but what does this mean?
It means that `Object` is our superclass, which our class (The subclass) will have all its functionality.
And we can expand this concept, so a superclass in a context could be the subclass in another context!
```java=
class Shape {
int x, y;
public Shape (int x, int y) {
this.x = x;
this.y = y;
}
}
class Circle extends Shape {
// Notice that circle will also have x and y.
double r;
public Circle (int x, int y, double r) {
super(x, y);
this.r = r;
}
}
class Rectangle extends Shape {
int w, h;
public Rectangle (int x, int y, int w, int h) {
super (x, y);
this.w = w;
this.h = h;
}
}
class Square extends Rectangle {
public Square (int x, int y, int d) {
super (x, y, d, d);
}
}
```
Notice that `Rectangle` is the subclass for `Shape`, but it's the superclass for `Square`.
## Overriding methods
One of the most important things about inheritance is the ability to override methods, this will allow us to change the behaviour of certain methods in the superclass if we instantiated the subclass.
```java=
class Shape {
int x, y;
public Shape (int x, int y) {
this.x = x;
this.y = y;
}
public int getArea () {
return 0;
}
}
class Rectangle extends Shape {
int w, h;
public Rectangle (int x, int y, int w, int h) {
super (x, y);
this.w = w;
this.h = h;
}
@Override
public int getArea () {
return w * h;
}
}
```
So in this example, we have the `getArea` method, which will return zero if we created a shape, but if we created a rectangle it will return `w*h`, notice that you won't find this very useful until you understand Polymorphism.
But here is another simple example, the method `toString` is a method that converts an object to a string value, and you can find it in the `Object` class, which by default will return the type and address of the instance, but we could modify it, so whenever we print a certain class it will return a useful data.
```java=
public class Test {
public static void main(String[] args) {
Student s1 = new Student("Mohammed", 25);
System.out.println(s1); // Try it without overriding toString.
}
}
class Student {
private String name;
private int age;
public Student (String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Name: " + name + " - Age: "+age;
}
}
```
## Introduction to Polymorphism
The main concept of Polymorphism is that you could store an instance of a subclass, in a superclass typed variable, which will allow us to do magical things!
```java=
public class Test{
public static void main(String[] args) {
Shape s1 = new Square(0, 0, 10);
}
}
```
Notice that `s1` contains an instance of `Square`, but its type is `Shape`, but notice that you will be able to call only `Shape` methods.
To check the type of the instance we could use `instanceof` keyword, for example:
```java=
System.out.println(s1 instanceof Square); // this will print true
System.out.println(s1 instanceof Circle); // this will print false
```
And you can use casting to change if you want to consider s1 as `Square` again, for example:
```java=
if (s1 instanceof Square) {
Square temp = (Square) s1;
}
```
## Debugging
### What is Debugging?
Broadly, debugging is the process of detecting and correcting errors in a program.
<p style='text-align:justify'>
There are different kinds of errors, which you are going to deal with. Some of them are easy to catch, like syntax errors, because they are taken care of by the compiler. Another easy case is when the error can be quickly identified by looking at the stack trace, which helps you figure out where the error occurred.
</p>
<p style='text-align:justify'>
However, there are errors which can be very tricky and take really long to find and fix. For example, a subtle logic error, which happened early in the program may not manifest itself until very late, and sometimes it is a real challenge to sort things out.
</p>
<p style='text-align:justify'>
This is where the debugger is useful. The debugger is a powerful tool, which lets you find bugs a lot faster by providing an insight into the internal operations of a program. This is possible by pausing the execution and analyzing the state of the program by thorough examination of variables and how they are changed line by line. While debugging, you are in full control of the things.
</p>
For more information about debugging please visit [Tutorial: Debug your first Java application | IntelliJ IDEA Documentation](https://www.jetbrains.com/help/idea/debugging-your-first-java-application.html).
### How to Debug your code using intellij
#### Set breakpoints.
**Breakpoints** indicate the lines of code where the program will be suspended for you to examine its state
Click to the left of the line where you want to suspended the program, a red circle will appear and the line's colour will change to light red.

#### Run the program in debug mode.
Right-click on the green triangle next to the main method line and choose Debug.

#### Step through the program
Now that we are comfortable with the Debug tool window, it's time to step into the `getData()` method and find out what is happening inside it.
Continue stepping with Step Over `F8`. Notice how it is different from Step Into. While it also advances the execution one step forward, it doesn't visit other methods like Integer.parseInt() along the way.

#### The result will be printed in the console tab

#### Stop the debugger session and rerun the program

## Exercise
### Why the following code make error when create object from Child.
```java=
public class Parent {
public Parent(int n) {
System.out.println("Parent " + n);
}
}
class Child_1 extends Parent {
public Child_1() {
System.out.println("Child_1");
}
public Child_1(int n) {
System.out.println("Child_1 " + n);
}
}
```
**Answer**: There is no default constructor in the Parent class.
```java=
public class Parent {
public Parent() {
System.out.println("Parent");
}
public Parent(int n) {
System.out.println("Parent " + n);
}
}
class Child_1 extends Parent {
public Child_1() {
this(5);
super();
System.out.println("Child_1");
}
public Child_1(int n) {
System.out.println("Child_1 " + n);
}
}
```
**Answer**: Call to `super()` must be the first statement in constructor body.
### What is the output of the following code:
```java=
class A {
public void print() {
System.out.println("I'm A");
}
public void getData() {
print();
}
}
class B extends A {
@Override
public void print() {
System.out.println("I'm B");
}
public static void main(String[] args) {
new B().getData();
}
}
```
**Answer**: I'm B.
```java=
class ParentA {
protected int b = 3;
public ParentA() {
b += 3;
System.out.println("b = " + b);
}
public ParentA(int i) {
this();
b += 2;
System.out.println("b = " + b);
}
}
class ChildA extends ParentA {
int b = 4;
public ChildA() {
super(3);
b += 1;
System.out.println("b = " + b);
}
}
class ChildB extends ChildA {
public ChildB() {
b += 2;
System.out.println("b = " + b);
}
public static void main(String[] args){
ChildB childB = new ChildB();
}
}
```
**Answer**:
b = 6
b = 8
b = 5
b = 7
```java=
class ParentA {
protected int a = 2;
protected int b = 3;
public ParentA() {
a += 1;
b += 2;
System.out.println("b = " + b);
}
public ParentA(int i) {
this();
b -= 1;
System.out.println("a = " + a);
a -= 1;
}
public int getB(){
this.a += 2;
this.b += 4;
return b - a;
}
}
class ChildA extends ParentA {
int a;
int b = 1;
public ChildA() {
super(3);
a += 7;
b += 5;
}
}
class ChildB extends ChildA {
public ChildB() {
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("b = " + getB());
}
public static void main(String[] args){
ChildB childB = new ChildB();
}
}
```
**Answer**:
b = 5
a = 3
a = 7
b = 6
b = 4
```java=
class ParentA {
public void print() {
System.out.println("ParentA");
}
public String foo() {
return "Foo";
}
}
class ChildA extends ParentA {
@Override
public void print() {
System.out.println(this.show());
System.out.println(foo());
System.out.println("ChildA");
}
public String show() {
return "ChildA_1";
}
}
class ChildB extends ChildA {
@Override
public String show() {
return "ChildB_1";
}
public static void main(String[] args) {
ChildB childB = new ChildB();
childB.print();
}
}
```
**Answer**:
ChildB_1
Foo
ChildA
```java=
class MySuper {
int m = 3;
public MySuper() {
myMethod();
}
void myMethod() {
System.out.print("x = " + m);
}
}
class MySub extends MySuper {
int n = 2;
public static void main(String[] args) {
MySub mySub = new MySub();
}
@Override
void myMethod() {
System.out.print("x = " + n);
}
}
```
**Answer**: x = 0
###### tags: `Computer Programming II` `Pre-Lab` `IUG` `Computer Engineering`
<center>End Of Pre-Lab 3</center>