I recently was in an interview and during that interview I realized my programming concepts aren't as concrete as I thought.
I was asked, describe a time in your previous job where you used polymorphism?
After some thinking I said that we had a record class which every new record extended. So if we have a AddRecord or a RemoveRecord or any other type of record, they would extend Record. The record interface looked something like this:
public abstract Record{
public writeLine(String line);
public getColumn(int column);
public setHeader(String header);
...
}
public AddRecord extends Record{
public writeLine(String line){
// do something
}
// etc...
}
public MakeRecord{
Record r;
public setRecord(Object s){
if(s instanceof Record){
r = s;
}
}
public void printNewRecord(){
while(thingsToWrite){
r.writeLine(something);
}
}
}
I just shorthanded it so don't nit pick it please.
I told them this was using polymorphism because regardless of the record type, it could be wrote without knowing what type of record it was. This was valuable because we are writing files that needed to be padded correctly, either zero filled or padded with spaces etc...
If this isn't polymorphism, please tell me how I can change my example into something that uses polymorphism.
Long answer short: yes
Polymorphism is, according to webster:a (1) : existence of a species in several forms independent of the variations of sex (2) : existence of a gene in several allelic forms (3) : existence of a molecule (as an enzyme) in several forms in a single species b : the property of crystallizing in two or more forms with distinct structure
we are focused with definition a. this describes, in java terms, as using 1 "top" class to reference two "bottom" classes. That is shown in the above example, to the best of my knowledge.
A very basic example of polymorphism:
import java.util.ArrayList;
public class TestClass{
public static void main(String args[]) {
ArrayList animals = new ArrayList();
animals.add(new Bear());
animals.add(new Fish());
animals.add(new Animal());
for (Animal a : animals){
a.someMethod();
}
}
}
class Animal {
public void someMethod(){
System.out.println("I am an Animal");
}
}
class Bear extends Animal{
public void someMethod(){
System.out.println("I am a Bear");
}
}
class Fish extends Animal{
public void someMethod(){
System.out.println("I am a Fish");
}
}
The output of this is:
I am a Bear
I am a Fish
I am an Animal
So we can see here that the loop calling the methods on each type of object calls them all on Animal, and yet the actual method called on each object is that objects own implementation of that method.
Clearly for this to work every object in the collection MUST have an implementation of this method, although it can obviously use the superclass’ version if that is appropriate for that object.
This means that the objects in a collection (as an example of how it may be used) can be decided at runtime, and don’t have to be individually type cast back to their true form, but can simply be called by a parent class type or interface type. This allows for far more flexibility in the code, and makes it easier to maintain. It also allows for code which is more generic and loosely coupled.
So there it is in a nutshell. There are tons of examples online to have a look at. It’s a brilliant concept, and one which is well worth investing some time into understanding.
The example is not good for explaining polymorphism.
Addrecord is not good extension of Record class. Addrecord should be method and not a class.
So basically you should have Record class having Addrecord method and this method can be overriden by special records like - ColumnnameRecord.
In the case where you have specialRecord class derived from Record class and Record Class have methods which are overriden by derived classes then you have good examples of polymorphism.
Current example is technically correct but not conceptual correct.
Another example for Polymorphism:
abstract class PolyGeometricEntity
{
public int center_x__mm; // commen superset
public int center_y__mm; // commen superset
public void move(int d_x__mm, int d_y_mm) // commen superset
{
center_x__mm += d_x__mm;
center_y__mm += d_y_mm:
}
public abstract int area(); // commen superset on abstract level, but specialized at implementation level
public abstract void draw(); // commen superset on abstract level, but specialized at implementation level
}
class CircleEntity : PolyGeometricEntity
{
public override int area()
{
// circle specific
return 1;
}
public override void draw()
{
// draw a circle
}
}
class TriangleEntity : PolyGeometricEntity
{
public override int area()
{
// triangle specific
return 1;
}
public override void draw()
{
// draw a triangle
}
}
class PolyCanvas
{
List<PolyGeometricEntity> entities = new List<PolyGeometricEntity>();
void CreateEntity(string toCreateClass)
{
// assume that code is called by the ui
// you do not know what the user decides at runtime
// Polymorphism 'starting' now:
PolyGeometricEntity toCreate = null;
if (toCreateClass == "c") { toCreate = new CircleEntity(); }
else if (toCreateClass == "t") { toCreate = new TriangleEntity(); }
entities.Add(toCreate);
}
void ReDraw()
{
foreach (PolyGeometricEntity toDraw in entities)
{
toDraw.draw(); // polymorphism in action!
}
}
}
Related
I have the following classes
class Person {
private String name;
void getName(){...}}
class Student extends Person{
String class;
void getClass(){...}
}
class Teacher extends Person{
String experience;
void getExperience(){...}
}
This is just a simplified version of my actual schema. Initially I don't know the type of person that needs to be created, so the function that handles the creation of these objects takes the general Person object as a parameter.
void calculate(Person p){...}
Now I want to access the methods of the child classes using this parent class object. I also need to access parent class methods from time to time so I CANNOT MAKE IT ABSTRACT.
I guess I simplified too much in the above example, so here goes , this is the actual structure.
class Question {
// private attributes
:
private QuestionOption option;
// getters and setters for private attributes
:
public QuestionOption getOption(){...}
}
class QuestionOption{
....
}
class ChoiceQuestionOption extends QuestionOption{
private boolean allowMultiple;
public boolean getMultiple(){...}
}
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption().getMultiple())
{...}
}
}
The if statement says "cannot find getMultiple for QuestionOption." OuestionOption has many more child classes that have different types of methods that are not common among the children (getMultiple is not common among the children)
NOTE: Though this is possible, it is not at all recommended as it kind of destroys the reason for inheritance. The best way would be to restructure your application design so that there are NO parent to child dependencies. A parent should not ever need to know its children or their capabilities.
However.. you should be able to do it like:
void calculate(Person p) {
((Student)p).method();
}
a safe way would be:
void calculate(Person p) {
if(p instanceof Student) ((Student)p).method();
}
A parent class should not have knowledge of child classes. You can implement a method calculate() and override it in every subclass:
class Person {
String name;
void getName(){...}
void calculate();
}
and then
class Student extends Person{
String class;
void getClass(){...}
#Override
void calculate() {
// do something with a Student
}
}
and
class Teacher extends Person{
String experience;
void getExperience(){...}
#Override
void calculate() {
// do something with a Teacher
}
}
By the way. Your statement about abstract classes is confusing. You can call methods defined in an abstract class, but of course only of instances of subclasses.
In your example you can make Person abstract and the use getName() on instanced of Student and Teacher.
Many of the answers here are suggesting implementing variant types using "Classical Object-Oriented Decomposition". That is, anything which might be needed on one of the variants has to be declared at the base of the hierarchy. I submit that this is a type-safe, but often very bad, approach. You either end up exposing all internal properties of all the different variants (most of which are "invalid" for each particular variant) or you end up cluttering the API of the hierarchy with tons of procedural methods (which means you have to recompile every time a new procedure is dreamed up).
I hesitate to do this, but here is a shameless plug for a blog post I wrote that outlines about 8 ways to do variant types in Java. They all suck, because Java sucks at variant types. So far the only JVM language that gets it right is Scala.
http://jazzjuice.blogspot.com/2010/10/6-things-i-hate-about-java-or-scala-is.html
The Scala creators actually wrote a paper about three of the eight ways. If I can track it down, I'll update this answer with a link.
UPDATE: found it here.
Why don't you just write an empty method in Person and override it in the children classes? And call it, when it needs to be:
void caluculate(Person p){
p.dotheCalculate();
}
This would mean you have to have the same method in both children classes, but i don't see why this would be a problem at all.
I had the same situation and I found a way around with a bit of engineering as follows - -
You have to have your method in parent class without any parameter and use - -
Class<? extends Person> cl = this.getClass(); // inside parent class
Now, with 'cl' you can access all child class fields with their name and initialized values by using - -
cl.getDeclaredFields(); cl.getField("myfield"); // and many more
In this situation your 'this' pointer will reference your child class object if you are calling parent method through your child class object.
Another thing you might need to use is Object obj = cl.newInstance();
Let me know if still you got stucked somewhere.
class Car extends Vehicle {
protected int numberOfSeats = 1;
public int getNumberOfSeats() {
return this.numberOfSeats;
}
public void printNumberOfSeats() {
// return this.numberOfSeats;
System.out.println(numberOfSeats);
}
}
//Parent class
class Vehicle {
protected String licensePlate = null;
public void setLicensePlate(String license) {
this.licensePlate = license;
System.out.println(licensePlate);
}
public static void main(String []args) {
Vehicle c = new Vehicle();
c.setLicensePlate("LASKF12341");
//Used downcasting to call the child method from the parent class.
//Downcasting = It’s the casting from a superclass to a subclass.
Vehicle d = new Car();
((Car) d).printNumberOfSeats();
}
}
One possible solution can be
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption() instanceof ChoiceQuestionOption)
{
ChoiceQuestionOption choiceQuestion = (ChoiceQuestionOption)q.getOption();
boolean result = choiceQuestion.getMultiple();
//do something with result......
}
}
}
I design my game application and face some troubles in OOP design.
I want to know some patterns which can help me, because java have not any multiple extends option. I will describe my problem below, and also explain why multiple interface doesn't help me at all. Lets go.
What we want is "class is set of features". By feature I mean construction like:
field a;
field b;
field c;
method m1(){
// use, and change fields a,b,c;
}
method m2(){
// use, and change fields a,b,c;
}
//etc
So, basically the feature is a set of methods and corresponding fields. So, it's very close to the java interface.
When I talk that class implemets "feature1" I mean that this class contains ALL "feature needed" fields, and have realisation of all feature related methods.
When class implements two features the tricky part begins. There is a change, that two different features contains similar fields (names of this fields are equal). Let the case of different types for such fields will be out of scope. What I want - is "feature naming tolerance" - so that if methodA() from feature A change the field "common_field", the methodB from feature B, that also use "common_field" as field will see this changes.
So, I want to create a set of features (basically interfaces) and their implementations. After this I want to create classes which will extends multiple features, without any copy-paste and other crap.
But I can't write this code in Java:
public static interface Feature1 {
public void method1();
}
public static interface Feature2 {
public void method2();
}
public static class Feature1Impl implements Feature1 {
int feature1Field;
int commonField;
#Override
public void method1() {
feature1Field += commonField;
commonField++;
}
}
public static class Feature2Impl implements Feature2 {
int feature2Field;
int commonField;
#Override
public void method2() {
commonField++;
}
}
public static class MyFeaturedClass extends Feature1Impl, Feature2Impl implements Feature1, Features2 {
}
So, as you can see the problem are really complex.
Below I'll describe why some standart approaches doesn't work here.
1) Use something like this:
public static class MyFeaturesClass implements Feature1,Feature2{
Feature1 feature1;
Feature2 feature2;
#Override
public void method2() {
feature2.method2();
}
#Override
public void method1() {
feature1.method1();
}
}
Ok, this is really nice approach - but it does not provide "feature field name tolerance" - so the call of method2 will not change the field "commonField" in object corresponding the feature1.
2) Use another design. For what sake you need such approach?
Ok. In my game there is a "unit" concept. A unit is MOVABLE and ALIVE object.
Movable objects has position, and move() method. Alive objects has hp and takeDamage() and die() methods.
There is only MOVABLE objects in my game, but this objects isn't alive.
Also, there is ALIVE objects in my game, but this objects isn't movable (buildings for example).
And when I realize the movable and alive as classes, that implements interfaces, I really don't know from what I should extends my Unit class. In both cases I will use copy-paste for this.
The example above is really simple, actually I need a lot of different features for different game mechanics. And I will have a lot of different objects with different properties.
What I actually tried is:
Map<Field,Object> fields;
So any object in my game has such Map, and to any object can be applied any method. The realization of method is just take needed fields from this map, do its job and change some of them. The problem of this approach is performance. First of all - I don't want to use Double and Interger classes for double and int fields, and second - I want to have a direct accsess to the fields of my objects (not through the map object).
Any suggestions?
PS. What I want as a result:
class A implements Feature1, Feature2, Feature3, Feature4, Feature5 {
// all features has corresponding FeatureNImpl implementations;
// features 1-2-3 has "shared" fields, feature 3-4 has, features 5-1 has.
// really fast implementation with "shared field tolerance" needed.
}
One possibility is to add another layer of interfaces. XXXProviderInterface could be defined for all possible common fields, that define a getter and setter for them.
A feature implementation class would require the needed providers in the constructor. All access to common fields are done through these references.
A concrete game object class implementation would implement the needed provider interfaces and feature interfaces. Through aggregation, it would add the feature implementations (with passing this as provider), and delegate the feature calls to them.
E.g.
public interface Feature1 {
void methodF1();
}
public interface Feature2 {
void methodF2();
}
public interface FieldAProvider {
int getA();
void setA(int a);
}
public class Feature1Impl implements Feature1 {
private FieldAProvider _a;
Feature1Impl(FieldAProvider a) {
_a = a;
}
void methodF1() {
_a.setA(_a.getA() * 2);
}
}
// Similar for Feature2Impl
public class GameObject implements Feature1, Feature2, FieldAProvider
{
int _fieldA;
Feature1 _f1;
Feature2 _f2;
GameObject() {
_f1 = new Feature1Impl(this);
_f2 = new Feature2Impl(this);
}
int getA() {
return _fieldA;
}
void setA(int a) {
_fieldA = a;
}
void methodF1() {
_f1.methodF1();
}
void methodF2() {
_f2.methodF2();
}
}
However, I don't think this is an optimal solution
Suppose we have the following toy interfaces:
interface Speakable
{
public abstract void Speak();
}
interface Flyer
{
public abstract void Fly();
}
and we have a class that implements both interfaces:
class Duck implements Speakable, Flyer
{
public void Speak()
{
System.out.println("quack quack don't eat me I taste bad.");
}
public void Fly()
{
System.out.println("I am flying");
}
}
At this point I see different ways to invoke methods on Duck and I can't decide which one is best practice.
Consider this scenario:
public class Lab
{
private static void DangerousSpeakAndFly(Object x)
{
Speakable temp = (Speakable) x;
temp.Speak();
Flyer temp2= (Flyer) x;
temp2.Fly();
}
public static void main(String[] args)
{
Duck daffy= new Duck();
DangerousSpeakAndFly(daffy);
}
}
This program will behave as expected, because the object passed in to the function happens to be castable to Flyer and Speakable, but I cringe when I see code like this because it does not allow compile time type checking and due to tight coupling it can throw unexpected exceptions for example when a differently typed object (not castable to either or one of the interfaces) is passed in as parameter, or if implementation of Duck changes down the line so it no longer implements Flyer.
I see Java code written like this all the time, sometimes in textbooks (for example pg. 300 of "Head First Design Patterns" by O'Reilly) so there must be a merit in it that I am missing.
If I were to write similar Code I would try to avoid downcasting to a type or interface that is not guaranteed. for example in this scenario I would do something like this:
interface SpeakingFlyer extends Flyer, Speakable
{
}
class BuzzLightyear implements SpeakingFlyer
{
public void Speak()
{
System.out.println("My name is Buzz");
}
public void Fly()
{
System.out.println("To infinity and beyond!");
}
}
Which would allow me to do:
private static void SafeSpeakAndFly(SpeakingFlyer x)
{
x.Speak();
x.Fly();
}
public static void main(String[] args)
{
BuzzLightyear bly= new BuzzLightyear();
SafeSpeakAndFly(bly);
}
Is this an unnecessary overkill? what are the pitfalls for doing this?
I feel like this design decouples the SafeSpeakAndFly() function from its parameters and keeps nasty bugs at bay due to compile time type checking.
Why is the first method used so extensively in practice and the latter isn't?
I see Java code written like this all the time, sometimes in textbooks (for example pg. 300 of "Head First Design Patterns" by O'Reilly) so there must be a merit in it that I am missing.
This book was initially published back in 2004 and I don't think Java was supporting Generics at that time. So unsafe casting was something that was very commonly used then. Probably, if I didn't have the support of parametric polymorphism in Java, I would first check if the parameter is an instance of the type I'd like to cast it to and then do the actual cast:
private static void dangerousSpeakAndFly(Object x) {
if (x instanceof Speakable) {
Speakable temp = (Speakable) x;
temp.Speak();
}
if (x instanceof Flyer) {
Flyer temp2= (Flyer) x;
temp2.Fly();
}
}
Having Generics, however, lets us do this:
private static <T extends Speakable & Flyer> void reallySafeSpeakAndFly(T x) {
x.Speak();
x.Fly();
}
Here, the compiler can make sure we're not passing something that doesn't implement Speakable and Flyer and can detect such sassy attempts at compile-time.
Why is the first method used so extensively in practice and the latter isn't?
It might be that you've seen a lot of legacy code, I suppose. :)
You can enforce the argument to be at the same time Speakable and Flyer making a method generic with type intersection:
private <T extends Speakable & Flyer> static void DangerousSpeakAndFly(T x) {
// use any of `Speakable` or `Flyer` methods of `x`
}
thus you don't need casting nor creating additional interface.
class I {
String s="yes its me:I";
void Mine(){
System.out.println(s);
}
}
class N extends I {
String l="yes its me:N";
void Mine(){
System.out.println(l);
}
}
class T extends N{
String m="yes its me:T";
void Mine(){
System.out.println(m);
}
}
class Test{
public static void main(String[] args) {
I i=new I();
N n=new N();
T t=new T();
I r; // r is a variable of class type I
r=i; // fine here
r.Mine(); //no doubt here
r=n; // heres the problem
r.Mine(); // these are working only
r=t; //with overriding methods existing & no other method exists in all classes
r.Mine();
}
}
Also tell me please: if we declare a variable of class type, what does it do (I mean is it going to recognise by the number of methods and instance variables of the class or only methods or only instance variables).
class Vehicle {
Engine myEngine = new Engine();
void start() {
myEngine.start();
}
void stop() {
myEngine.stop();
}
}
class VehicleWithSteering extends Vehicle {
Steering mySteering = new Steering();
void start() {
mySteering.reset();
myEngine.start();
}
void steerLeft() {
mySteering.left();
}
void steerRight() {
mySteering.right();
}
}
As you can see, VehicleWithSteering does have methods which the basic Vehicle did not have. It also overrides the void start() method as starting this more complex vehicle involves a different routine.
class NoviceDriver {
Vehicle myVehicle;
public NoviceDriver(Vehicle vehicle) {
myVehicle = vehicle;
}
void doSomething() {
myVehicle.start();
myVehicle.stop();
}
}
class AdvancedDriver {
VehicleWithSteering myVehicle;
public NoviceDriver(VehicleWithSteering vehicle) {
myVehicle = vehicle;
}
void doSomethingElse() {
myVehicle.start();
myVehicle.steerLeft();
myVehicle.stop();
}
}
The AdvancedDriver needs additional functionalities which the basic Vehicle can not satisfy, so it will always need an instance of VehicleWithSteering.
class Test{
public static void main(String[] args) {
// Create one basic vehicle
Vehicle a = new Vehicle();
// And one more advanced
VehicleWithSteering b = new VehicleWithSteering();
// A novice driver is satisfied with having a basic vehicle
NoviceDriver x = new NoviceDriver(a);
// The advanced driver however needs more functionality
AdvancedDriver y = new AdvancedDriver(b);
// A novice driver can use the advanced vehicle as well
// But he will not bother about the advanced functionality
NoviceDriver z = new NoviceDriver(b);
}
}
The NoviceDriver only knows how to access methods of Vehicle. But since these methods are also present in VehicleWithSteering, he can use that one as well. NoviceDriver doesn't even know what steering means so he won't touch any controls he doesn't know about.
You can't fit an AdvancedDriver with a Vehicle as this one doesn't incorporate the required steering methods.
If there was an even more advanced refinement of the VehicleWithSteering, both the NoviceDriver and the AdvancedDriver could still use it for executing their limited tasks as it still provides the required basic functionalities.
The NoviceDriver has access to all public methods and properties the original Vehicle had. It does not know about new methods or properties added later on. In this case, it could see the inherited Engine myEngine property on the VehicleWithSteering, but it can not see the new Steering mySteering property.
As for your last question: That depends on the language.
In Java, each class has an internal list of other inherited classes and interfaces it implements. Whenever you are casting a refinement to a more primitive type, Java will check whether the primitive type is in the list or not. This behavior is also used in other strictly typed languages such as C++, C# and many others.
The alternative concept would be Duck-Typing.
When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.
When a language uses Duck-Typing, it will look up the requested method in the object by name and signature. This may happen either at compile time or at runtime, in latter case an exception is thrown in most languages supporting Duck-Typing.
Some languages such as PHP and various other scripting languages feature both strict type checks and Duck-Typing. That means you can both optionally enforce a strict type check on the list of inherited classes and implemented interfaces, as well as defaulting to Duck-Typing when that check was omitted.
Consider:
class MP3Player // any MP3 player
class IPod extends MP3Player // an iPod MP3 player
class IPodClassic extends IPod // an iPod Classic in particular
Then:
MP3Player m = new IPod();
m.playMp3();
is allowed because an iPod is an MP3 player and can do anything an MP3 player can do.
IPod i = new MP3Player(); // Not allowed
i.showAppStore(); // MP3Player might not have app store
is not allowed because not all MP3 player's are iPods.
IPodClassic ic = new IPod(); // Not allowed
ic.getHardDisk(); // Not all iPod objects have a hard disk.
is not allowed because not all iPod's are iPod classics.
I am getting a little confused between using objects as attributes within other objects (and invoking methods on the attribute) using composition, versus having a good overall coupling.
Is there a tradeoff here?
Perhaps its easier giving examples of bad coupling to explain the difference (if there is a difference)?
EDIT example:
public class MyClass(){
MyOtherClass moc;
public MyClass(MyOtherClass temp){
moc = temp;
}
public void method(){
moc.call()
}
}
is this bad coupling because of the dependency on the composition relationship?? If not, what would be bad coupling in this example.
Two fundamental ways to relate classes are inheritance and composition.When you establish an inheritance relationship between two classes, you get to take advantage of dynamic binding and polymorphism.
Given that the inheritance relationship makes it hard to change the interface of a superclass, it is worth looking at an alternative approach provided by composition. It turns out that when your goal is code reuse, composition provides an approach that yields easier-to-change code.
class Fruit {
// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {
System.out.println("Peeling is appealing.");
return 1;
}
}
class Apple extends Fruit {
}
class Example1 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
If at some point in the future, however, you wish to change the return value of peel() to type Peel, you will break the code for Example1 code even though Example1 uses Apple directly and never explicitly mentions Fruit.
Composition provides an alternative way for Apple to reuse Fruit's implementation of peel(). Instead of extending Fruit, Apple can hold a reference to a Fruit instance and define its own peel() method that simply invokes peel() on the Fruit. Here's the code:
class Fruit {
// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {
System.out.println("Peeling is appealing.");
return 1;
}
}
class Apple {
private Fruit fruit = new Fruit();
public int peel() {
return fruit.peel();
}
}
class Example2 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
Inheritance gives you higher coupling than Composition.
Instead of bad/good coupling, it seems like the most accepted terms are tight/loose coupling, with loosely coupled objects being preferred. In your example, tighter coupling could be something like this (with added functionality for illustration):
public class MyClass()
{
MyOtherClass moc;
public MyClass(MyOtherClass temp)
{
moc = temp;
}
public void method()
{
for (int i = 0; i < moc.items.Count; i++)
{
moc.items[i].Price += 5;
}
}
}
Here, MyClass depends on specific implementation details of MyOtherClass (the implementation of the list of items, the cost, etc...). A more loosely coupled way to handle this type of scenario would be to move that logic into a function on MyOtherClass. That way all of the implementation details of MyOtherClass are hidden from MyClass, and can change independently of MyClass.