• No results found

Object Oriented Programming. Lecture One. Classes and Objects

N/A
N/A
Protected

Academic year: 2022

Share "Object Oriented Programming. Lecture One. Classes and Objects"

Copied!
58
0
0

Loading.... (view fulltext now)

Full text

(1)

Object Oriented Programming

Lecture One

Classes and Objects

Subjects:

1.1 Designing a Class

1.2 Creating Objects from Classes

1.3 Access Modifiers: Public and Private

1.1 Designing a Class

You can describe any real thing (object) in the world using classes, a class is a template or blueprint that contains variables to describe objects properties and methods to describe objects actions and events, for example, you can create a class to describe a car, bicycle, train, computer, TV, employee, student, table, chair, or anything in the world.

For example to describe a rectangle which is a thing that have a length, width and a color, you can create a class named rectangle that must be public and saved in a file named rectangle as shown below:

Filename: Rectangle.java

// Project 1 – File 1 public class Rectangle {

// rectangle variables (Properties) public double length, width;

private int color;

}

Note that the above class doesn’t have a main method because this class only describes a rectangle; it is a template, not an executable class.

length

width color

(2)

Also we can compute the area of the rectangle, so we add a public method for computing the area as follows:

public class Rectangle {

// rectangle variables (Properties) public double length, width;

private int color;

// rectangle methods (Actions) public double computeArea() {

return (length * width);

} }

1.2 Creating Objects from Classes

To work with the rectangle class and test it, you need another class that contains a main method; we will name it TestRect as shown below:

Filename: TestRect.java

// Project 1 – File 2 public class TestRect {

public static void main(String[] args) {

Rectangle r1; // declare an object

r1 = new Rectangle (); // create an object (reserve memory)

} }

The above class is used to run and test the Rectangle class; it contains a main method were execution starts from. Inside the main method we create an object named r1 of type class rectangle.

Note: you can’t work with template classes directly (there are exceptions) because you have to declare and create objects of template classes then work with these objects like the r1 object, just like when you declare a variable of some type like:

int a;

you can’t work with the type int

int = 3; //Incorrect

you must first declare a variable of type int then work with that variable.

int a;

a = 3;

Note: Simple data types (not classes) like int, float, byte, etc. only needs declaration, you don’t need to create them with the reserved word new, because when you declare them, memory will be reserved for them automatically.

(3)

While when working with objects of classes, you need to declare them first then create them later and the reason for this is to be able to pass parameters to the object during the creation process as we will see later.

1.3 Access Modifiers: Public and Private

Note that class Rectangle contains three properties or variables: length, width and color, note that length as well as width are public which mean that we can access them from anywhere, while color is private which mean we can access it only from inside the class Rectangle, for example: we will update the TestRect class to try to display the width as shown below:

public class TestRect {

public static void main(String[] args) { Rectangle r1 = new Rectangle();

Syste.out.println(r1.width);

} }

The above program is correct because width is public and can be reached from anywhere. Now we will update the TestRect program to try to display the color variable as shown below:

public class TestRect {

public static void main(String[] args) { Rectangle r1 = new Rectangle();

System.out.println(r1.color); // Incorrect }

}

The above program is incorrect because you can’t reach color since it is private which means we can’t reach it from outside the class, now how can we display color, is it impossible? Well it is possible and there are 2 ways:

1- Change its declaration to be public inside class Rectangle so that we can change it from outside the Rectangle class just like the width variable.

2- Declare a public method inside the Rectangle class that can return the value of the color variable and call this method from outside the Rectangle class as shown below:

public class Rectangle {

// rectangle variables (Properties) public double length, width;

private int color;

public int getColor() {

(4)

return (color);

}

public double computeArea() { return (length * width);

} }

Now the execution class will be like this:

public class TestRect {

public static void main(String[] args) { Rectangle r1 = new Rectangle();

System.out.println(r1.length+” “+r1.width);

System.out.println(r1.getColor());

} }

Now, let’s change the length, width and color:

public class TestRect {

public static void main(String[] args) { Rectangle r1 = new Rectangle);

r1.length = 34.7; r1.width=5;

r1.color = 30; // Incorrect

System.out.println(r1.length+” “+r1.width);

System.out.println(r1.getColor());

} }

Again we can’t reach variable color, so we need another method to change its value as shown below:

public class Rectangle {

public double length, width;

private int color;

public int getColor() { return (color);

}

public void setColor(int newColor) { color = newColor;

}

public double computeArea() { return (length * width);

} }

Now the execution class will be like this:

(5)

public class TestRect {

public static void main(String[] args) { Rectangle r1 = new Rectangle();

r1.length = 34.7; r1.width=5;

r1.setColor(30);

System.out.println(r1.length+” “+r1.width);

System.out.println(r1.getColor());

} }

You may ask yourself, why you have to declare a variable as private and provide two methods for retrieving and changing its value.

Well if you declare a variable as public, then any other programmer (and may be you) may change its value to an incorrect value, for example, length is public and that means I can give it an incorrect value as shown below:

r1.length = -12.7;

But as we all know that the rectangle length can’t be negative, so this is a logical error because java will execute the program (there are no syntax errors).

To solve this problem, we have to hide it by declaring it as private and provide two public methods, one for retrieving the length value and one for setting the length value by checking the new value before assigning it to the variable as shown below:

public class Rectangle {

private double length, width;

private int color;

public double getL() { return (length);

}

public double getW() { return (width);

}

public void setL(int newL) { if(newL >= 0.0)

length = newL;

}

public void setW(int newW) { if(newW >= 0.0)

width = newW;

}

public int getColor() { return (color);

}

public void setColor(int newColor) { color = newColor;

}

(6)

public double computeArea() { return (length * width);

} }

Note that methods setL & setW check the new value and if it was positive (>=0) then it will set it to length or width, but if the new value was negative, the method will not change it and keep the old value.

Summary:

We can protect our variables by making them private and provide public methods to get and set their values.

(7)

Object Oriented Programming

Lecture Two

More on Classes, Using Objects as Pointers, Using Packages.

Subjects:

1.4 Time Example

1.5 Using Objects as Pointers 1.6 Using Packages

1.4 Time Example

Let’s design a time class to be used for storing time for different cities. We will start by a class with only public variables:

public class Time {

public int hour, minute;

// P for PM and A for AM public char dayNight;

}

Now if we want to work with the time class, lets create a new class and name it Main then create a number of object from the time class, each object represent a city time as shown below:

public class Main {

(8)

public static void main(String[] args) { Time baghdad, london, berlin, sofia;

baghdad = new Time();

baghdad.hour = 6;

baghdad.minute = 9;

baghdad.dayNight = 'P';

london = new Time();

london.hour = 4;

london.minute = 90;

london.dayNight = 'P';

berlin = new Time();

berlin.hour = 50;

berlin.minute = 9;

berlin.dayNight = 'P';

sofia = new Time();

sofia.hour = 6;

sofia.minute = 9;

sofia.dayNight = 'M';

} }

The above program is syntactically correct and you can run it, but if you take a look at it, then you will notice the following logical errors:

1- London time (4:90:P) the minute part is 90 but minute can’t be greater than 59 (there are only 60 minutes in an hour).

2- Berlin time (50:9:P) the hour is 50 but it can’t be greater than 12 (there are only 24 hours in a day, 12 for AM and 12 for PM).

3- Sofia time (6:9:M) notice the dayNight is M, while it can only be either P or A.

The Time class needs to be redesign in order to accept only correct values, so all variables must be hidden by making them private and provide public methods (setters and getters) to change variables values in a correct way and as follows:

public class Time {

private int hour, minute;

// P for PM and A for AM private char dayNight;

// Getter and Setter methods for hour public void setHour(int value) {

if(value <= 12) hour = value;

}

public int getHour() { return hour;

}

(9)

// Getter and Setter methods for minute public void setMinute(int value) {

if(value < 60)

minute = value;

}

public int getMinute() { return minute;

}

// Getter and Setter methods for dayNight public void setDayNight(char value) {

if( (value == 'P') || (value == 'p') ) dayNight = 'P';

else if( (value == 'A') || (value == 'a') ) dayNight = 'A';

}

public char getDayNight() { return dayNight;

}

// return a string representing the time public String toString() {

return( hour + ":" + minute + ":" + dayNight );

} }

Now let’s use the new class to define time objects for cites and as shown below:

public class Main {

public static void main(String[] args) { Time baghdad, london, berlin, sofia;

baghdad = new Time();

baghdad.setHour(6);

baghdad.setMinute(9);

baghdad.setDayNight('P');

System.out.println(baghdad.toString());

london = new Time();

london.setHour(4);

london.setMinute(90);

london.setDayNight('P');

System.out.println(london.toString());

berlin = new Time();

berlin.setHour(50);

berlin.setMinute(9);

berlin.setDayNight('P');

System.out.println(berlin.toString());

sofia = new Time();

sofia.setHour(6);

sofia.setMinute(9);

sofia.setDayNight('M');

(10)

System.out.println(sofia.toString());

} }

1.5 Using Objects as Pointers

After you declare an object, you can use it to point to another created object without having to create it with the new keyword, for example:

public class Main {

public static void main(String[] args) { // Declare t0, t1, t2, and t3

Time t0, t1, t2, t3;

// Cretae only t0 T0 = new Time();

// Make t1, t2, and t3 points to t0 t1 = t0;

t2 = t0;

t3 = t0;

t0.setHour(8);

t1.setMinute(9);

t2.setDayNight('P');

System.out.println(t3.toString());

} }

1.6 Using Packages

Packages can help programmers manage the complexity of application components.

Packages also facilitate software reuse by enabling programs to import classes from other packages (for example, importing the Scanner class inside your Main class), rather than copying the class into each program that uses them. Another benefit of packages is that they provide a convention for unique class names, which helps prevent class-name conflict.

Example 1:

Project 1: SpaceShip

package oop.course1.examples;

public class SpaceShip { public String leader;

public int power;

public int hitPower;

}

(11)

}

Project 2: Test1 public class Main {

public static void main(String[] args) { oop.course1.examples.SpaceShip sp1;

sp1 = new oop.course1.examples.SpaceShip();

}

Project 3: Test2

import oop.course1.examples.SpaceShip;

// or import oop.course1.examples.*;

public class Main {

public static void main(String[] args) { SpaceShip sp1;

sp1 = new SpaceShip();

}

(12)

Object Oriented Programming

Lecture Three

Package Access, Constructors, Using this keyword.

Subjects:

1.7 Package Access 1.8 Constructors

1.9 Using this keyword

(13)

1.7 Package Access

If no access modifier (public or private) is specified for a method or variable when it is declared in a class, the method or variable is considered to have package access. In a program that consists of one class declaration, this has no specific effect. However, if a program uses multiple classes from the same package, these classes can access each other's package-access members directly through references to objects of the appropriate classes.

Example 2:

packages test2;

public class TestPackageAccess { int nu;

}

package test2;

public class Main {

public static void main(String[] args) {

TestPackageAccess t = new TestPackageAccess t.nu = 6;

}

Note that Main and TestPackageAccess classes are in the same package (test2).

Variable nu was defined with a package access and class Main can access it directly without package name.

1.8 Constructors

When we declare and create objects of classes, its variables are set to their default values (numbers set to 0, etc.) but what if we want to initialize the newly created object variables immediately.

To do that, we need to add constructors, a constructor is a special method that is used to initialize object variables in the creation stage, and constructors have the following properties:

1- Constructors must be public.

2- Every constructor must have the same name of the class.

3- They never return a value, so there is no return type (not even void).

4- You can’t use a return keyword inside a constructor because you can’t return values.

5- Constructors are called automatically by the new keyword when a new object is created, so you can’t call a constructor from another method.

6- By default, the java runtime provides a no-argument default constructor for each class that doesn’t have one.

(14)

7- If you declare constructors then the java runtime won’t provide your class with a no-argument default constructor.

In the Time class, when we create a new object (like baghdad) from class Time, the new keyword calls the Time default constructor.

Now let’s design our own constructor to accept 3 values (hour, minute, and dayNight):

public class Time {

private int hour, minute;

// P for PM and A for AM private char dayNight;

// Constructors

public Time(int h, int m, char dn) { setHour(h);

setMinute(m);

setDayNight(dn);

}

// Getter and Setter methods for hour public void setHour(int value) {

if(value <= 12) hour = value;

}

public int getHour() { return hour;

}

// Getter and Setter methods for minute public void setMinute(int value) {

if(value < 60)

minute = value;

}

public int getMinute() { return minute;

}

// Getter and Setter methods for dayNight public void setDayNight(char value) {

if( (value == 'P') || (value == 'p') ) dayNight = 'P';

else if( (value == 'A') || (value == 'a') ) dayNight = 'A';

}

public char getDayNight() { return dayNight;

}

// return a string representing the time

(15)

public String toString() {

return( hour + ":" + minute + ":" + dayNight );

} }

Now let’s test our new class

public class Main {

public static void main(String[] args) { Time moscow = new Time(7, 9, 'p');

System.out.println(moscow.toString());

} }

Note: since we declare our own constructor, java runtime will not provide the default constructor, so the following program is incorrect:

public class Main {

public static void main(String[] args) { Time moscow = new Time();

} }

To solve this problem we have to add the no-argument constructor (overloading method):

public Time() { }

We can also add code to the no-argument constructor as follows:

public Time() { hour = 0;

minute = 0;

dayNight = 'A';

}

Function overloading (also method overloading) is a programming concept that allows programmers to define two or more functions with the same name and in the same scope. Each function has a unique signature (or header), which is derived from:

function/procedure name. number of arguments. arguments' type.

We can also add many constructors as follows:

public Time() { hour = 0;

minute = 0;

dayNight = 'A';

}

(16)

public Time(int h) { hour = h;

minute = 0;

dayNight = 'A';

}

public Time(int h, int m) { hour = h;

minute = m;

dayNight = 'A';

}

public Time(char dn) { hour = 0;

minute = 0;

dayNight = dn;

}

public Time(int h, int m, char dn) { hour = h;

minute = m;

dayNight = dn;

}

Now we can use constructors after new as shown below:

Time paris = new Time(5, 9);

Time belgrade = new Time('P');

Time montevideo = new Time(1);

1.9 Using this keyword

Any variable defined in class, is general. Also the methods that written in class, are general. General means that they are known in all classes' methods. Any class has general region which is shared for all methods inside this class. The rest space of a class is divided into local regions. Each local region is reserved for specified method.

The variables inside methods region are local. The local variable is known only inside its method, and unknown outside its method. See the following example:

Public class Square{

private int length;

public void set(int a){if(a>0)length=a;}

public int get(){return length;}

Public int comput1(int b){ Int a; set(b); a=b*b; Return a;}

Public int comput2(){ Int a; a=length*4; return a;}}

Look at Square class; length, set(int), get(), comput1(int) and comput2() are general.

They are saved at shared region, so they are known for all methods of class Square.

Which means, Variable length could be used inside any method. Any method could be called inside other methods.

(17)

Variables b and a of method comput1(int) are local. So they are saved at the local region that reserved for comput1(int) method. They are known only inside comput1(int). they are unknown at get(), set(int), and comput2().

Variable a of method set(int) is known inside its method and unknown for others.

Also variable a inside method comput2() is known inside its method and unknown for all others. Note that variables a at different methods are not the same, but length is the same at all methods.

Suppose that programmer defines variables inside methods and he likes to use variables-id the same as they are written at the shared region. Sure he can do it. Inside a method if variable is found, java will use it, and do not go to the shared region. See the following code.

Public class Square{

private int length;

public void set(int length){if(length>0)length=length;}

public int get(){return length;}

Public int comput1(int b){ Int a; set(b); a=b*b; Return a;}

Public int comput2(){ Int a; a=length*4; return a;}}

Declare variable length instead of a inside method set(int). Now the program will check the local length, if it is larger than 0 then local length=local length. Any value will not be changed. Java will not reach the shared region because it found the needed variables inside the local region. So the code now is wrong.

Java provides this keyword to solve this problem. this is used to tell Java to reach the variable at shared region. So code will be as following.

Public class Square{

private int length;

public void set(int length){if(length>0)this.length=length;}

public int get(){return length;}

Public int comput1(int b){ Int a; set(b); a=b*b; Return a;}

Public int comput2(){ Int a; a=length*4; return a;}

Now, method set(int) will check the local var value, if it is greater than 0, then set the shared length equal to value of local length.

(18)

Object Oriented Programming

Lecture Four

Composition

Subjects:

1.10 Composition

1.10 Composition

Many compound examples need to create object inside class. Dividing compound properties into more than one class makes project more flexible and easer to check errors. For example class person information includes many properties:

name, gender, birth date, certificate, address, work, length, weight, marital, no of children. Many of these properties have more details. Try listing more details in the same class:

first name, second name, last name, gender, day, month, year, certificate type, average, country, city, street name, no1, no2, no3, work name, address of work, length, marital, and no of children.

It is difficult to build class with all those details. At the same time very important details will be lost in case of briefing information. So the solution is dividing into many classes and then use objects inside classes.

Composition represents has-a relationship. In a has-a relationship, an object contains one or more object references as members. For example, a car has a steering wheel (and a car object has a reference to a steering wheel object).

(19)

Example of student:

Public class Name{

String first, second, third;

public Name(){first=""; second=""; third="";}

public Name(String first, String second, String third){

this.first=first();

this.second=second;

this.third=third;}

public String tostr(){return first+second+hird;}

}

Public class Subject{

String name; private int mark;

public Subject(){name=""; mark=0;}

public Subject(String name, int mark){

this.name=name; set(mark);}

public void set(int mark){

if (mark>=0 && mark<=100)this.mark=mark;}

public int get(){return mark;}

public String tostr(){return name+mark;}

}

Public class Student{

Name name; int age;

Subject s1, s2, s3, s4;

public Student(){

name=new Name();

age=0;

s1=new Subject();

s2=new Subject();

s3=new Subject();

s4=new Subject();}

public Student(String first, String second, String last, int age, String name, int mark){

this.name= new Name(first, second, third);

this.age=age;

this.s1=new Subjet(name,mark);

this.s2=new Subjet(name,mark);

this.s3=new Subjet(name,mark);

this.s4=new Subjet(name,mark);

}

public String tostr(){

return name.tostr()+ age + s1.tostr()+ s2.tostr()+

s3.tostr()+ s4.tostr();}

}

The main class:

Import java.util.Scanner Public class Main{

Public static void main(String []args){

Student st1=new Student();

System.out.println(st1.tostr());

Student st2 = new Student( "Ahmad" , "Hameed" ,

"Mahmood" , 19 , "AI" , 70);

(20)

Scanner in=new Scanner(System.in);

String s2,s3; int m2,m3;

S2=in.nextLine();

S3=in.nextLine();

m2=in.nextInt();

m3=in.nextInt();

st2.s2.name=s2;

st2.s3.name=s3;

st2.s2.set(m2); st2.s3.set(m3);

System.out.println(st2.tostr());

} }

Class Student may be written as follows:

Public class Student{

Name name; int age;

Subject s1, s2, s3, s4;

public Student(){age=0;}

public Student(int age){ this.age=age;}

public String tostr () {

return name.tostr () + age+s1.tostr() + s2.tostr() + s3.tostr() + s4.tostr();}

}

So The main class must be as follows:

Import java.util.Scanner Public class Main{

Public static void main(String []args){

Student st1=new Student();

Name name;

Subject sb1, sb2, sb3, sb4;

name=new Name();

sb1=new Subject();

sb2=new Subject();

sb3=new Subject();

sb4=new Subject();

st1.name=name;

st1.s1=sb1; st1.s2=sb2; st1.s3=sb3; st1.s4=sb4;

System.out.println(st1.tostr());

Student st2=new Student(19);

Name nm=new Name("Ahmad","Hameed","Mahmood");

Subject sb11=new Subject("c++",60);

Subject sb22=new Subject("OOP",77);

Subject sb33=new Subject("Comp theory",40);

Subject sb44=new Subject("Numerical",50);

System.out.println(st2.tostr());}

}

s

(21)

Object Oriented Programming

Lecture Five

finalize, static, and final

Subjects:

1.11 Garbage Collection

1.12 Static Variables (Class Variables)&Static Methods (Class Methods)

1.13 Static Import

1.14 Final Instance Variables

1.11 Garbage Collection

Every object uses system resources, such as memory, you have to give these resources back to the system when they are no longer needed, because if you don't, a resource leaks will occur and prevent your program or other programs from using that resource.

JVM1 performs automatic garbage collection to reclaim memory occupied by objects that are no longer used. When there are no more references to an object, the object is eligible to be collected.

(22)

Other types of resource leaks can occur when you open a file on disk, modify its contents, and forget to close it, in this way other applications can't use this file unless you close it or your application ends.

Before the garbage collector reclaims an objects memory, it calls the objects finalize method to perform termination housekeeping, it doesn't take parameters and has return type void.

Note: the garbage collector is not guaranteed to execute at a specified time, and may never execute before a program termination, so you never know when the finalize method will be called, and that is why most programmers avoid using method finalize.

1: The Java Virtual Machine (JVM) is the runtime engine of the Java Platform, which allows any program written in Java or other language compiled into Java bytecode to run on any computer that has a native JVM.

When Java bytecode is executed by an interpreter, the execution will always be slower than the execution of the same program compiled into native machine language. ... Some JVM implementations do not include an interpreter, but consist only of a just-in-time compiler.

Example:

public class Test {

private String name;

public Test(String name) { this.name = name;

System.out.println("Creating object " + name);

}

public void finalize() {

System.out.println("Terminating object " + name);

} }

public class Main {

public static void main(String[] args) { Test t1 = new Test("t1");

Test t2 = new Test("t2");

Test t3 = new Test("t3");

Test t4 = new Test("t4");

} }

The output of the previous Main class will contains four "Creating object X"

messages where X is the name of the object, these messages are displayed each time a new object is created and thus the constructor of that object is called.

But the output may not contains any "Terminating object X" because the program terminates before the garbage collector have the chance to terminate these objects and thus the finalize method never been called.

(23)

Now change main to be like this:

public class Main {

public static void main(String[] args) { Test t1 = new Test("t1");

Test t2 = new Test("t2");

Test t3 = new Test("t3");

Test t4 = new Test("t4");

t1 = null;

t2 = null;

t4 = null;

System.gc();

} }

In this new Main class, we assign the value null to three objects which mean we don't need them, then call the gc (garbage collector).

The output of this new Main class will be as following:

Creating object t1 Creating object t2 Creating object t3 Creating object t4 Terminating object t1 Terminating object t2 Terminating object t4

1.12 Static Variables (Class Variables) & Static Methods (Class Methods)

A static –class- variable is a variable shared by all objects of a class, a public static variable can be accessed from any object of the class, for example if we have a student class and want to know how many students objects are there at any time, we can use a static counter to do this as shown below:

public class Student { public String name;

public static int stdCo = 0;

public Student() { ++stdCo;

} }

public class Main {

public static void main(String[] args) { Student s=new Student();

System.out.println(Student.ctdCo);

}

}// the output of this program will be 1

(24)

A static variable can take any type access modifiers (public, private, package, ..).

Sure, when static variable is private then it needs a way to set its value and a way to get its value. In case that we write methods work on just static variables, so it is preferable to make the method static. A static method as well as static variable is a method that is shared for all class objects, and may be called using the class name. So the example of student counter will be as following:

public class Student { public String name;

private static int stdCo = 0;

public Student() { ++stdCo;

}

Public static int getCo(){

Return stdCo;

} }

public class Main {

public static void main(String[] args) {

System.out.println("Students: " + Student.getCo());//1 Student s1 = new Student();

System.out.println("Students: " + s1.getCo());//2

System.out.println("Students: " + Student.getCo());//3 Student s2 = new Student();

System.out.println("Students: " + s2.getStdCo());//4 System.out.println("Students: " + s1.getCo());//5

System.out.println("Students: " + Student.getCo());//6 }

}

Note that statement no.1 call the static method using class name without creating any object of that class. The statement no.2 call the static method using an object of the class, while statement 3 call it using class name, any way the two statements have the same result, because they are refer to the shared variable.

The output of the previous program:

0 1 1 2 2 2

Note: A static variable/method belongs to the class, not to the objects.

Note: A static method can't access non-static class members, because the static method can be called even when no objects of the class have been instantiated.

(25)

Note: this reference can't be used in static methods for the same reason above.

1.13 Static Import

It enables you to import static members of class or interface so you can access them via their unqualified names in your class. There are two types of static imports:

1- Single static import: used to import a specific static member, the syntax of this import is as follows:

import static packageName.ClassName.staticMemberName;

Example: import static java.lang.Math.PI;

2- Static import on demand: imports all static members of a class, its syntax is as follows:

import static packageName.ClassName.*;

Example: import static java.lang.Math.*;

Example:

import static java.lang.Math.*;

public class Main {

public static void main(String[] args) { System.out.println("PI = " + PI));

System.out.println("sqrt(243): " + sqrt(234));

} }

Note: A compilation error occur if you import methods from two or more classes with the same signature or fields with the same name.

1.14 Final Instance Variables

A final variable is a constant that once initialized, you can't change its value. You can declare a final variable with initial value that will never be changed as follows:

public final int MAX = 20;

Another way to declare final variables is to declare them and initialize them later (they are best initialized in constructors because each constructor can initialize a final variable to a specific value), for example:

(26)

public class Student { public String name;

private static int stdCo = 0;

private final int CURVE;

public Student() { ++stdCo;

CURVE = 10;

}

public Student(int c) { ++stdCo;

CURVE = c;

}

public static int getStdCo() { return stdCo;

} }

(27)

Object Oriented Programming

Lecture Six

Enumerations

Subjects:

1.15 Using Enumerations

1.16 Enumerations and Classes

1.15 Using Enumerations

Enumerations are used to represent a finite set of values (constants) that a variable can attain; it defines the domain of a type. For instance, a student's mark can be either (Excellent, Very good, Good, Average, Poor, Fail) which makes up an enumeration.

Example 1 – Student Mark I:

public enum Mark {

Excellent, VeryGood, Good, Average, Poor, Fail;

}

public class Main {

public static void main(String[] args) {

(28)

Mark Ahmed, Saad, Sara, Noor;

Ahmed = Mark.Excellent;

Saad = Mark.Poor;

Sara = Mark.VeryGood;

Noor = Mark.Average;

System.out.println("Ahmed degree: " + Ahmed);

if(Saad != Marks.Axcellent)

System.out.println("Saad degree is less than 90");

System.out.println("Degrees can be:");

Marks[] m = Marks.values();

for(int i=0; i<m.length; i++) System.out.println(m[i]);

} }

Example 2 – Student Mark II:

private enum Mark {

Excellent, VeryGood, Good, Average, Poor, Fail;

}

public class Main {

public static void main(String[] args) { Mark Ahmed, Saad, Sara, Noor;

Ahmed = Mark.Excellent;

Saad = Mark.Poor;

Sara = Mark.VeryGood;

Noor = Mark.Average;

System.out.println("Ahmed degree: " + Ahmed);

if(Saad != Marks.Axcellent)

System.out.println("Saad degree is less than 90");

System.out.println("Degrees can be:");

for(Marks m : Marks.values()) System.out.println(m);

} }

Example 3 – Week Days I:

public enum Days {

SATURDAY, SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY

}

public class Main {

public static String chkDay(Days d) { switch(d) {

case FRIDAY:

case SATURDAY: return ("Holiday");

case THURSDAY: return ("OFF Day");

case SUNDAY: return ("Heavey-duty Day");

(29)

default: return ("Normal Day");

} }

public static void main(String[] args) { Days d1, d2;

d1 = Days.SATURDAY;

d2 = Days.MONDAY;

System.out.println("Week Days are:");

for(Days d : Days.values()) System.out.println(d);

System.out.println(d1 + " is a " + chkDay(d1));

System.out.println(d2 + " is a " + chkDay(d2));

} }

Note: all enum constants are implicitly final.

Note: enum constants are implicitly static.

1.16 Enumerations and Classes

Enumerations like classes can have constructors, variables, and methods.

Example 4 – Week Days II:

public enum WeekDays {

SATURDAY("Holiday"), SUNDAY("Heavy duty day"),

MONDAY("Normal day"), TUESDAY("Normal day"), WEDNESDAY("Normal day"), THURSDAY("Light day"),

FRIDAY("Holiday");

private final String status;

// Constructor

WeekDays(String status) {

this.status = status;

}

// Get status

public String status() { return status;

} }

public class Main {

public static void main(String[] args) { WeekDays d1;

(30)

d1 = WeekDays.FRIDAY;

System.out.println(d1 + " is a " + d1.status());

for(WeekDays d:WeekDays.values())

System.out.println(d + " is a " + d.status());

} }

Note: If you attempt to create an object of an enum type with operator new results in a compilation error.

(31)

Object Oriented Programming

Lecture Seven

Inheritance & Protected Access

Subjects:

1.17 Introduction

1.18 Protected Access 1.19 Examples

1.20 Calling Superclass Constructors 1.21 Overriding Methods

1.17 Introduction

Inheritance is a form of software reuse in which a new class is created by absorbing an existing class's members and embellishing them with new or modified capabilities.

With inheritance, programmers save time during program development by reusing proven and debugged high-quality software.

When creating a class, rather than declaring completely new members, the programmer can designate that the new class should inherit the members of an existing class. The existing class is called the superclass, and the new class is the subclass. (The C++ programming language refers to the superclass as the base class

(32)

and the subclass as the derived class). Each subclass can become the superclass for future subclasses.

We distinguish between the is-a relationship and the has-a relationship. Is-a represents inheritance. In an is-a relationship, an object of a subclass can also be treated as an object of its superclass. For example, a car is a vehicle. By contrast, has- a represents composition. In a has-a relationship, an object contains one or more object references as members. For example, a car has a steering wheel (and a car object has a reference to a steering wheel object).

Inheritance relationships form tree-like hierarchical structures. A superclass exists in a hierarchical relationship with its subclasses. When classes participate in inheritance relationships, they become "affiliated" –اهل ةعبات- with other classes. A class becomes either a superclass, supplying members to other classes, or a subclass, inheriting its members from other classes. In some cases, a class is both a superclass and a subclass.

For example, a university community has thousands of members, including employees, students and alumni as shown in Figure-1. Employees are either faculty members or staff members. Faculty members are either administrators (such as deans and department chairpersons) or teachers. Note that the hierarchy could contain many other classes. For example, students can be graduate or undergraduate students. Undergraduate students can be freshmen, sophomores, juniors or seniors.

Figure - 1

Each arrow in the hierarchy represents an is-a relationship. As we follow the arrows in this class hierarchy, we can state, for instance, that an Employee is a CommunityMember and a Teacher is a Faculty member. CommunityMember is the direct superclass of Employee, Student and Alumnus, and is an indirect superclass of all the other classes in the diagram. Starting from the bottom of the diagram, the reader can follow the arrows and apply the is-a relationship up to the topmost superclass. For example, an Administrator is a Faculty member, is an Employee and is a CommunityMember.

(33)

Now consider the Shape inheritance hierarchy in Figure-2. This hierarchy begins with superclass Shape, which is extended by subclasses TwoDimensionalShape and ThreeDimensionalShape shapes are either TwoDimensionalShapes or ThreeDimensionalShapes. The third level of this hierarchy contains some more specific types of TwoDimensionalShapes and ThreeDimensionalShapes. We can follow the arrows from the bottom of the diagram to the topmost superclass in this class hierarchy to identify several is-a relationships.

For instance, a Triangle is a TwoDimensionalShape and is a Shape, while a Sphere is a ThreeDimensionalShape and is a Shape. Note that this hierarchy could contain many other classes. For example, Ellipses and Trapezoids are TwoDimensionalShapes.

Figure - 2

Because every subclass object is an object of its superclass, and one superclass can have many subclasses, the set of objects represented by a superclass is typically larger than the set of objects represented by any of its subclasses. For example, the superclass Vehicle represents all vehicles, including cars, trucks, boats, bicycles and so on. By contrast, subclass Car represents a smaller, more specific subset of vehicles.

A subclass normally adds its own fields and methods. Therefore, a subclass is more specific than its superclass and represents a more specialized group of objects.

Typically, the subclass exhibits the behaviors of its superclass and additional behaviors that are specific to the subclass.

The direct superclass is the superclass from which the subclass explicitly inherits. An indirect superclass is any class above the direct superclass in the class hierarchy, which defines the inheritance relationships between classes. In Java, the class hierarchy begins with class Object (in package java.lang), which every class in Java directly or indirectly extends (or "inherits from"). Java support only single inheritance, while C++ support multiple inheritance (which occurs when a class is derived from more than one direct superclass).

1.18 Protected Access

(34)

Using protected access offers an intermediate level of access between public and private. A superclass's protected members can be accessed by members of that superclass, by members of its subclasses and by members of other classes in the same package (i.e., protected members also have package access).

All public and protected superclass members retain their original access modifier when they become members of the subclass (i.e., public members of the superclass become public members of the subclass, and protected members of the superclass become protected members of the subclass).

1.19 Examples

In the first example, we will design a Circle, Square, and Rectangle classes without inheritance as shown below:

Example-1:

public class Circle { private String name;

private int borderColor;

private int fillColor;

private int sx, sy;

private double radius;

public Circle() { // 0 is black name = "Circle";

borderColor = 0;

fillColor = 0;

sx = 0; sy = 0;

radius = 0.0;

}

public void setName(String name) { this.name = name; } public void setBColor(int c) { borderColor = c; }

public void setFColor(int c) { fillColor = c; } public void setX(int x) { sx = x; }

public void setY(int y) { sy = y; }

public void setRadius(double r) { if(radius>=0.0) radius=r; } public String getName() { return name; }

public int getBColor() { return borderColor; } public int getFColor() { return fillColor; } public int getX() { return sx; }

public int getY() { return sy; }

public double getRadius() { return radius; } public String toString() {

return "name = " + name + "\n" +

"border color = " + borderColor + "\n" + "fill color = " + fillColor + "\n" + "start x = " + sx + "\n" +

(35)

"start y = " + sy + "\n"+

"radius = " + radius;

} }

public class Square { private String name;

private int borderColor;

private int fillColor;

private int sx, sy;

private double length;

public Square() { // 0 is black name = "Square";

borderColor = 0;

fillColor = 0;

sx = 0; sy = 0;

length = 0.0;

}

public void setName(String name) { this.name = name; } public void setBColor(int c) { borderColor = c; }

public void setFColor(int c) { fillColor = c; } public void setX(int x) { sx = x; }

public void setY(int y) { sy = y; }

public void setLength(int l) { if(l>=0.0) length = l; }

public String getName() { return name; }

public int getBColor() { return borderColor; } public int getFColor() { return fillColor; } public int getX() { return sx; }

public int getY() { return sy; }

public double getLength() { return length; } public String toString() {

return "name = " + name + "\n" +

"border color = " + borderColor + "\n" + "fill color = " + fillColor + "\n" + "start x = " + sx + "\n" +

"start y = " + sy + "\n" + "length = " + length;

} }

public class Rectangle { private String name;

private int borderColor;

private int fillColor;

private int sx, sy;

private double length;

private double width;

public Rectangle() {

(36)

// 0 is black name = "Square";

borderColor = 0;

fillColor = 0;

sx = 0; sy = 0;

length = 0.0; width = 0.0;

}

public void setName(String name) { this.name = name; } public void setBColor(int c) { borderColor = c; }

public void setFColor(int c) { fillColor = c; } public void setX(int x) { sx = x; }

public void setY(int y) { sy = y; }

public void setLength(int l) { if(l>=0.0) length = l; } public void setWidth(int w) { if(w>=0.0) width = w; } public String getName() { return name; }

public int getBColor() { return borderColor; } public int getFColor() { return fillColor; } public int getX() { return sx; }

public int getY() { return sy; }

public double getLength() { return length; } public double getwidth() { return width; } public String toString() {

return "name = " + name + "\n" +

"border color = " + borderColor + "\n" + "fill color = " + fillColor + "\n" + "start x = " + sx + "\n" +

"start y = " + sy + "\n" + "length = " + length + "\n" + "width = " + width;

} }

Note: the first example without inheritance requires 122 lines.

Now we will redesign the previous example by using inheritance, the first class will be the Shape class which is the superclass of TwoDShapes class which is the superclass for Circle, Square, and Rectangle classes.

Example-2:

package Inheritance;

public class Shape {

protected String name;

private int borderColor;

private int fillColor;

public Shape() { // 0 is black name = "";

borderColor = 0;

(37)

fillColor = 0;

}

public Shape(String name, int bColor, int fColor) { this.name = name;

borderColor = bColor;

fillColor = fColor;

}

public void setName(String name) { this.name = name; } public void setBColor(int c) { borderColor = c; }

public void setFColor(int c) { fillColor = c; } public String getName() { return name; }

public int getBColor() { return borderColor; } public int getFColor() { return fillColor; } public String toString() {

return "name = " + name + "\n" +

"border color = " + borderColor + "\n" + "fill color = " + fillColor;

} }

public class TwoDShapes extends Shape { private int sx, sy;

public TwoDShapes() {

sx = 0; sy = 0;

}

public void setX(int x) { sx = x; } public void setY(int y) { sy = y; } public int getX() { return sx; } public int getY() { return sy; } }

public class Circle extends TwoDShapes { private double radius;

public Circle() { name="circle"; radius = 0.0; }

public void setRadius(double r) { if(radius>=0.0) radius=r; } public double getRadius() { return radius; }

}

public class Square extends TwoDShapes { private double length;

public Square() { name="square"; length = 0.0; }

public void setLength(int l) { if(l>=0.0) length = l; }

(38)

public double getLength() { return length; } }

public class Rectangle extends TwoDShapes { private double length;

private double width;

public Rectangle() { name=Rectangle;

length = 0.0; width = 0.0; }

public void setLength(int l) { if(l>=0.0) length = l; } public void setWidth(int w) { if(w>=0.0) width = w; } public double getwidth() { return width; }

public double getLength() { return length; } }

The second example designed with inheritance requires only 71 lines, organized, and can be reused in many new projects.

Note: that the Shape class is a subclass of the Object class even if we never use the extend keyword (Shape class implicitly extends Object class).

Now let's write a program to test example-2:

package TheTest;

public class Main {

public static void main(String[] args) { Circle c1 = new Circle();

// next sentence is wrong (constructor not found) Circle c2 = new Circle("Blue Circle", 3, 3);

c1.setName("Red Circle");// inherited from shape c1.setBColor(4); // inherited from shape

// next sentence is wrong (can't access private members) c1.borderColor = 4;

c1.setFColor(4); // inherited from shape

c1.setSX(130); // inherited from TwoDShapes c1.setSY(50); // inherited from TwoDShapes c1.setRadius(33.2); // defined in Circle

// will only print name, borderColor, and fillColor

System.out.println(c1.toString());//inherited from shape }

}

From the second example, we can say that:

1- Shape is the direct superclass for TwoDShapes.

2- TwoDShapes is the direct superclass for the Circle class (also for Square and Rectangle).

3- Shape is the indirect superclass for the Circle class (also for Square and Rectangle).

4- Circle (also Square and Rectangle) is a subclass of the TwoDShapes class.

5- TwoDShapes is a subclass of the Shape class.

(39)

6- Shape is a subclass of the Object class.

7- TwoDShapes is a superclass and also a subclass.

8- Circle, Square, and Rectangle are in the same level.

9- Constructors are not inherited.

10- Private members are inherited but can't be accessed directly (only via public methods).

11- Protected member "name" is inherited and can be accessed directly in all subclasses (TwoDShapes, Circle, Square, Rectangle) also it can be accessed in any class inside this class, but it could not be accessed in class main because it is not subclass and not in the same package.

1.20 Calling Superclass Constructors

If we want to add another constructor for the TwoDShapes class:

public class TwoDShapes extends Shape { private int sx, sy;

public TwoDShapes() {

sx = 0; sy = 0;

}

public TwoDShapes(String name, int bc, int fc, int sx, int sy) { this.name=name;

setBColor(bc);

setFColor(fc);

this.sx = sx;

this.sy = sy;

}

public void setX(int x) { sx = x; } public void setY(int y) { sy = y; }

public int getX() { return sx; } public int getY() { return sy; } }

But instead of doing so, you can use the super keyword to call a constructor in the superclass, so the second constructor can be changed to this:

public TwoDShapes(String name, int bc, int fc, int sx, int sy) { super(name, bc, fc);

this.sx = sx;

this.sy = sy;

}

Now let's add another constructor for the Circle class:

(40)

public class Circle extends TwoDShapes { private double radius;

public Circle() { radius = 0.0; }

public Circle(String name, int bc, int fc, int sx, int sy, double r) {

super(name, bc, fc, sx, sy);

setRadius(rad);

}

public void setRadius(double r) { if(radius>=0.0) radius=r; } public double getRadius() { return radius; }

}

1.21 Overriding Methods

One problem with inheritance is that a subclass can inherit methods that it does not need or should not have. Even when a superclass method is appropriate for a subclass, that subclass often needs a customized version of the method. In such cases, the subclass can override (redefine) the superclass method with an appropriate implementation.

For example, in the second example, the toString method of Shape only prints name, borderColor, and fillColor, it does not print:

1- sx, sy, and radius for the Circle class 2- sx, sy, and length for the Square class

3- sx, sy, length, and width for the Rectangle class.

And in order to solve this problem, each of these classes (Circle, Square, and Rectangle) need to provide their own toString method, they need to override the old method inherited from the Shape class.

So the new TwoDShapes class should be like this:

public class TwoDShapes extends Shape { private int sx, sy;

public TwoDShapes() {

sx = 0; sy = 0;

}

public void setX(int x) { sx = x; } public void setY(int y) { sy = y; } public int getX() { return sx; } public int getY() { return sy; } public String toString() {

return "name = " + getName() + "\n" +

"border color = " + getBColor() + "\n" +

References

Related documents

Area Custodial Coordinators 5 FTE Custodial Staff 14 FTE Custodial Services Administrator 1 FTE Director of Maintenance 2 FTE Environmental Programs 9 FTE Energy Management 2

public static double findRectArea(double length, double width) {.. return length

(1) Grand total amount (from Z1 report tape) - amount in foreign bank drafts = regular amount to be deposited. c) Complete and make a copy of the daily Collection Summary Sheet.

Bracketed by eight dental hygiene students, and backed by administrative and official well wishers, Kristi Wilkins, chair, Department of Dental Hygiene, Loma Linda University School

 A strict credit policy can lead to missed sales.. A

The latest Angus Reid Global (ARG) survey on perceptions of crime, safety and justice in shows Canadians are feeling a little safer than they were two years ago, and

Suppose now that we want to create a new class, Square, for square boxes for which length = width. This class is clearly a sub-class of Box and will inherit most of its variables

No peddler, solicitor, or transient merchant, unless invited to do so by the property owner or tenant, shall enter the property of another for the purpose of conducting business as