Run Time Polymorphism - java

class A {
public void display(){
System.out.println("From Class A");
}
}
class B extends A {
public void display() {
System.out.println("From Class B");
}
}
public class Test {
public static void main(Strings[] args){
A a = new A();
A b = new B()
a.display();
b.display();
}
}
Output:
From Class A
From Class B
Now, I am getting the output as expected.
But I want to know why I am using A b = new B(), when same thing I can achieve by using
B b = new B().
What is the advantage of using former techniques, where and when it is beneficial for me?

Lets take an example here. We all know birds can fly, but there are some exceptions. We know from their behavior, so lets model this.
Generally, birds can fly, so:
class Bird {
void fly() {
System.out.println("I can fly");
}
}
class Eagle extends Bird {
void fly() {
System.out.println("I can fly very high");
}
}
We all know that ducks can't fly, but we don't say it for all birds. We say at runtime whether a specific bird can fly or not, depending on the bird.
class Duck extends Bird {
void fly() {
System.out.println("I can walk or swim only");
}
}
class FlightDemo {
public static void main(String[] args) {
Bird bird = new Bird();
bird.fly(); // output: I can fly
Bird eagle = new Eagle();
eagle.fly(); // output: I can fly very high
Bird duck = new Duck();
duck.fly(); // output: I can walk or swim only
}
}
You saw that at runtime it's decided that ducks can't fly. You can override its fly behavior and it would walk or swim. We saw that Duck IS a Bird, and it can't fly, so we have overridden its behavior, and still Duck IS a Bird, and it can walk or swim.

In your example, it doesn't matter which way you chose. Your example doesn't show the power of polymorphism.
Let's see a trivial example of Polymorphism:
interface Shape{
void draw();
}
class Rectangle implements Shape{
public void draw(){
System.out.println("Drawing Rectangle.");
}
}
class Triangle implements Shape{
public void draw(){
System.out.println("Drawing Triangle.");
}
}
class Circle implements Shape{
public void draw(){
System.out.println("Drawing Circle.");
}
}
Rectangle, Triangle, and Circle are just implementing their own definition of draw function.
Now, suppose you've to implement a drawAllShapes method in your Main class, which takes a bunch of shapes and print them all. But without polymorphism this can be hectic, as there can be different types of shapes. Now, here comes polymorphism to save us.
class RandomShapeFactory{
public static Shape createRandomShape(){
Shape randomShape;
Random random = new Random();
int randomNo = random.nextInt() % 3 + 1;
if (randomNo == 1){
randomShape = new Rectangle();
}
else if (randomNo == 2){
randomShape = new Triangle();
}
else{
randomShape = new Circle();
}
return randomShape;
}
}
class Main{
public static void main(String[] args){
Shape[] shapes = new Shape[10];
for (int i = 0; i < shapes.length; i++){
shapes[i] = RandomShapeFactory.createRandomShape();
}
drawAllShapes(shapes);
}
public static void drawAllShapes(Shape[] shapes){
for (int i = 0; i < shapes.length; i++){
shapes[i].draw();
}
}
}
This implementation of drawAllShapes doesn't have to know whether the Shape at index i is a Circle or Triangle or what, whichever Shape it is, it just calls their implementation of the draw method.
main method has all random shapes, and when passed to the drawAllShapes method, their relative implementations are invoked.
This kind of implementation also follows the Open/Closed Principle, that if you want, in future, to add some more Shapes to the hierarchy, drawAllShapes method doesn't have to know about the new shapes either, just add new classes and implement the Shape interface, and drawAllShapes will work with those shapes too.
See the above example in action here.

Related

How to create an instance that belongs to an interface and implement it

I'm currently learning Java so please bear with my ignorance. Here is my current code
Shape.java
public interface Shape {
public abstract void draw();
}
Rectangle.java
public abstract class Rectangle implements Shape {
private final double width, length;
public Rectangle() {
this(1,1);
}
public Rectangle(double width, double length) {
this.width = width;
this.length = length;
}
public void draw() {
System.out.println("A rectangle of sides " + length + " by " + width + " will be drawn");
}
}
TestPolymorph.java
public class TestPolymorph implements Shape {
public static void main(String[] args) {
Shape[] drawObject = { new Rectangle(40, 60) };
drawObject[0].draw();
}
#Override
public void draw() {
// TODO Auto-generated method stub
}
}
Is there anything wrong with my current code since it's not working. My question is how can I create a drawObject instance that belongs to Shape class and during runtime drawObjectwill be created with two arguments, length and width (giving 40 and 60 for example), draw method of Rectangle will then be invoked.
You're close, there really isn't any need to have your TestPolymorph implement Shape. That is your driver, not a model implementing an interface so you could take that off.
Lastly, remove the abstract from the Rectangle class. That is not an abstract class because you actually want an instance of that type.
Try to remove the abstract modifier from the Rectangle object. You also don't need to implement the Shape interface in TestPolymorph.java
Shape[] drawObject = { new Rectangle(40, 60) };
above is your code
Shape[] drawObject = { new Rectangle(40, 60) {} };
this is correct code
since you are creating objects of abstract class you have to go with this
approach. or you can just remove abstract modifier from Rectangle class
if you are creating a object of abstract class you are forced to implement all its abstract methods , since you dont have any abstract method inside your abstract rectangle class you just have to new Rectangle(40, 60) {}
pass empty brackets at the end bt if your class has abstract methods inside the brackets you have to implement the abstract method
Improving Interface
Every method declaration in the body of an interface is implicitly public and abstract.
Ref: http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.4
Make it simple. Rather than complicating the things.
Just go in a valid inherited manner.
Remove the abstract from Rectangle class and also there is no need for TestPolymorph to implement the Shape interface.
Rectangle implements the Shape interface and just Test Polymorphism in TestPolymorph.

Multiple type custom arraylist

I currently am trying to make a simple RPG-ish game. I want monsters to spawn randomly on the map. I have it set up so that when I want one to spawn it is added to an ArrayList called monsters. I will be having many different types of monsters by the time I am done, and each one has its own class (ex. Zombie, Ghost...) each class will have a method to draw the monster called draw. I want to know how I can do this.
Monsters is an ArrayList<Object> so it will be able to have the different classes in it, but It won't let my do Monsters.get(i).draw(); Is this actually possible, or am I being stupid.
You failed to cast the object ArrayList<Object> back to Monster
// Monster.get(i) == Object
// (Monster) Monsters.get(i) == Monster
// cast the list item i from Object to Monster
((Monster) Monsters.get(i)).draw();
A better solution:
interface Monster {
void draw();
}
// implement draw on each
class Zombie implements Monster {}
class Ghost implements Monster {}
ArrayList<Monster> monsters = new ArrayList<>();
// legal
monsters.add(new Zombie());
monsters.add(new Ghost());
// legal
monsters.get(i).draw();
You can go with class -> extends solution or this interface -> implements. Either way this is a very bare bones example of a better way to implement your Monsters.
Yes, it is possible, first you need to create an interface, like IMonster which contains a draw method. Then, have each monster type implement this interface.
Your ArrayList will look like this:
List<IMonster> monsters = new ArrayList<IMonster>();
monsters.add(new Ghost());
monsters.add(new Goblin());
So here is an example:
import java.util.ArrayList;
import java.util.List;
public class Monsters {
private static List<IMonster> monsters = new ArrayList<IMonster>();
public static void main(String[] args) {
monsters.add(new Ghost());
monsters.add(new Goblin());
monsters.add(new Devil());
for (IMonster monster : monsters) {
monster.draw();
}
}
}
interface IMonster {
public void draw();
}
abstract class AbstractMonster implements IMonster {
#Override
public void draw() {
System.out.println("Shared drawing code for all monsters");
}
}
class Ghost extends AbstractMonster {
#Override
public void draw() {
super.draw();
System.out.println("Ghost drawing code");
}
}
class Goblin extends AbstractMonster {
#Override
public void draw() {
super.draw();
System.out.println("Goblin drawing code");
}
}
class Devil extends AbstractMonster {
#Override
public void draw() {
super.draw();
System.out.println("Devil drawing code");
}
}
You have to cast your item get from the ArrayList like this -
Object item = Monsters.get(i);
Monster monster = (Monster) item;
monster.draw();
Or better you may use some Interface. You may use an interface (for example Drawable ). Your Monsterand other drawable class would implement it. Then use the ArrayList of Drawable.
interface Drawable{
public void draw();
}
public class Monster implements Drawable {
public void draw(){
//implementation of monster's draw
}
}
...
...
ArrayList<Drawable> monsters = new ArrayList<Drawable>();
...
...
monsters.get(i).draw();

Create an array of superclasses while maintaining polymorphic attributes

If I had an array of Birds that is filled during run-time, how can I access member methods specific to child classes?
class Bird
{
public Bird() {}
public void fly(int x) {
System.out.println("Flew "+x+" meters");
}
}
class DumbBird extends Bird
{
public DumbBird() {super();}
public void fly(int x) {
x-=5; //we're dumb
System.out.println("Flew "+x+" meters");
}
public void sing() {
System.out.println("La la la!");
}
}
public static void main(String[] args)
{
Bird[] cage = new Bird[10];
cage[0] = new Bird();
cage[1] = new Dumbbird();
cage[2] = new Sleepybird();
//.... more bird types
cage[1].sing(); //is inaccessable because it is of type Bird not DumbBird!
}
Is there a good way to be able to have a an array of generic types while being able to access member functions specific to a child class? I would like to not have to edit the Bird class.
In theory, yes. Items put in arrays are reifiable, so you could determine which type you're looking at and cast the particular object to it's actual type. This isn't a very clean solution, though, so I wouldn't recommend it.
You may consider having an abstract class or interface representing bird that has methods most birds would support, along with a check method canSing() or canFly(). Birds that don't support this such as flightless birds can throw an UnsupportedOperationException if you try to call a method the bird doesn't support, but there is no easy way to generically reference all of the birds and know about all of the different methods each sub-type of bird can have.
Just to remove my answer from the comments.
Switch to using lists instead of arrays and when you pull your specific bird out, you will need to cast it to the correct type of "Bird", see the below code example:
import java.util.ArrayList;
class Bird
{
public void fly(int x) {
System.out.println("Flew "+x+" meters");
}
}
class DumbBird extends Bird
{
public void fly(int x) {
x-=5; //we're dumb
System.out.println("Flew "+x+" meters");
}
public void sing() {
System.out.println("La la la!");
}
}
class Test {
public static void main(String[] args) {
ArrayList<Bird> cage = new ArrayList<Bird>();
cage.add(new Bird());
cage.add(new DumbBird());
cage.add(new Bird());
cage.add(new DumbBird());
cage.add(new SleepyBird());
((DumbBird) cage.get(1)).sing();
}
}

Run method based on input, without if-statement logic

I have one single method that takes in 2 parameters:
public void generate(int size, String animal){
// output a picture of the "animal" on java.swing of size "size"
}
So the possibility of the animals are Monkey, Giraffe, Dog, Cat, and Mouse. However, the assignment specifies that I can only have 1 method, no if-statements / cases / ternary operators, no external classes. So in the method, I have to create all 5 of these animals:
public void generate(int size, String animal){
// output picture of Monkey
// output picture of Giraffe
// output picture of Dog
// output picture of Cat
// output picture of Mouse
}
So in turn, I was thinking I have to only make part of the method run based on the inputs. Is there any way to do this? The professor's hint was to use "multiple dispatch", but if there is only 1 method, how is this possible?
public interface Animal {
public void draw(int size);
}
public class Monkey implements Animal {
public void draw(int size) {
// ...
}
}
etc.
Since you do not want to use if/else/switch-case , assuming each type of animal is a class you can try this implementation.
public class Test {
static Map<String, Animal> animalTypeMap = new HashMap<String, Animal>();
static {
animalTypeMap.put("Monkey", new Monkey());
// put other animals in the map
}
public static void main(String[] args) {
Test test = new Test();
test.generate(5, "Monkey");
}
public void generate(int size, String animal) {
// output picture of Monkey
Animal animalObj = animalTypeMap.get(animal);
animalObj.draw(size);
// output picture of Giraffe
// output picture of Dog
// output picture of Cat
// output picture of Mouse
}
}
interface Animal {
public void draw(int size);
// .....more methods
}
class Monkey implements Animal {
// ...implement methods
#Override
public void draw(int size) {
System.out.println("Monkey of size " + size + " drawn");
}
// ...more methods
}
// ....more classes implementing animal interface

Is this consider polymorphism?

I'm confused with polymorphism and I'm wondering if this is consider polymorphism?
I feel it looks kind of weird but it still compiles correctly.
public class Family {
void FamilyInfo() {
System.out.println("This is a family super class");
}
}
public class Grandparents extends Family {
void FamilyInfo() {
System.out.println("Graparents are the elders in the family and they are the sub class of family");
}
}
public class Parents extends Grandparents {
void FamilyInfo() {
System.out.println("The parents are the children of the grandparents and they are the sub sub class for family");
}
}
public class FamilyDemo {
public static void main(String ary[]) {
Grandparents Gp = new Grandparents();
Parents P1 = new Parents();
Gp.FamilyInfo();
P1.FamilyInfo();
}
}
Your method FamilyInfo is being overridden in all three classes in the hierarchy. This is one example of polymorphism.
When you call Gp.FamilyInfo();: It will call the method implemented in Grandparents class and print Graparents are the elders in the family and they are the sub class of family while P1.FamilyInfo(); will call the method in Parents class and print The parents are the children of the grandparents and they are the sub sub class for family.
Thus you can see that same method FamilyInfo() has two different behaviors, which is polymorphic behavior.
Your example is very similar to one mentioned in the tutorial here: Java Tutorial : Polymorphism. So don't get confused.
The example does not demonstrate polymorphism,rather i can just see simple object oriented inheritance.In order that the concept of polymorphism be used the code should be the following.
public class FamilyDemo
{
public static void main(String ary[])
{
Family Gp = new Grandparents();
Family P1 = new Parents();
Gp.FamilyInfo();
P1.FamilyInfo();
}
}
Even though Gp is of type Family, it behaves like type Grandparents because it is initialized with an object of that type.
Then,the following may be expected:
Graparents are the elders in the family and they are the sub class of family.
The parents are the children of the grandparents and they are the sub sub class for family.
Our trainer said that using extends is more of an example of inheritance. But if we use implements(interface), we can say that it is polymorphic because we can implement many interfaces.
e.g.
interface Horse {
void run();
}
interface Eagle {
void fly();
}
public class Pegasus implements Horse, Eagle {
// Implement methods
public void run() {
// do run
}
public void fly() {
// do fly
}
}
The dictionary definition of polymorphism refers to a principle in
biology in which an organism or species can have many different forms
or stages
The basic concept is for a given object to act like another. This is achieved through the use of interfaces and inheritance in Java.
A better example of this would be (with you code as a base)
public class FamilyDemo {
public static void main(String ary[]) {
Family gp = new Grandparents();
Family p1 = new Parents();
dump(gp);
dump(p1);
}
public static void dump(Family family) {
family.FamilyInfo();
}
}
This basically allows Gradparents and Parents to "act" as they are Family
1.What is polymorphism?
In object-oriented programming, polymorphism (from the Greek meaning "having multiple forms") is the characteristic of being able to assign a different meaning or usage to something in different contexts - specifically, to allow an entity such as a variable, a function, or an object to have more than one form.
2. Two Types of polymorphism
a) Static or Compile time Polymorphism
Which method is to be called is decided at compile-time only. Method overloading is an example of this.for example
public class calculation
{
public int add(int x, int y)
{
return x + y;
}
public int add(int x, int y, int z)
{
return x + y + z;
}
}
here you can see there are two functions with the same name but different signatures
b)Dynamic or Runtime Polymorphism.
Run time polymorphism is also known as method overriding. In this mechanism by which a call to an overridden function is resolved at a Run-Time (not at Compile-time) if a base Class contains a method that is overridden.
Class BaseClass
{
Public void show ()
{
Console.WriteLine("From base class show method");
}
}
Public Class DynamicDemo : BaseClass
{
Public void show()
{
Console.WriteLine("From Derived Class show method");
}
Public static void main(String args[])
{
DynamicDemo dpd=new DynamicDemo ();
Dpd.show();
}
}
Technically speaking, this is polymorphism. However, you have chosen a poor example and it seems like you are not quite understanding the idea behind polymorphism. A better example would be something like this.
public abstract class Shape {
public abstract void drawShape();
}
public class Rectangle extends Shape {
public void drawShape() {
// code for drawing rectangle
}
}
public class Circle extends Shape {
public void drawShape() {
// code for drawing circle
}
}
public class FilledRectangle extends Rectangle {
public void drawShape() {
super.drawShape();
// code for filling rectangle
}
}
Then a class that is responsible for the drawing doesn't need to know how to draw each individual shape. Instead, it can do this
public void drawAllShapes(Shape[] myShapes) {
for (int i = 0; i < myShapes.length; ++i) {
myShapes[i].drawShape();
}
}
The goal is to abstract away the concrete implementation and all the details that go with and instead only present a common interface. This makes it a lot easier to work with different classes, as you can see in the last method above.
A good example for polymorphism would be:
public static void print(Family[] family){
for(int i=0; i< family.length; i++){
family[i].FamilyInfo();
}
}
public static void main(String args[])
{
Family[] family = new Family[2];
Grandparents Gp = new Grandparents();
Parents P1 = new Parents();
family[0] = Gp;
family[1] = P1;
//and then send the array to another method which
//doesn't "know" which entry in the array is a parent and which is grandparent
//and there you can loop the array calling family[i].FamilyInfo();
//THIS is the whole idea of polymorphism in a nutshell
print(family);
}
Yes, in your example program you are using inherit and polimorphism, infact both are closed related.
You are using inherit because you extend once Family from Grandparents class, and once Parents class extending Grandparents and you are also using polimorphism because you are writing in your subclasses a method void FamilyInfo which is written in the super class.
You should use #Override in this way:
public class Parents extends Grandparents {
#Override
void FamilyInfo() {
System.out.println("The parents are the children of the grandparents and they are the sub sub class for family");
}
}

Categories