I'm creating a program where I have an Animal class, and extending that, a 'Sheep' and 'Cow' class.
In my program, I also have a 'Farm' class that will create a new animal when 'generate()' is called. When I initialize the program, each farm is given a specific animal to generate.
I can think of several ways of doing this, but none of them seem particularly nice. One way I've come up with is to have my classes set out like this:
public class Farm {
public Animal typeOfAnimalToSpawn;
public Farm(Animal a) {
typeOfAnimalToSpawn = a;
}
public void generate() {
typeOfAnimalToSpawn.spawnMe();
}
}
public abstract class Animal {
public abstract void spawnMe();
}
public class Sheep {
public void spawnMe() {
new Sheep().create();
}
public void create() {
// Spawn this sheep onto the field (By making it visible or something)
// Do whatever needs done when a sheep arrives
}
}
This seems crazily complicated and convoluted for something that I can only assume has a simple and elegant solution. In this scenario, I'm actually using the Sheep both as a type (For the farm) and an object (For when it's created). On top of this, it bugs me that calling 'new Sheep()' doesn't actually create a sheep, and it's only after something calls create() that anything happens. It also doesn't feel right to store an entire instance of an animal simply to serve as a type for the farm to spawn future animals.
It would be easy enough to simply have a farm for every type of animal:
public abstract class Farm {
public abstract generate();
}
public class SheepFarm extends Farm {
public void generate() {
new Sheep();
}
}
public class Sheep {
public Sheep() {
// Do whatever needs done when a sheep arrives
}
}
That's nice and neat on the surface but involves an extra, completely useless class for every new animal added to the program. Not exactly ideal either.
There is another way, with reflection, but I'm reluctant to use it as I'm sure there's some more sensible way of doing things.
So, my question is, what's the best way to approach a situation such as this one, and is there a simpler way of doing things than the solutions I've posted above?
I'm completely self-taught so I don't know of the proper way to do things and have had to work things out for myself with Google but it's completely failed me here; I've got no idea where to even start finding information about common programming paradigms, except, of course, for Wikipedia, which doesn't exactly come with a 'learn to write neat code' tutorial.
If my question comes off vague or even down-right nonsensical, please just ask me to clarify.
A way that I would go about it is to use generic types for Farm (however, you'd have to remove the abstract identifier on the Animal class):
public class Farm<E extends Animal> {
private E e;
public Farm() {
this.e = (E) new Animal();
}
public void generate() {
e.spawnMe();
}
}
If you're not familiar with generic types, I'd definitely research them!
Your first solution seems pretty efficient. I think it'd be the best way to go about it since you can just enter Farm sheepfarm = new Farm(new Animal...). Good luck :)
Related
Here is the example code:
public class Whatever
{
public static void main(String[] args)
{
LazyManufacturer manufacturer = new LazyManufacturer();
Porsche oldPorsche = new Porsche();
Porsche newPorsche = new Porsche();
manufacturer.updateCar(oldPorsche, newPorsche);
// for a car that I do not know the brand of, I would instantiate Car directly. So Car cannot be abstract
}
}
public class Car {
private String carCommonAttribute;
public void updateAccordingTo(Car car) {
carCommonAttribute = car.carCommonAttribute;
System.out.println("common updated");
}
}
public class Porsche extends Car {
private String porscheExclusiveAttribute;
public void updateAccordingTo(Porsche car) {
super.updateAccordingTo(car);
porscheExclusiveAttribute = car.porscheExclusiveAttribute;
System.out.println("porsche exclusive updated");
}
}
public class Garbage extends Car {
private String garbageAttribute;
// similar to Porsche
}
public class LazyManufacturer {
public <T extends Car> void updateCar(T oldCar, T newCar) {
oldCar.updateAccordingTo(newCar);
}
}
I know this is a bad example, but it is good enough for illustrating what I'm trying to achieve.
Right now the output is "common updated". I would like to see "porsche exclusive updated" as well.
I understand that at compile time, startCar(car) would see start method in Car class as the best fit as its signature perfectly matches what it is looking for. However, is there a way to get around that at runtime? At runtime, startCar would find a better fit for the start method because Porsche is a narrower type, isn't it?
What mark is saying is Change your Car -> start() method to start() instead of start(Car). This way you will be able to achieve what you intent to do.
Usually classes in same hierarchy should have exactly same method signatures so that they override the base class method ( only when behaviour needs to change, of course child classes can also have more methods). There is no need to pass the Car instance to the method, as the object always has access to itself. The passed parameter serves no purpose. For the driver, yes driver needs to have a car as input. Why does the car needs itself as input to call a method?
"At runtime, startCar would find a better fit for the start method because Porsche is a narrower type, isn't it?"
Isn't.
At runtime, JVM has no spare time to choose methods's best fit depending on actual type of given argument.
Best fit is chosen at compile time, according to declared type of arguments.
As #markspace said, you probably want to override start(), instead of overloading it. To do so, make signatures of Car.start() and Porche.start() identical. Either remove the argument (it is not used anyway), or declare the argument as Car car in both cases.
So, I probably have tought of my program the wrong way, but I can't find how to do what I'm trying to in a pretty way. I also could not find how to search this in Google properly, so sorry if this is already answered. Here is what I have:
I have an abstract class GameWorld which will be extended into several different gameWorlds, like GameAWorld, GameBWorld... I have another abstract class GameRenderer which will be responsible for the rendering of these worlds, and will also be extended into GameARenderer, GameBRenderer...
My issue is, when GameARenderer is created (in another class, not GameAWorld), it receives a general GameWorld (which is actually a GameAWorld). I need to get an object from GameAWorld, which is not in GameWorld. Therefore, what I am doing in the GameARenderer now is:
Obj chair = ((GameAWorld)world).getChair();
because if I simply do world.getA(), without the cast, GameWorld won't have the getA() method.
I believe that this may be sounding confusing, so I will try to clarify it later on, if no one understands...
Feel free to suggest changes on my architecture, if no code will solve it.
As a short but hopefully good enough example I'll try to help you out.
public interface Drawable {
void draw(Graphics g);
}
public class GameWorld {
List<GameObject> gameObjects;
List<GameObject> getGameObjects() {...}
}
public class GameAWorld extends GameWorld {...}
public class GameObject implements Drawable {
// this could be abstract too. Whatever suits your needs.
#Override
public void draw(Graphics g) { ... }
}
//inside a renderer
List<GameObject> gameObjects = gameWorld.getGameObjects();
for (GameObject go : gameObjects)
go.draw(g);
That's the way I'd do it. Be advised I slapped that together quick-like; it might not be 100% correct but you should get the point.
I am looking for a technique to have a single entry point for my interface, but where each implementation is handled differently.
Let's show an example.
I have got a couple of implementations of an Instrument-interface. Instruments ofcourse share some similarities (they make music, have something to do with notes and scales) but they are played very differently.
A Musician can play an instrument, and a gifted musician can play several instruments:
public interface Musician {
void play(Instrument instrument);
}
public class GiftedMusician implements Musician {
#Override
public void play(Instrument instrument) {
if (instrument instanceof Guitar) {
play((Guitar) instrument);
} else if (instrument instanceof Bass) {
play((Bass) instrument);
} else if (instrument instanceof Piano) {
play((Piano) instrument);
}
}
public void play(Guitar guitar) {
guitar.strumWithPick();
}
public void play(Bass bass) {
bass.pluckString();
}
public void play(Piano piano) {
piano.pressKey();
}
}
I have found a solution using instanceof but I am not sure if this is the way to go. I am looking for a design pattern or otherwise best practice to handle such a scenario.
Edit:
This example was of course very simple, let's make it a little less obvious. Because, as i said, there are many many kinds of instruments, which are played in different ways. Like a contrabass. How would I implement a Musician that plays regular- and contrabass?
public class Contrabass implements Instrument{
public void play(boolean useBow) {
if(useBow)
playWithBow();
else
pluckWithFingers();
}
}
In my opinion, you should declare the following method in Instrument:
public void play(Musician musician);
You can then implement it differently for each instrument.
For instance:
class Guitar implements Instrument {
#Override
public void play(Musician musician) {
System.out.printf("Musician %s is playing the guitar!%n", musician.getName());
strumWithPick();
}
}
... and so on.
With this example, your GiftedMusician class would make less sense, unless you decide to use composition to associate an Instrument or many to a Musician.
In the latter case, your GiftedMusician would have a constructor overload taking, say, a Collection<Instrument>, whereas your Musician would only have a constructor with a single Instrument.
For instance (with Instrument as abstract class, to add core "functionality" to play):
class Musician {
protected Collection<Instrument> instruments;
Musician(Instrument instrument) {
instruments = new HashSet<Instrument>();
if (instrument != null)
instruments.add(instrument);
}
public String getName() {
// of course
return "J. S. Bach";
}
}
class GiftedMusician extends Musician {
GiftedMusician(Instrument instrument) {
super(instrument);
}
GiftedMusician(Collection<Instrument> instruments) {
super(null);
this.instruments = new HashSet<Instrument>(instruments);
}
}
abstract class Instrument {
protected String name;
public void play(Musician musician) {
System.out.printf("Musician %s is playing %s%n", musician.getName(), name);
}
}
Edit following up question edit.
If you need to parametrize a specific playing technique into your play method, without an overload anti-pattern and returning to the instanceof long list anti-pattern, you've got all the more reason to parametrize play with a Musician.
It's the Musician who decides the technique they want to play with after all.
Once within the play body, you can then adapt the playing logic to something in the lines of musician.getCurrentTechnique().
First of all: You're right when questioning the use of instanceof. It may have some use-cases, but whenever you feel tempted to use instanceof, you should take a step back and check whether your design is really sound.
My suggestions are roughly in line with what Mena said in his answer. But from a conceptual view, I think that the direction of the dependency is a bit odd when you have to write a line like
instrument.play(musician);
instead of
musician.play(instrument);
A phrase like "an instrument can be played" IMHO suggests that the instruments are a parameter of a method, and not the object that the method is called on. They are "passive", in that sense. (One of your comments was also related to this, when you said that "the Instrument-class has an import on Musician", which doesn't seem right). But whether or not this is appropriate also depends on the real use-case. The example is very artificial and suggestive, and this may lead to suggestions for solutions that don't fit in the real world. The possible solutions for modeling this largely vary in the responsiblities, the question "Who knows what?", and how the modeled structures are intended to be used, and it's hard to give a general answer here.
However, considering that instruments can be played, it seems obvious that one could intruduce a simple method bePlayed() in the Instrument interface. This was already suggested in the other answers, leading to an implementation of the Musician interface that simply plays the instrument:
public class GiftedMusician implements Musician
{
#Override
public void play(Instrument instrument)
{
instrument.bePlayed();
}
}
One of the open issues is:
Who (and how) decides whether a musician can play the instrument?
One pragmatic solution would be to let the musician know the instrument classes that he can play:
public class GiftedMusician implements Musician
{
private final Set<Class<?>> instrumentClasses =
new LinkedHashSet<Class<?>>();
<T extends Instrument> void learn(Class<T> instrumentClass)
{
instrumentClasses.add(instrumentClass);
}
void drinkLotsOfBeer()
{
instrumentClasses.clear();
}
#Override
public void play(Instrument instrument)
{
if (instrumentClasses.contains(instrument.getClass())
{
instrument.bePlayed();
}
else
{
System.out.println("I can't play the " + instrument.getClass());
}
}
}
In your EDIT, you opened a new degree of freedom for the design space: You mentioned that the instruments can be played in different ways (like the contrabass, with bow or fingers). This suggests that it may be appropriate to introduce a PlayingTechnique class, as Mena also said in the comments.
The first shot could look like this
interface PlayingTechnique {
void applyTo(Instrument instrument);
}
But this raises two questions:
1. Which methods does the Instrument interface offer?
This question could be phrased in more natural language: What do Instruments have in common?. Intuitively, one would say: Not much. They can be played, as already shown in the bePlayed() method mentioned above. But this does not cover the different techniques, and these techniques may be highly specific for the particular class. However, you already mentioned some methods that the concrete classes could have:
Guitar#strumWithPick()
Bass#pluckString()
Piano#pressKey();
Contrabass#playWithBow();
Contrabass#pluckWithFingers()
So regarding the PlayingTechnique class, one could consider adding some generics:
interface PlayingTechnique<T extends Instrument>
{
Class<?> getInstrumentClass();
void applyTo(T instrument);
}
and have different implementations of these:
class ContrabassBowPlayingTechnique
implements PlayingTechnique<Contrabass> {
#Override
public Class<?> getInstrumentClass()
{
return Contrabass.class;
}
#Override
public void applyTo(Contrabass instrument)
{
instrument.playWithBow();
}
}
class ContrabassFingersPlayingTechnique
implements PlayingTechnique<Contrabass> {
#Override
public Class<?> getInstrumentClass()
{
return Contrabass.class;
}
#Override
public void applyTo(Contrabass instrument)
{
instrument.pluckWithFingers();
}
}
(Side note: One could consider generalizing this even further. This would roughly mean that the Instrument interface would have several sub-interfaces, like StringInstrument and KeyInstrument and WindInstrument, each offering an appropriate set of more specific methods, like
StringInstrument#playWithBow()
StringInstrument#playWithFingers()
While technically possible, this would raise questions like whether a Guitar may be played with the bow, or a Violin may be played with the fingers - but this goes beyond what can seriously be considered based on the artificial example)
The GiftedMusician class could be adjusted accordingly:
public class GiftedMusician implements Musician
{
private final Set<PlayingTechnique<?>> playingTechniques =
new LinkedHashSet<PlayingTechnique<?>>();
<T extends Instrument> void learn(PlayingTechnique<T> playingTechnique)
{
playingTechniques.add(playingTechnique);
}
void drinkLotsOfBeer()
{
playingTechniques.clear();
}
#Override
public void play(Instrument instrument)
{
for (PlayingTechnique<?> playingTechnique : playingTechniques)
{
if (playingTechnique.getInstrumentClass() == instrument.getClass())
{
// May need to cast here (but it's safe)
playingTechnique.applyTo(instrument);
return;
}
}
System.out.println("I can't play the " + instrument.getClass());
}
}
Still, there is a second open question:
2. Who decides (when and how) which PlayingTechique is applied?
In the current form, a gifted musician could learn two playing techniques for the same instrument class:
giftedMusician.learn(new ContrabassBowPlayingTechnique());
giftedMusician.learn(new ContrabassFingersPlayingTechnique());
// Which technique will he apply?
giftedMusician.play(contrabass);
But whether the decision is made by the Musician (maybe based on some "proficiency" that is associated with each technique), or from the outside, will depend on the real-world problem that you are actually trying to solve.
Add method
void play();
to the Instrument interface. Each implementation of it should be calling respective method, e.g.
public class Guitar implements Instrument {
public void play() {
strumWithPick();
}
private void strumWithPick() {
// implementation details here
}
}
Then GiftedMusician#play(Instrument) should be simplified:
public void play(Instrument instrument) {
instrument.play();
}
Add the method void play(); to your interface without any parameters. What you want to do is exhibit the behaviour of polymorphism.
So instead of using instanceof to check for each implementation, you have it in your interface as just void play();. Hence, whenever the interface is implemented, the play() method can be overriden and implemented specifically for the given class e.g. your Bass class.
It seems code examples have already been given in other answers but specifically look up the term polymorphism in the context of OOP. In particular this question has some good answers: What is polymorphism, what is it for, and how is it used?
I have the following code in which I have a parent class and its child. I am trying to determine how the code benefits from using polymorphism.
class FlyingMachines {
public void fly() {
System.out.println("No implementation");
}
}
class Jet extends FlyingMachines {
public void fly() {
System.out.println("Start, Taxi, Fly");
}
public void bombardment() {
System.out.println("Throw Missile");
}
}
public class PolymorphicTest {
public static void main(String[] args) {
FlyingMachines flm = new Jet();
flm.fly();
Jet j = new Jet();
j.bombardment();
j.fly();
}
}
What is the advantage of polymorphism when both flm.fly() and j.fly() give me the same answer?
In your example, the use of polymorphism isn't incredibly helpful since you only have one subclass of FlyingMachine. Polymorphism becomes helpful if you have multiple kinds of FlyingMachine. Then you could have a method that accepts any kind of FlyingMachine and uses its fly() method. An example might be testMaxAltitude(FlyingMachine).
Another feature that is only available with polymorphism is the ability to have a List<FlyingMachine> and use it to store Jet, Kite, or VerySmallPebbles.
One of the best cases one can make for using polymorphism is the ability to refer to interfaces rather than implementations.
For example, it's better to have a method that returns as List<FlyingMachine> rather than an ArrayList<FlyingMachine>. That way, I can change my implementation within the method to a LinkedList or a Stack without breaking any code that uses my method.
What is the advantage of polymorphism when both flm.fly() and j.fly()
give me the same answer?
The advantage is that
FlyingMachines flm = new Jet();
flm.fly();
returns
"Start, Taxi, Fly"
instead of
"No implementation"
That's polymorphism. You call fly() on an object of type FlyingMachine and it still knows that it is in fact a Jet and calls the appropriate fly() method instead of the wrong one which outputs "No implementation".
That means you can write methods that work with objects of type FlyingMachine and feed it with all kinds of subtypes like Jet or Helicopter and those methods will always do the right thing, i.e. calling the fly() method of the appropriate type instead of always doing the same thing, i.e. outputting "No implementation".
Polymorphism
Polymorphism is not useful in your example.
a) It gets useful when you have different types of objects and can write classes that can work with all those different types because they all adhere to the same API.
b) It also gets useful when you can add new FlyingMachines to your application without changing any of the existing logic.
a) and b) are two sides of the same coin.
Let me show how.
Code example
import java.util.ArrayList;
import java.util.List;
import static java.lang.System.out;
public class PolymorphismDemo {
public static void main(String[] args) {
List<FlyingMachine> machines = new ArrayList<FlyingMachine>();
machines.add(new FlyingMachine());
machines.add(new Jet());
machines.add(new Helicopter());
machines.add(new Jet());
new MakeThingsFly().letTheMachinesFly(machines);
}
}
class MakeThingsFly {
public void letTheMachinesFly(List<FlyingMachine> flyingMachines) {
for (FlyingMachine flyingMachine : flyingMachines) {
flyingMachine.fly();
}
}
}
class FlyingMachine {
public void fly() {
out.println("No implementation");
}
}
class Jet extends FlyingMachine {
#Override
public void fly() {
out.println("Start, taxi, fly");
}
public void bombardment() {
out.println("Fire missile");
}
}
class Helicopter extends FlyingMachine {
#Override
public void fly() {
out.println("Start vertically, hover, fly");
}
}
Explanation
a) The MakeThingsFly class can work with everything that is of type FlyingMachine.
b) The method letTheMachinesFly also works without any change (!) when you add a new class, for example PropellerPlane:
public void letTheMachinesFly(List<FlyingMachine> flyingMachines) {
for (FlyingMachine flyingMachine : flyingMachines) {
flyingMachine.fly();
}
}
}
That's the power of polymorphism. You can implement the open-closed-principle with it.
The reason why you use polymorphism is when you build generic frameworks that take a whole bunch of different objects with the same interface. When you create a new type of object, you don't need to change the framework to accommodate the new object type, as long as it follows the "rules" of the object.
So in your case, a more useful example is creating an object type "Airport" that accepts different types of FlyingMachines. The Airport will define a "AllowPlaneToLand" function, similar to:
//pseudocode
void AllowPlaneToLand(FlyingMachine fm)
{
fm.LandPlane();
}
As long as each type of FlyingMachine defines a proper LandPlane method, it can land itself properly. The Airport doesn't need to know anything about the FlyingMachine, except that to land the plane, it needs to invoke LandPlane on the FlyingMachine. So the Airport no longer needs to change, and can continue to accept new types of FlyingMachines, be it a handglider, a UFO, a parachute, etc.
So polymorphism is useful for the frameworks that are built around these objects, that can generically access these methods without having to change.
let's look at OO design first, inheritance represents a IS-A relationship, generally we can say something like "let our FlyingMachines fly". every specific FlyingMachines (sub class) IS-A FlyingMachines (parent class), let say Jet, fits this "let our FlyingMachines fly", while we want this flying actually be the fly function of the specific one (sub class), that's polymorphism take over.
so we do things in abstract way, oriented interfaces and base class, do not actually depend on detail implementation, polymorphism will do the right thing!
Polymorphism (both runtime and compile time) is necessary in Java for quite a few reasons.
Method overriding is a run time polymorphism and overloading is compile time polymorphism.
Few of them are(some of them are already discussed):
Collections: Suppose you have multiple type of flying machines and you want to have them all in a single collection. You can just define a list of type FlyingMachines and add them all.
List<FlyingMachine> fmList = new ArrayList<>();
fmList.add(new new JetPlaneExtendingFlyingMachine());
fmList.add(new PassengerPlanePlaneExtendingFlyingMachine());
The above can be done only by polymorphism. Otherwise you would have to maintain two separate lists.
Caste one type to another : Declare the objects like :
FlyingMachine fm1 = new JetPlaneExtendingFlyingMachine();
FlyingMachine fm2 = new PassengerPlanePlaneExtendingFlyingMachine();
fm1 = fm2; //can be done
Overloading: Not related with the code you gave, But overloading is also another type of polymorphism called compile time polymorphism.
Can have a single method which accepts type FlyingMachine handle all types i.e. subclasses of FlyingMachine. Can only be achieved with Polymorphism.
It doesn't add much if you are going to have just Jets, the advantage will come when you have different FlyingMachines, e.g. Aeroplane
Now that you've modified to include more classes, the advantage of polymorphism is that abstraction from what the specific type (and business concept) of the instance you receive, you just care that it can fly
Polymorphism can also help our code to remove the "if" conditionals which is intended to produce production level code because removing conditionals will increase the code readability and helps us to write better unit test cases, we know for "n" if cases there comes n!(n factorial) possibilities.
Let us see how
if you have class FlyingMachine and which takes a string in the constructor defining the type of FlyMachine as below
class FlyingMachine{
private type;
public FlyingMachine(String type){
this.type = type;
}
public int getFlyingSpeedInMph {
if(type.equals("Jet"))
return 600;
if(type.equals("AirPlane"))
return 300;
}
}
We can create two instances of FlyingMachine as
FlyingMachine jet = new FlyingMachine("Jet");
FlyingMachine airPlane = new FlyingMachine("AirPlane");
and get the speeds using
jet.fylingSpeedInMph();
airPlane.flyingSpeedInMph();
But if you use polymorphism you are going to remove the if conditions by extending the generic FlyMachine class and overriding the getFlyingSpeedInMph as below
class interface FlyingMachine {
public int abstract getFlyingSpeedInMph;
}
class Jet extends FlyingMachine {
#Override
public int getFlyingSpeedInMph(){
return 600;
}
}
class Airplane extends FlyingMachine {
#Override
public int getFlyingSpeedInMph(){
return 600;
}
}
Now you can get the flying speeds as below
FlyingMachine jet = new Jet();
jet.flyingSpeed();
FlyingMachine airPlane = new AirPlane();
airPlane.flyingSpeed();
Both flm.fly() and j.fly() give you the same answer because of the type of the instance is actually the same, which is Jet, so they are behave the same.
You can see the difference when you:
FlyingMachines flm = new FlyingMachines();
flm.fly();
Jet j = new Jet();
j.bombarment();
j.fly();
Polymorphism is define as same method signature with difference behaviour. As you can see, both FlyingMachines and Jet have method fly() defined, but the method is implemented differently, which consider as behave differently.
See
aa
Polymorphism
Let's add one more class in this, It help's you to understand use of polymorphism..
class FlyingMachines {
public void fly() {
System.out.println("No implementation");
}
}
class Jet extends FlyingMachines {
public void fly() {
System.out.println("Start, Jet, Fly");
}
}
class FighterPlan extends FlyingMachines {
public void fly() {
System.out.println("Start, Fighter, Fight");
}
}
public class PolymorphicTest {
public static void main(String[] args) {
FlyingMachines flm = new Jet();
flm.fly();
FlyingMachines flm2 = new FighterPlan();
flm2.fly();
}
}
Output:
Start, Jet, Fly
Start, Fighter, Fight
Polymorphism gives you benefits only if you need Polymorphism.
It's used when an entity of your conceptual project can be seen as the specialization of another entity.
The main idea is "specialization".
A great example stands in the so called Taxonomy,for example applied to living beings.
Dogs and Humans are both Mammals.
This means that, the class Mammals group all the entities that have some properties and behaviors in common.
Also, an ElectricCar and a DieselCar are a specialization of a Car.
So both have a isThereFuel() because when you drive a car you expect to know if there's fuel enough for driving it.
Another great concept is "expectation".
It's always a great idea to draw an ER (entity relationship) diagram of the domain of your software before starting it.
That's because your are forced to picture which kind of entities are gonna be created and, if you're able enough, you can save lot of code finding common behaviors between entities.
But saving code isn't the only benefit of a good project.
You might be interested in finding out the so called "software engineering" that it's a collection of techniques and concepts that allows you to write "clean code" (there's also a great book called "Clean code" that's widely suggested by pro-grammes).
The good reason for why Polymorphism is need in java is because the concept is extensively used in implementing inheritance.It plays an important role in allowing objects having different internal structures to share the same external interface.
polymorphism as stated clear by itself, a one which mapped for many.
java is a oops language so it have implementation for it by abstract, overloading and overriding
remember java would not have specification for run time polymorphism.
it have some best of example for it too.
public abstract class Human {
public abstract String getGender();
}
class Male extends Human
{
#Override
public String getGender() {
return "male";
}
}
class Female extends Human
{
#Override
public String getGender() {
return "female";
}
}
Overriding
redefine the behavior of base class.
for example i want to add a speed count int the existing functionality of move in my base Car.
Overloading
can have behavior with same name with different signature.
for example a particular president speaks clear an loud but another one speaks only loud.
Here, for this particular code, there is no need of polymorphism.
Let's understand why and when we need polymorphism.
Suppose there are different kinds of machines (like car, scooter, washing machine, electric motor, etc.) and we know that every machine starts and stops. But the logic to start and stop a machine is different for each machine. Here, every machine will have different implementations to start and stop. So, to provide different implementations we need polymorphism.
Here we can have a base class machine with start() and stop() as its methods and each machine type can extend this functionality and #Override these methods.
Take a look at this code (from here)
abstract class EntityA {
AssocA myA;
abstract void meet();
}
abstract class AssocA {
int something;
abstract void greet();
}
class AssocAConcrete extends AssocA {
void greet() {
System.out.println("hello");
}
void salute() {
System.out.println("I am saluting.")
}
}
class EntityAConcrete extends EntityA {
void meet() {
System.out.println("I am about to meet someone");
((AssocAConcrete)myA).salute();
}
}
There are two parallel inheritance trees, for a parent class and an associated class. The problem is with line 23:
((AssocAConcrete)myA).salute();
It is a pain and I have that kind of thing all over my code. Even though that line is part of the concrete implementation of Entity, I need to remind it that I want to use the concrete implementation of AssocA, AssocAConcrete.
Is there some kind of annotation to declare that relationship? Or is there a better, more colloquial Java way to express this design? Thanks!
This is in response to #Dave, because I want to put some code in...
Interesting! So the invocation would look something like this:
AssocAConcrete myAssoc = new Assoca();
EnitityA<T extends AssocA> myEntity = new EntityA<AssocAConcrete>();
myEntity.setAssoc(myAssoc);
myAssoc.salute();
Yes? That's really cool. I think I will use it!
I would think this is a lot neater using generics...
abstract class EntityA<T extends AssocA> {
// Basically, this means myA is at least an AssocA but possibly more...
T myA;
abstract void meet();
}
abstract class AssocA {
int something;
abstract void greet();
}
class AssocAConcrete extends AssocA {
void greet() {
System.out.println("hello");
}
void salute() {
System.out.println("I am saluting.");
}
}
class EntityAConcrete extends EntityA<AssocAConcrete> {
void meet() {
System.out.println("I am about to meet someone");
myA.salute();
}
}
Aside from avoiding the casting, this also makes it much easier to add different functionality in your AssocA implementations. There should always be a way to do things without using dummy implementations (ie methods that just throw "NotImplementedException") or casting. Even though it isn't always easy or worth the refactoring time to do so. In other words, no one is going to blame you for casting (well...maybe some people will but you can't please everyone).
EDIT (Notes on instantiation):
From #pitosalas' comments below...
//Won't work...can't call 'new' on abstract class AssocA
AssocAConcrete myAssoc = new Assoca();
//Instead, do this...
AssocAConcrete myAssoc = new AssocAConcrete();
And then....
// Again, won't work. T is only declaring the type inside your class/method.
// When using it to declare a variable, you have to say EXACTLY what you're making,
// or at least something as exact as the methods you're trying to invoke
EnitityA<T extends AssocA> myEntity = new EntityA<AssocAConcrete>();
//Instead do this...
EnitityA<AssocAConcrete> myEntity = new EntityAConcrete();
// Or this...
EntityAConcrete myEntity = new EntityAConcrete();
And then this should be good...
// Assuming this is defined as `public void setAssoc(T newAssoc) {this.myA = newAssoc;}`
myEntity.setAssoc(myAssoc);
myAssoc.salute();
Looks suspicious to me. There is nothing terrible about casting, but in this case, you could resolve the issue by bringing the salute method into AssocA. Subclasses of AssocA can provide their implementations; that's part of the benefit of inheritance.
What you are doing now is saying all EntityA instances have an AssocA instance, but then in your meet method you basically force the AssocA instance to be an AssocAConcrete instance. That's the part that is suspicious; why does AssocA exist if you really need an AssocAConcrete.
Another option (based on your comments) is to invoke salute in the greet method. That way, the specific subclass has specified behavior greet, defined in the superclass, and does what it wants. In this case, salute could become private or protected. Another implementation can easily do something different, like runLikeHell.
The problem of parallel class hierarchies is very real and really sucks. The logical coupling that AssocAConcrete always go with EntityAConcrete can not be expressed with the type system.
You can not specialize the type of myA in EntityAConcrete to be AssocAConcrete, without hiding it from a superclass. I think the closest work that addressed that was "Family polymorphism", but that's not mainstream.
If you have a large part of code where you are using the reference "myA" you could declare another reference like that:
public AssocAConcrete myAConcrete = (AssocAConcrete)myA;
now you can use the new reference myAConcrete and access the functions of the AssocAConcrete Class.
If you need to do this a lot like hvgotcodes mentioned you should probbably consider moving the method up to the AssocA Class.