Sunday 16 June 2013

Why Students are not Persons and also Employees are not Persons either !! Well lets see whats goin on....

Consider the following structure :

Employee -------- > Person <--------- Student 


Both Employee and Student extends Person.

(Note that arrow is always towards the Parent class and tail towards the subclasses)

Now 

Each Student is a Person.
Each Employee is a Person.

So

Person somePerson = new Student();            // perfect no probs!!
Person someOtherperson = new Employee(); // perfect no probs either!!

Also 

Student student = new Student ();
Employee emp = new Employee();
Person p = student ; // perfect
p = emp; // perfect

So Basically if a Child extends or implements Parent , depending upon if Person is a class or an interface, below code do not pose any problems.
( Assuming Child is a concrete class with default public constructor )

Parent parent = new Child(); 


NOW Having said all that above lets have some more  students and employees. ( Below <Type> any thing that goes inside <> is Generic type. If it goes with List<T> this means List is a collection of objects of type T, T may be  Student, Employee etc. )

List<Student> students = new ArrayList<Student>();

List<Employee> employees = new ArrayList<Employee>();

so now a question : 

List<Person> persons = students;

is perfect or is there some thing wrong. Going by the intuition and if  above was well absorbed then answer should be yeah, this is just perfect. Isn't a group of students a group of Persons, they are.

OK now having agreed upon that lets see this.

No problems with 

 List<Person> persons = students; 
=> persons and students both points to a single object which is a
List of students.

But hey, all employees are persons too, 

persons.add(new Employee()); //this should be perfect too.

Whats wrong with that. !!

Okkss are we adding an Employee to a List of Students

Hmmm.... no we don't want that. Students are students Employees are Employees, though both are Persons.

Hence. from above :


List<Student> students = new ArrayList<Student>();

List<Employee> employees = new ArrayList<Employee>();

so now a question : 

List<Person> persons = students;  

 this is NOT OK!!.  This can lead to addition of Employees to students.


__________________________________________________________________

So whats the catch : 

Basically when it is said :
Student s = new Student();
Person p = s;

There is only one object to which both p and s points to.

Now if We say 

Employee e = new Employee();

and 

p = e;

Now p no more points to Student object , now both e and p points to Employee Object and s points to Student alone. So no HARM.

But when we say 
List <Student> students = new ArrayList<Student>();
List<Person> persons = students;
persons and students points to object of a list of Students but same time persons can have more persons being added to it like Employees so This leads to addition of Employees to the list of Students and hence COMPILER says this is not done .

Students derive from Persons but 
List<Student> do not derive from List<Person>.


List<Person> persons = new ArrayList<Person>();
persons.add(new Employee());
persons.add(new Student());

this is ok but 

persons = new ArrayList<Employee>() is NOT OK.


________________________________________________________________________________

few extra words: 


OK now having the above understanding there are few more things to explore like the wild cards,etc. Also in java 7 we have few new features like 

we can say 

List<Student> students = new ArrayList<>(); // This is acceptable. On right hand side we can skip the type and simple <> shall suffice.
  
Also it is always a good idea to program to interfaces or super types for flexible design ( SuperType variable taking objects of Sub types as Person p = new Student(). and on left hand we have List and on right hand side we have ArrayList. This is a good design, Better read more on this!!)



Good Luck!!

Krishna

10 comments:

  1. Nice piece of information. Keep it up!!

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. I have a doubt :O
    is it valid if student extends both employee and person classes??????

    ReplyDelete
    Replies
    1. @Khushi, First of all thanks for the comment,

      Khushi is a nice name and seems I got a topic for my next non technical blog. The name means happiness. :)

      Also the question asked inspire me to write another blog over multiple parent classes for a child class:

      But in short I shall try to answer the question.

      The simple answer you can find is the Diamond problem but apart from that there s little more than the diamond problem. I ll try to make u understand in short here .

      Suppose There is a class Food having an abstract method

      public abstract String getTaste(),

      Now there are two non ABSTRACT concrete classes :

      SaltedFood extends Food
      giving implementation to getTaste() and returning "Salted".


      And

      SweetFood extends Food
      giving implementation to getTaste() and returning "Sweet"

      Now Suppose There is another Imaginary NON ABSTRACT CONCRETE class :
      Lets suppose KhushiPreparedCurry extends SweetFood and also extends SaltedFood.

      Now KhushiPreparedCurry has getTaste() from its parent classes and also lets suppose the developer did not decide to give its own implementation of getTaste() and use the concrete implementation of the parent classes.

      Now on creating the objects of KhushiPreparedCurry and calling the method getTaste() using

      khushiPreparedCurry Object.getTaste();

      What shoud be returned Sweet or Salted.?


      Now This is the diamond problem.

      so MULTIPLE INHERITANCE IS NOT ALLOWED IN JAVA.

      But then you can say a class inherits from two classes how :

      GrandMa<---Ma<---Child now Child inherits Ma and GrandMa....

      Also There are interfaces, A class can implement multiple interfaces. Now just give a thought if two interfaces have same method signatures, and also if two interfaces have same
      method name, same parameters but different return types and a class implements both of them, how will be the implementation be affected ...leaving you on this thought, shall be back with more blogs...take care..God bless..

      Delete
  4. well i knw the answer to this... if a class implements 2 or more interfaces having same ABSTRACT method, this only forces the child class to define this method so thr is no prob with it since class has its own SINGLE definition to the ABSTRACT function :), though if the interfaces have abstract VARIABLE of same name then we have to use the variable though Class Name of Interface... :)

    and if thr is a condition like person<-Student<-Employee
    then
    List students = new ArrayList();
    List persons = students;
    then
    list.add(new Employee());
    will be valid???? as in this case now every employee is also student, every student is also person.

    so in this case what will java interpret :O


    PS: Nice Blog...Awesome Explanation. Have a Nice Day

    ReplyDelete
    Replies
    1. Good words and praises !! who doesn't like them...I like them a lot thanks:)

      Now in reply I got two points to say :

      Point number 1 :

      Few terms :

      Class, Interface, methods, properties, abstract.

      So @Khushi lets replace function with method and variable with property in your comment above.

      Abstract is an adjective used for methods and classes. Any class having a method which is abstract is an abstract class.

      Meaning of abstract by google : Existing in thought or as an idea but not having a physical or concrete existence.

      Now all interfaces are abstract and their object can not be instantiated.
      All methods in an interface are abstract.
      What about the properties.

      ALL PROPERTIES OF AN INTERFACE ARE PUBLIC STATIC FINAL.

      (and you said variable, to which I ll say BBT bazinga!! heh:P , sorry for this but I loved BBT whatever little I have watched)

      Also as we have the properties as final so we have proper object or if primitive type we have a known final value of the same, so abstract for the properties we do not use.

      Point Number 2 :
      person<---Student<---Employee

      in this case
      List students = new ArrayList();
      List persons = students;

      Both students and persons are general List and not the list of Student or Person Or Employee, You can add object of any java concrete class in it,, why just Employee.

      Raw List : List students = new ArrayList();
      List of student : List < Student > students = new ArryList < Student > ()

      The second type of list was introduced in java 5. This helps in type checks at run time.

      But in case we would have had

      List < Student > students = new ArrayList < Student > ();
      List < Person > persons = students; // this line shall give you compilation error.


      As I have said in the blog :

      Students derive from Persons but
      List < Student > do not derive from List < Person >.


      List < Person > persons = new ArrayList < Person > ();
      persons.add(new Employee());
      persons.add(new Student());

      this is ok but

      persons = new ArrayList < Employee > () is NOT OK.


      hmm..we may miss few things while first time reading something, I would recommend my blog once again and completely.

      Keep smiling ..:) God Bless..



      Delete
    2. in Comment above we have three concrete classes
      Employee -------- > Person <--------- Student

      Delete
  5. was very confused somewhere then i implemented it myself to see results Now m kind of happy... sometimes u need to discuss in deep to remember it for life time...:)

    PS. its a great blog plz write more

    ReplyDelete
  6. @Khushi : thanks for reading and appreciating my first writing. Nice to know you implemented the idea yourself and saw the result.
    Now I hope you would understand why I choose the topic as :

    Why Students are not Persons and also Employees are not Persons either !! Well lets see whats goin on....

    Its very important to implement once you read bout an idea so that you can understand what the idea is all about in reality.

    ReplyDelete