Week 5 & 6 – Polymorphism, Abstract Classes, JAVA Generics & Interfaces

Polymorphism

Suppose we have a class called – food. The class food contains one eat void function which is supposed to print “I love food”. Now suppose we create two subclasses of food called pizza and meat. We may overwrite the void method in pizza and meat class as print “I love pizza” and “I love meat” respectively. And now if we are to write a main method in the following manner, what should our output be?

Class Polymorph

public static void main (String[] args){

pizza lunch = new pizza();

food lunch = new pizza();

Consider the line: pizza lunch = new pizza();

the first word “pizza” is the data type of the variable we are about to create, “lunch” is the reference variable while “new pizza()” indicates that by referring to lunch we are referring to pizza object.

On the other hand the line: food lunch = new pizza(); indicates that its a variable of food object and all the food methods are associated with lunch.

So what does all of this explanation really mean in easy terms? What does the this line ” food lunch = new pizza(); ” do and why is it important? Here’s what it does:

Your variable lunch will be using the constructor of its subclass first, in our case of class food and then coming to its own constructor but the methods that it will be using would still come from the class pizza.

So now try and figure out what the following code would print:

public class A {
   int num = 13;

   public A(){
     System.out.println("one")
   }
   public void report(){
     System.out.println("two")
   }
}

public class B extends A {

  int num =2;

  public B(){
    System.out.println("here");
  }
 
  public void report(){
   System.out.println("five");
  }
}

public class Day1 {

 public static void main(String[] args) {

 A variable = new B();
 System.out.println("NEXT");
 variable.report();

 
 }

}

Result 

one
here
NEXT
five

Now what if in my main code I want to print the int num variable’s value, what would it give me? Value of int num in class A or value of int num in class B ?

So Note that even though it uses its own methods, it doesn’t only use A class’s constructor but it also uses A class’s instance variable values.

public static void main(String args[]){
A variable = new B();
System.put.println("NEXT")
variable.report();
System.out.println(variable.num);

Result

one
here
NEXT
five
12

Example

food lunch[] = new food[2];
lunch[0] = new pizza();
lunch[1] = new meat();
for (int x=0, x<2, x++){
   lunch[x].eat();
}

Result

I love pizza
I love meat

Note: Polymorphic Array is mainly to store elements of different subclasses and easily use them with their overwritten/individual methods.

public class fatty{

  public void digest(food x){
      x.eat()

  }
}

We could use its subclasses and pass them in as parameters instead, their eat method would automatically get called with them. See below:

public static void main(String args[]){
   fatty dinner = new fatty();
   food fo = new food();
   food me = new meat();
   dinner.digest(fo);
   dinner.digest(me);

Result

I love food
I love meat

Abstract Class & Methods

Abstract classes are created to be extended as they cannot be instantiated. What that means is – we cannot write the following line in the main method:

Grade mygrade = new Grade();

However if grade has a subclass called NumericGrade, then we could written as:

NumericGrade Numgrade = new NumericGrade(); or

Grade Numgrade = new NumericGrade(); <– POLYMORPHISM

When you hear “abstract class” you would think that it would  contain abstract methods only. But when you study such classes you understand that this is NOT how is works. An abstract class may include abstract methods but this is not a must. It may have no abstract methods at all and still be an abstract class.

Now this raises a few questions

1) What is an abstract method?

2) If an abstract class contains no abstract methods then why do we even form abstract classes ?

3) Do abstract methods need to be created in abstract classes only?

1 — An Abstract Method is a method that is not written yet but only mentioned. That means that we have its name written out and that our subclasses MUST have these methods. However, they have the freedom in writing it however they like. An abstract method works more like a prescription, you must have this method called “bla” but you can write it anyway you like.

For example: public int gpa();

You need to have a method in subclasses called gpa and it must return an integer. How you do it is up to you. But notice that if a subclass is an abstract class as well then it does not need to implement the abstract methods of its parent class.

2–  It is true that an abstract class may not have abstract methods. But then why do we need an abstract class ? Could we not rename it to a normal class?  This is why you may want to create and keep an abstract class: Abstract classes usually keep generic methods (What a generic method is you will find out soon below). Imagine this. If a function does not do the same thing in all the subclasses but the type of parameter is takes in and deals with is different for each subclass, then what do we do, we write a method in each subclass and it doesn’t exactly look write to us since the method’s so similar to the other method in the other subclass. Programmers want to code less! So what we can do is create a generic method (generalized method) in the superclass and make all subclasses implement it. This is a big reason that abstract classes are used for.

3–  Yes it does. An abstract method cannot be created anywhere else but an abstract class. A normal class cannot have any abstract methods! For a class to have abstract methods it needs to be declared as an abstract class.

Follow through an example:

Inside an abstract class you may use abstract method, something that is common to every Grade (for example: gpa).

If we have a method called public abstract void write(); in our abstract Grade Class then we must override/implement the abstract write method in the subclass. The implementation of the object is also written in the subclass. Let’s see how that works:

package grade;
public class NumericGrade extends Grade {
  
  public void write(){
     System.out.println("Your Numeric Grade is: ")
  }
}

package grade;
public class LetterGrade extends Grade{
  
  public void write(){
     System.out.println("Your Letter Grade is: ")
  }
}

package grade

public static void main(String[] args){

  NumericGrade numGrade = new NumericGrade();
  numGrade.write();
  Letter Grade letGrade = new LetterGrade();
  letgrade.write();

Result

Your Numeric Grade is:
Your Letter Grade is:

It goes to its own class to access the method being called. If I write something like:

Grade mygrade = new NumericGrade();
mygrade.write()
Grade hergrade = new LetterGrade();
hergrade.write()

Result

Your Numeric Grade is:
Your Letter Grade is:

This becomes polymorphism now. What happens here is that the method is looked for in the Grade class, even though the player class method will be used but if there is no method of the same name is the Grade class then it doesn’t work.

Now follow through this, another polymorphism/abstract class example:

Grade[] grade = new Grade[2];
grade[0] = numGrade;
lunch[1] = letGrade;
for (Grade obj: grade){
   obj.write();
}

Result

Your Numeric Grade is:
Your Letter Grade is:

 Java Generics

Consider the following code:

public class Day2 {

 public static void main(String[] args) {

  Integer[] i_ray = {1,2,3,4};
  Character[] c_ray = {'s','u','k','a','i','n','a'};
  printME(i_ray);
  printME(c_ray);
 }

}

public static void printME(Integer[] i){
 for(Integer x: i){
    System.out.println();
}
}
public static void printME(Character[] i){
  for(Character c: i){
    System.out.println();
}
}

It is obvious that this can be shortened since one method is being repeated and we programmers do not like repetition. However can we avoid repetition if objects of different classes are being used? Any thoughts?

The Answer is yes we could. This repetition of methods could be avoided if we use Java Generics and implement the generic method can may be applied on any type of data. We want to get rid of an overloaded method

Generic Method:

public static void main(String[] args){
    Integer[] i_ray = {1,2,3,4};
    Integer[] c_ray = {'s','u','k','a','i','n','a'};
    printMe(i_ray);
    printMe(c_ray);
}

public static <T> void printME(T[] x){
 
 for (T item: x){
   System.out.printf("%s " + var)
 System.out.println();
 }
}

Instead of looping through element of different type of items it is easier to create on generic method for all these types and loop through that. We may use T since T is able to store objects of different types. Notice that the generic and the non-generic methods have identical output printed, therefore it’s more efficient and less time consuming to apply generic methods where needed.

Result

1 2 3 4
s u k a i n a

 Interface in Java

  • An Interface does not have any implemented methods
  • A method prescribed in an interface must be implemented by the classes that implement this interface
  • Any variable declared in an Interface is public, final and static!
  • All methods in an interface are public and abstract

“public abstract typeItReturns FunctionName();”

  • Since interface has only abstract methods, these shouldn’t must be implemented but also overriden in the classes that implements it
  • a Class can implement as many interfaces as it likes unlike extending a superclass
  • All the fields in an interface are by default public, final and static

Why are Interfaces needed?

There is no multiple inheritance concept in java, like there is in python. That means that one class can only have ONE PARENT, it is not allowed to be a child of  more than one parent inheriting one thing from one parent and another thing from another. This is one main reason Interface is used.

So how does Interface work as multiple class inheritance?

Suppose I am a class “Sukaina”

I am basically a student, citizen, daughter and sister and I am supposed to  be a subclass of all these classes technically. How do I do it in Java?

Create 4 different Interfaces: Citizen (with an abstract method votes), Student (with its abstract methods like studies),  Daughter (with her abstract methods such as ResponsibleFor) and sister (with its abstract methods as TakesCare). So now class Sukaina can implement all these interfaces and respectively their methods also. So instead of being a child of multiple classes, she could implement multiple classes classes and their respective methods.

 

 

 

 

Leave a comment