Monday 26 December 2011

Oops! Oop is so easy and fun to learn.

Hi, this is Mary Herberth, a private computer-science teacher (for interested high school students) by profession for over a decade now. I'd like to share the way I used to teach a bunch of my students the basics of Java that I found effective, easy and effortlessly graspable.
This was how it all started with the unorthodox procedure I'd designed:
Disclaimer: Some of the stuff used to explain a few things might be mischievous.
-------------------------------------------------------------------------------------------------------------
 

 
--------------------------------------------------------------------------------------------------------------------------
 
Well consider me as a ‘class’ – a LadyTeacher class. That actually means I’m like a template for creating other ‘LadyTeacher’ objects, much like a blueprint.
And as a ‘class’, I can have, basically, my instance variables and methods.
Instance variables’ are what I have, while ‘methods’ are what I can do.
 
 Roses are red and violets are blue,
‘Instance Variables’ are ‘what I have’ and ‘methods’ are ‘what I can do’.
 
To illustrate, my ‘qualification’, ‘experience’ and even my ‘beauty’ (which itself might be an object of ‘Beauty’ class) are all my ‘instance variables’.
Meanwhile, some stuff that I could do, like doTeaching(), clearDoubts(), giveTuitions() are my methods – because I can ‘do’ them.
 
However, I’m not a standalone authority teaching you here but I adhere to some norms, of say Teachers’ Association, who mandate all teachers to implement some methods (note the word ‘mandatory’).
So, I’m said of ‘implementing’ an ‘interface’ (Teachers’ Association) and I’m compelled to implement its methods. (Say it mandates me to take attendance of students)
Syntactically,
public class LadyTeacher implements TeachersAssociation {
public void takeAttendance()
{
}
}
 
Wait, you might ask what’s that ‘public’ for in ‘public void takeAttendance()’ ??
Well, imagine I’ve got a set of methods (what I could ‘do’) and each one of them is of a different kind for me. For example, takeAttendance() is a method I’m not much worried about and hence I don’t mind if it’s called from outside of my class or outside of my package. So I keep it ‘public’ – “visible from anywhere”. And this applies to methods. When it comes to variables, there are some minor changes which I’ll explain you soon.
But imagine I’ve got a method called checkMyAge() that returns my presentAge (a variable, what I ‘have’). Obviously, I don’t want an outsider to know my age (although I can fake and return ‘18’ every time someone calls it). I’m having that method just for my internal calculations, say to fill up some form and is supposed to be called only from my class. No one else should be able to use it upon me. So, I declare it ‘private’.
 
Also, since I’m a lady teacher, I, by default, have all the methods (what I could ‘do’) of a ‘Lady’, as a Lady teacher can still deliver a baby.
This eases my task of taking care of most of my methods just by extending ‘Lady’ class, inheriting all its methods at once (This does allow me to have my own teacher-specific methods as well).
public class LadyTeacher extends Lady implements TeachersAssociation{
public void takeAttendance()
{
}
}
 
But wait, I’m not just a lady, I’m an alumnus of Harvard University too, I need THEIR methods as well! Cool, I can inherit multiple classes??
Well, it turns out that you can’t. Java does NOT allow ‘multiple inheritance’. A class can have at most, one superclass.
But implementing multiple interfaces is allowed, you can use them.
 
Why I am not allowed to extend multiple classes?
Well, the answer looks pretty simple. But before we get there, let me tell you what ‘overriding a method’ is.
 
As I told you, a method is something which I ‘do’. Now if I extend a class, say Lady class, by default I inherit all the public and protected methods (‘do’) of the Lady class. This makes my life easier as I need not write method bodies for washClothes(), wearABra() etc again because they are already present in my superclass, the Lady class. But imagine, I’m such a pervert that I don’t wish to wear a bra and hence want to return false (or null) for wearABra() method. How could I achieve that? There comes this concept of method overriding: You override a method by including it in your class and coding it the way you wish. So, I override wearABra() in my class.
 
public class LadyTeacher extends Lady implements TeachersAssociation{
public void takeAttendance()
{
}
public String wearABra()
{
                                 return(“It’s none of your business”);
}
}
 
Coming to the previous question: Why not am I allowed to extend multiple classes?
In a line, to avoid conflicts while calling methods. Elaborating, if I (the Teacher class) extend two classes, say HarvardUniversity class and KennedyHighSchool class (this was where I did my schooling) which are both in-turn extended from one single superclass , say EducationalInstitutions class, then when any method of this superclass (EducationalInstitutions) if overridden by both its subclasses (HarvardUniversity and KennedyHighSchool) , say calculateGrade() method, is called from my class (the Teacher class where that’s not overridden), then there’s an obvious ambiguity for the JVM in deciding which of them should be called. Single inheritance avoids this.
 
So what’s the workaround?
You can implement multiple interfaces (be careful while interpreting this, YOU CAN IMPLEMENT MULTIPLE INTERFACES, not the methods again). This gives you a decent way of using whatever methods you’d like to call.
 
Now imagine some method (what I ‘do’) say, getExperienceInfo() which I want to be used by myself and anyone who’s sitting in my super-class hierarchy. That’s the default accessor, you don’t need to specify anything for them. There’s a last type of accessor called ‘protected’ that can be called by anyone from within your ‘package’ (More on packages in next class).
 
But before anything else, I’d like to tell you how the LadyTeacher objects (the individual LadyTeacher s) are created. Every class has something called a ‘constructor’. When you create an instance of a class, or speaking of this context, if you create a LadyTeacher object (an individual LadyTeacher) out of the LadyTeacher class, it’s the constructor where the ‘creation’ happens.
This is how you create a LadyTeacher object using its constructor typically:
 
LadyTeacher missClara = new LadyTeacher(); // here missClara is the name of the LadyTeacher object you’ve just created. Note that this is the name of the teacher variable, not of the just created teacher.
 
With this, a part of heap is allotted to the newly created LadyTeacher object, missClara.
We call ‘missClara’ a reference to the object freshly created.
Now to do this, the LadyTeacher class should contain a constructor or any superclass from its superclass hierarchy should. By default, all classes are primarily extended from the ‘Object’ class. So if none of the classes used appear to contain the constructor, don’t worry, Object class provides one, at least that’s not an error, although most of the time you would be providing or using some constructor aptly.
Okay, let’s create a constructor for our LadyTeacher. But wait, while creating a new object (a new LadyTeacher in this case), one might be having different criteria or parameters, say sometimes one wouldn’t be knowing the teacher’s name, sometimes you do and such. To facilitate all that, you can have multiple constructors in your class, all with the same name – the class name itself, but with different parameters. Typically, as just mentioned, the name of the constructor is the name of the class itself.
 
As illustrated below, here there are two constructors (with the same name- the class name itself), one of which doesn’t take any argument and the other requires the name of the teacher. If you call the first constructor while creating a new LadyTeacher (object), it assigns missJenkins as the name of that teacher.(Note here: nameOfTeacher is an instance variable as I mentioned already, something I have) . On the other hand, if you want to name your teacher yourself, you need to call the second constructor to whom you need to pass the name, like this:
 
LadyTeacher missClara = new LadyTeacher(“Clara Hatterbern”);
 
And this is the class now:
public class LadyTeacher extends Lady implements TeachersAssociation{
String nameOfTeacher;
                public LadyTeacher()
{
nameOfTeacher = missJenkins;
}
 
public LadyTeacher(String name1)
{
nameOfTeacher = name1;
}
 
public void takeAttendance()
{
//......
}
 
public String wearABra()
{
           return(“It’s none of your business”);
}
}
 
This particular thing what you just saw is called “constructor overLOADING". In general, any method can be overloaded this way keeping in mind that their signature(the argument list and the return value are collectively referred as the signature of a method) should be different. In that case, it’s referred as ‘method overLOADING’.
 
Now imagine you need to know how many LadyTeachers are there in the whole of US of A. Obviously, to be a LadyTeacher, one has to create the LadyTeacher instance. So, understandably, the total number of LadyTeacher objects created is what we are looking for. But how do we calculate this? Yes, we need to keep a counter. Where? Right, inside the constructor of the LadyTeacher class, because that’s where LadyTeachers are created. But it should be done in such a way that it’s the property of the class and not of the individual objects (individual LadyTeachers). Obviously, why should any specific LadyTeacher be keeping the count of the total number of LadyTeachers of the country? There come the ‘static’ variables. As told before, ‘variables’ are those which we ‘have’. ‘static’ variables are those which are specific to a class (LadyTeacher class) rather than to the individual objects (individual LadyTeacher s). Other way put, ‘static variables’ are NOT the property of any object (any LadyTeacher herself) but of the class (the LadyTeacher class, the blueprint). So ‘static variables’ retain their values throughout and it doesn’t get re-initialized when new objects are created (well, unless that’s not what are looking for).
 
===== to be continued in the next class =====