Object Oriented Programming (oop)

Although we write the programs in a general way, the objects themselves cause the behavior to be specific. This lets us write programs that will work correctly even for objects that haven't been invented yet.

5.1 Inheritance
We have already been using the terms Superclass and Subclass. A superclass is the parent class while a Subclass is the child class. A subclass inherits the behavior and variables of its Direct superclass.
Therefore in the following code JOptionPane inherits all the methods and all the encapsulated data variables that lie within JComponent.
+--java.awt.Component
.
+--java.awt.Container
.
+--javax.swing.JCmponent
.
+--javax.swing.JOptionPane
Class JOptionPane inherits from class JComponent.
But wait a second. Isn't JComponent the Subclass of Container? Correct. So, that tells us JComponent inherits all the methods and all the encapsulated data variables of Container. Container is the Superclass. So, when JOptionPane inherits everything from JComponent (which itself inherited everything from container), that must mean JOptionPane inherits everything from both JComponent and Container, So, let's put this together: the JOptionPane inherits all the methods and all the encapsulated data variables in all the superclasses above it.
To understand how this happens consider this question – When we want to create a copy of some object, what do we do? We use the new keyword to fire off the Subclass object's Constructor and we instantiate the object. And so, if we want to create a copy of the superclass, we need to somehow, fire off the superclass object's Constructor.
Whenever you extended another class. (a class superclass) you have created an instance of every above your class in the class hierarchy. When the Constructor for sales fires, it silently also fires the Constructors for JApplet and every other class above JApplet in the hierarchy:
Public class sales extends JApplet
{

}
When the Constructor for sales fires, it silently also fires the Construtors for JApplet and every other class above JApplet in the hierarehy.
The adds, that implies it already has everything else. By the time your subclass is created, it already has an instance of every superclass above it and every single thing the superclass contain. Every method, every data variables present in the superclass is also present in the subclass. The point to note here is that if your class has everything above it then you can say it is an example of the classes above it. Finally, since the Subclass has everything the Superclass has, we can say that every Subclass is also an object of the Superclass.
So, let's ponder this: JOptionPane inherits from JComponent. The JoptionPane inherits everything JComponent, JoptionPane is a Container JoptionPane is a Component and JoptionPane is an Object.
Classes-object, Component and Container are Indirect Superclass to the JoptionPane ,JComponent is the Direct Superclass to the JoptionPane. We say JoptionPane is a Jcomponent a container, Component, and an Object.

5.2 Impact of access modifiers
Access Modifiers are among the thorniest and most confusing aspect of OOP. But, remember, encapsulation is one of the priMaya benefits of object orientation, so access is important. The familiar private access modifier lets us shield our instance variables from the prying eyes of the outside world. Relying on Access Modifiers, you can shield both your class's private instance variables and its private methods. With those ends in mind, Java let's review the four different levels of access: private, protected, public and the default if you don't specify-package.
Specifier class Subclass Package World
Private x
Package x x
protected x x x
public x x x x

As you can see, a class always has access to its own instance variables, with any access modifier. The second column shows that Subclasses of this class (no matter what package they are in) have access to public (obviously) and protected variables. Therefore, the important point is that Subclasses can reach protected-access variables, but can't reach package-access variables unless the Subclass happen to be saved in the same package. The third column "package" shows that classes in the same package as the class (regardless of their parentage) have access to data variables. In the fourth column, we see that anything and anyone has access to a public data variable or method—defeating the purpose of encapsulation.

5.2.1 Private
When a class inherits from a Superclass, you cannot access the Superclass's private data variables. The private data is Secret, In other words, the Subclass cannot automatically reach the private data variables of the Superclasss. A private data variable is accessible only to the class in which it is defined.
Objects of type Alpha can inspect or modify the iamprivate variable and can call privateMethod, but objects of any other type cannot.
class Alpha
{
private int iamprivat;
public Alpha (int iam)
{
iamprivate = iam;
}
private void privateMethod ( )
{
iamprivate = 2;
System.out.printin ("" + iamprivate);
}
}
The Beta class, for example, cannot access the iamprivate variables invoke privateMethod on an object of type Alpha because Beta is not of type Alpha.
class Beta
{
public void accessMethod ( )
{
Alpha a = new Alpha ( ) ;
a.imprivate = 10; // Invalid
a.privateMethod 9 ); // Invalid
}
}
The compiler would complain if you tried this. so can one instance of an Alpha object access the private data variables of another instance of an Alpha object? well yes objects of the same type have access to one another private members.

5.2.2 Package
If you do not specify the access for either a method or an encapsulated data variable, then it is given the default access: package. This access allows other classes in the same package as your class to access its data variables as if they were their own. This level of access assumes that classes in the same package as your class are friends who won't harm your class' data.
Notice that no access modifier is declared. So, iamprivate and method privateMehod both default to package access. All classes declared in the package Greek. along with class Delta, have access to iamprivate and privateMethod.
package Greek;
class Delta
{
int iamprivate;
void privateMethod ( )
{
system.out.printin ("privateMethod");
}
}
If you use multiple objects from the same package, they can access each other's package-access methods and data variables directly, merely by referencing an object that has been instantiated. With package access, other objects in the package don't have to bother going through the methods. They can get right to the variables. So, when you don't include any access modifier, you are in fact giving your variable package access.
int x; // package access instance variable
Notice, it's declared neither public not private.

5.2.3 Protected
Protected allows the class itself, Subclasses and all classes in the same package to access the members. Generally speaking, protected offers greater access than package access. Use the protected access level when it's appropriate for a class's subclasses to have access to the member, but not for unrelated for class's Subclasses to have access. Protected members are like family secrets—you don't mind if someone in the family knows—but you don't want outsiders to know.
The Access Modifier protected can be used on either a method or an encapsulated data variable. Protected serves as a middle ground between the private and public access modifier. A Superclass's protected data variables may be accessed only by: methods of Superclass, methods of the Subclass or methods of other classes in the same package.
To summarise protected members have package access. Protected access means the variable is public to the class, private outside the class, and public to the subclasses. It's like the Subclasses can reach up and get access to the data variables of the Superclass.

5.3 Super reference
Already, we know that the Superclass-subclass interaction has a big effect on the Constructor. The Superclass Constructors are either implicitly or explicitly called first in the Constructor of a Subclass.
super (whatever the Superclass needs)
Using this super reference, you can call the Constructor of your Subclass' Direct Superclass. If you use this super reference, then it must be the very first statement in eh subclass' Constructor.
public class Employee
{
string name;
staring SSN;
public Employee (string nm' string soc)
{
name = nm;
SSN = soc;
}
public double cale_pay ( )
{
return 0.0;
}
}
public class HourlyEmployee
extends Employee
{
double hourly_rate;
int hours;
public HourEmployee ( )
{
// implicit (hidden) call to superclass constructor,
hourly_rate = 0.0;
hours = 0;
}
public HourlyEmployee (string n, string s, double r, int h)
{
// implicit (hidden) call to superclass constructor,
hourly_rate = r;
hours = 0;
}
public double calc_pay ( )
{
return hours * hourly_rate ;
}
}
public class HourlyEmployee
extends Employee
{
double hourly_rate;
int hours;
public HourEmployee ( )
{
super (n, s) ; // Explicit call to Superclass constructor
hourly_rate = 0.0;
hours = 0;
}
public HourlyEmployee (string n, string s, double r, int h)
{
super (n,s) ;n // Wxplicit call to superclass constructor,
hourly_rate = r;
hours = h;
}
public double calc_pay ( )
{
return hours * hourly_rate ;
}
}

There is a similar statement that is used to call your Subclass' constructor within your Subclass. Don't get the two confused.

5.4 Subclass as an object of the Superclass
A subclass contains more than its Superclass contains. Because of that, we say inside of a Subclass is complete copy of its Superclass. Previously, we said a Subclass is an object of the Superclass type. Now, we take that one step further. A Subclass contains everything (and more) required to make a complete example of the Superclass. In other words, in certain situations, we can ignore the difference between the Superclass and Subclass objects,.
An object of a Subclass can be treated as an object of its Superclass. What would stop this from being true? Is there any part of the Superclass that in missing from the Subclass? Well no it's all there. Certainly if we are asking a Subclass to fill in for its parent. We throw away the extra stuff that the subclass added, but—because a subclass "is an" example of its Superclass—we can "treat the Subclass as an example of the superclass. " And, if we only want to call the methods from the Superclass and access the data variables that come from the Superclass—what's the difference?
Doing this might be interesting. As long as we treat the reference llike it only refers to the Superclass, we can handle a Suclass object from a Superclass "reference." As long as we only call the methods that exist in the Superclass, this will work fine.
public class Employee
{
string name;
staring SSN;
public Employee (string nm' string soc)
{
name = nm;
SSN = soc;
}
public double cale_pay ( )
{
return 0.0;
}
}
public class HourlyEmployee
extends Employee
{
double hourly_rate;
int hours;
public HourEmployee ( )
{
return hours * hourly_rate ;
}
}
public class salariedEmployee
extends Employee
{
double mountlySalary;
public double calc_pay ( )
{
return monthlySalary;
}
}
public class TestEmp
{
public money = 0.0;
HourlyEmployee hour;
hour = new HourlyWmployee ( ) ;
money = hour.calc_pay ( ) ;
system.out.println ("Money" + money ) ;
}
}
public class TestEmp
{
public static void main (string args [ ] )
{
double money = 0.0;
SalariedEmployee salr;
salr = new SalariedEmployee ( ) ;
money = salr.calc_pay ( ) ;
system.out.println ("Money=" + money ) ;
}
}
public class TestEmp
{
public static void main (string args [ ] )
{
double money = 0.0;
Employee empl;
empl = new salariedEmployee ( ) ;
money = salr.calc_pay ( ) ;
system.out.println ("Money=" + money ) ;
}
}
As long as we only call the methods that exist in the Superclass, this will work fine.
public class TestEmp
{
public static void main (string args [ ] )
{
double money = 0.0;
Employee empl;
empl = new salariedEmployee ( ) ;
money = salr.calc_pay ( ) ;
system.out.println ("Money=" + money ) ;
}
}
So, why in the world might want to do this?
public class RetiredEmployee
Extends Employee
{
double monthlyPension;
public double cale_pay ( )
{
return mothlypension;
}
}
Imagine if after we built our system we decided to add a class, for Retired Employees. If we had built our program on a Superclass reference, then we wouldn't have to rebuild anything. The runtime environment sees what kind of object we have instantiated, and calls the right method override.
public class TestEmp
{
public static void main (string args [ ] )
{
double money = 0.0;
Employee empl;
empl = new salariedEmployee ( ) ;
money = salr.calc_pay ( ) ;
system.out.println ("Money=" + money ) ;
}
}
Caution, this works only when you're calling a method that exists in your Superclass, not one thay exists only in the Subclass. And so now you see the advantage of identifying a bunch of empty methods in your Superclass. And the whole process is called, polymorphism.

5.5 Polymorphism
We can create a Superclass reference that is an array. Then, when we instantiate the array, we can attach all different kinds of Subclass objects to the Superclass array reference. As long as we're only calling methods that exist in the Superclass, we can work our way through the array and it will call all the correct overridden versions of each individual Subclass object. The Superclass reference only knows about methods that exist in the Superclass. The Superclass only tries to call the methods it knows about. That's perfectly fine, because all the methods in the Superclass are available in its Subclass.
Therfore the Superclass isn't aware that the object it references can do a whole lot more than the Superclass thinks it can. So, "We can create a Superclass reference array that actually points to Subclass object." As long as we treat those Subclass objects as if they were Superclass objects, (meaning we only call the methods in the Superclass) we have no problems. The Subclass knows how to do everything its parent Superclass can do. The kinds can do everything the parent can.
However, if we try to do it the other way around, treating the Superclass as if it were one of its children then we can have problems. The Subclass can do many things the Superclass cannot. The kids can do many things the parent cannot. If we called the Superclass with the Subclass's reference, then you might expect the Subclass reference can do all things the kids can and you'd be wrong. If you want to go the other way, attach a Superclass object to a Subclass reference. You have to do an explicit cast, as a way of informing the compiler that you really want to do this dumb thing.
A suprclass object is not Subclass object. An HourlyEmployer is an Employee (Superclass is not subclass object). If you want to actually call some of the methods that don't exist in the Superclass, then you have to first cast the object back to a reference of its own kind.

5.5.1 Constructors and finalizes in subclasses
Whenever you instantiate a Subclass object, the Constructors for the Superclass should be called to initialize the instance variables of the Superclass. This instantiation can be done either implicitly or explicitly (via the super Reference). These calls to instantiate the superclass object must the first thing in your class's Constructor method. The opposite of the constructor method is the finaliser method. If your class bother to define a must be the last thing in the finalizer method. You will always want to difine your finaliser method as protected, So that Subclasses that inherit from your class can access its finalizer. Classes that only use Superclass object (not inherit them) cannot use the Superclass's finalizer methods.
You must always use this "super" reference when you intend to call the finaliser of the Superclass. If you omit the super class, you're actually calling the finaliser of the method you're already inside of – which is called infinite recursion. You cannot do a cascading call to a Superclass. Instead, you have to rely on the Superclass itself to call its own Superclass.

5.5.2 Implicit Subclass-object to Superclass-object conversion
In order to understand the concept of subclass and superclass object, let's consider the following illustration. Ravi was feeling entrepreneurial, and so he decided to buy a piece of land in Bihar. Ravi paid 250 for what the deed described as a wooden shack in the swamp. But, to his great surprise, when he got there, Ravi discovered he hadn't bought a shack in a swamp, but rather, the Taj Mahal on a beautiful lake. Ravi was ecstatic. Ravi got more than he was promised. Maya was feeling entrepreneurial too, and so she decided to buy a huge mansion on an estate in Bihar. She paid 25 Million for what the deed described as a palatial estate on 40 acres of land. But, to her great surprise, found she hadn't bought a magnificent mansion and estate, but rather, a Doublewide trailer next to a dump. Maya was horrified. Maya got less than was promised.
Ravi's situation is akin referring to a Subclass object with a Superclass reference. You get more than you expected. It's a pleasant suprprise.
superclassRef = new subclassobject
Maya's situation is akin to a superclass object with a Subclass reference. You get less than you expecte. It's a tragic mistake.
SubclassRef = new Superclassobject
Therer are four possible conversions that can occur:
1. Refer to a Superclass object with a Superclass references. This is routine
2. Refer to Subclass object with a Subclass references. This is also routine
3. Refer to Subclass object with a Superclass references.
This is safe because the Subclass object is an object of its Superclass. Such code can only refer to Superclass methods. You can make an array of Superclass reference. Then, you can treat them the same, as if they really were all Superclass objects. As long as you call methods that exist in the Superclass (but were overridden by each of the various Subclasses). then the runtime system calls the correct overridden method for each on. This process is known as Dynamic Binding.
4. Refer to a Superclass object with a Subclass reference.
This is a syntax error! It doesn't make sense. It is only remotely possible if the subclass is explicitly cast into a Superclass reference. which is a way of telling the compliler you are doing this damn-fool thing with your eyes open. Here's the problem: A Subclass contains more and does more than its Superclass parent. If you use a Subclass reference to point to a Superclass object, you are implying that the object has more data variables available than it really does—and if someone made that assumption—they would be sorely mistaken.

5.5.3 Use polymorphism
class Employee
{
private String ssn;
public Employee ( )
{
ssn = " " ;
}
public Employee (string soc_num)
{
ssn = soc_num;
}
public string getSSN ( )
{
return ssn;
}
public double calcpay ( )
{
return 0;
}
}
Employee is our Superclass. As we see, it contains the instance variable string ssn, a Constructor, the Accessor method getSSN() and the empty method calcpay(), which we will need to override in all the Subclass because they will all need to calculate pay differently.
class Hourl Employee extend Employee
{
double hourRate;
int hoursWorked;
public aHourly Employee ( )
{
hourlyRate = 0.0;
hoursWorked = 0;
}
public void setHourlyRate (double rate)
{
hourlyRate = rate;
}
public void setHoursWorked (int hours)
{
hourWorked = hours;
}
public double calcpay ( )
{
return hourlyRate * hoursWorksed;
}
}
public class DemoPolymorphism
{
double pay = 0;
public DemoPolymorphism ( )
{
Employee supEmp = new Hourly Employee ( ) ;
Hourly Employee subHrEmp = new Hourly Employee ( ) ;
pay = supEmp. calcPay ( ) ;
system.out.println ("Superclass pay = " + pay ) ;
subHrEmp.setHoursWorked (20) ;
pay = SubHrEmp.calc_pay ( ) ;
System.out.println ( "Subclass pay = " + pay ) ;
supEmp = subhrEmp;
pay = supEmp. calcPay ( ) ;
system.out.println ("Superclass pay = " + pay ) ;
}
public static void main (string [ ] args )
{
DemoPlymorphism demo = new DemoPolymorphism ( ) ;
}
}
we declare a reference to an object of type Employee called supEmp. However, we instantiate an HourlyEmployee object and assign the reference to the SuperclassEmployee. This works because—afterall—HourlyEmployee is an Employee.
public class DemoPolymorphism
{
double pay = 0;
public DemoPolymorphism ( )
{
Employee supEmp = new Hourly Employee ( ) ;
Hourly Employee subHrEmp = new Hourly Employee ( ) ;
pay = supEmp. calcPay ( ) ;
system.out.println ("Superclass pay = " + pay ) ;
subHrEmp.setHourlyRate (5.65) ;
subHrEmp.setHoursWorked (20) ;
pay = SubHrEmp.calc_pay ( ) ;
System.out.println ( "Subclass pay = " + pay ) ;
supEmp = subhrEmp;
pay = supEmp. calcPay ( ) ;
system.out.println ("Superclass pay = " + pay ) ;
}
public static void main (string [ ] args )
{
DemoPlymorphism demo = new DemoPolymorphism ( ) ;
System.exit (0 ) ;
}
}
superclass pay = 0.0
subclass pay = 113.0
superclass pay =113.0
press any key to continue . . .

The Wrong way to Use polymorphism—a Syntax Error—(Without An Explicit Cast)
public class CastSubTypeReftoSuperTypeobject
{
double pay = 0;
public CastSubTypeReftoSuperTypeobject
{ // Syntax Error ! ! !
HourlyEmployee subHrEmp = new Employee ( ) ; // Error !
// The error is not yet revealed.
pay = SubHrEmp.calcpay ( ) ;
System.out.println ( "Subclass pay = " + pay ) ;
// Error because the objeft doesn't have these
// methods available.
subHrEmp.setHourlyRate (5.65) ;
subHrEmp.setHoursWorked (20) ;
pay = SubHrEmp.calc_pay ( ) ;
System.out.println ( "Subclass pay = " + pay ) ;
}
public static void main (string [ ] args )
{
CastSubTypeReftoSuperTypeobject demo;
demo = new CastSubTypeReftoSuperTypeobject ( ) ;
system.exit (0) ;
In the program, we know that SubHrEmp was declared as a type HourlyEmployee. But instead of getting a Mansion (HourlyEmployee), the reference was assigned to a Doublewide Trailer (Employee). The object doesn't have these methods and these message calls won't work!
C:\ CastSubTypeReftoSuperTypeobject.java:59:
Incompatible type for declaration.
Explicit cast needed to convert Employee to HourlyEmployee.
HourlyEmployee subHrEmp = new Employee ( ) ; // Error!
^
1 error
Tool completed with exit code 1
At this point, the compliler is extremely unhappy. So, let's give it what it is specifically asking for an explicit cast and see what happens then.
public class DemoPolymorphism
{
double pay = 0;
public DemoPolymorphism ( )
{
Employee supEmp = new Hourly Employee ( ) ;
{ // Now we've Band-Aided the Error with An
// Explicit cast
HourlyEmployee subHrEmp;
subHrEmp = (HourlyEmployee) new Employee ( );
// The error is not yet revealed.
pay = SubHrEmp.calc_pay ( ) ;
System.out.println ( "Subclass pay = " + pay ) ;
// Error because the objeft doesn't have these
// methods available.
subHrEmp.setHourlyRate (5.65) ;
subHrEmp.setHoursWorked (20) ;
pay = SubHrEmp.calc_pay ( ) ;
System.out.println ( "Subclass pay = " + pay ) ;
}
public static void main (string [ ] args )
{
CastSubTypeReftoSuperTypeobject demo;
demo = new CastSubTypeReftoSuperTypeobject ( ) ;
system.exit (0) ;

Exception in thread "main" java.lang.ClassCastException: Employee at
astSubTypeReftoSuperTypeobject.(CastSubTypeReftoSuperTypeobject.java:60)atastSubTypeReftoSuperTypeobject.main (CastSubTypeReftoSuperTypeobject.java: 75)
Press any key to continue . . .
At this stage, the compiler is incensed, it trusted us when we asked for that Explicit cast, and look what happened.

5.6 polymorphism and dynamic binding
Say that we have a bunch of objects that are all Shapes: Circles, Squares, Triangles, Trapezoids, etc. If we want to draw them all, we could use a large switch statement that asks if the object is a circle, do this, if a square, do this. If a triangle, do that. The big switch could work okay. but if we decided to add a parallelogram to our shapes, then we would have to remember to add another Brach to our switch statement. Every place we wanted to do some behavior based on the shape, we would have to change our logic.
Polymorphism can save us that trouble and make programs that will work with Shapes that hadn't even been thought of when the class was written. with polymorphism, the objects themselves know what kind of object they are, and they do the right behavior based on their internal awareness of their own type. In our Shapes example, we could assume that each shape Subclass that inherits off of the master superclass—shape –would have a draw() method. That draw() method would detail exactly how to generate the Square or the circle or the Triangle. Each shape subclass knows how to draw itself. Certainly, we could go through the trouble of drawing each shape one by one. But wouldn't it be nice if we could just treat all those various shape subclasses as copies of it be nice if we could just treat all those various shape subclasses as copies of the superclass? Then we could create an array of Superclass references that actually are initialized with subclass objects. We could move through the array calling the draw() method of the superclass for each element in the array. The overridden draw() methods in each Subclass shape could take care of drawing the shape the right way.
Therefore, to make this work, the only thing we have to remember is, Declare draw() in the Superclass, then, override draw () in each of the Subclass to draw the correct shape. The Run-Time Type Identification system will choose the correct subclass's draw() method dynamically i.e., on-the-fly at execution time. This is called dynamic method binding, and it makes polymorphism work. Polymorphism relies on Dynamic Binding. Polymorphism, allows you to process superclass objects in a Generic way. Only the parts of a program that need specific knowledge of the new class must be tailored specifically to the new class.