Jump to content
  • Advertisement
Sign in to follow this  
ManaStone

Avoiding polymorphism in Java

This topic is 2540 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is there a way I can explicitly avoid polymorphism is Java? For example, in the following code:

public class Main
{
public static void main(String[] args)
{
new Main().Run();
}
public void Run()
{
ClassB b = new ClassB();
b.doThing();
}
public class ClassA
{
public void doThing()
{
print();
}
public void print()
{
System.out.println("A");
}
}
class ClassB extends ClassA
{
public void print()
{
System.out.println("B");
}
}
}


Is there anyway I can write doThing() so that it always calls the ClassA version of print so that when the program runs it prints “A” instead of “B”

Share this post


Link to post
Share on other sites
Advertisement
Why would you want to?

In general, if you run into this sort of thing where it's hard to do something in the language, it's a hint not to do that.

Share this post


Link to post
Share on other sites

Why would you want to?

In general, if you run into this sort of thing where it's hard to do something in the language, it's a hint not to do that.


Polymorphism caused a problem in one of my programs when a constructor called the wrong function. I've settled the problem, but I would like to be able to avoid in the future.

Share this post


Link to post
Share on other sites

Is there a way I can explicitly avoid polymorphism is Java? For example, in the following code:

public class Main
{
public static void main(String[] args)
{
new Main().Run();
}
public void Run()
{
ClassB b = new ClassB();
b.doThing();
}
public class ClassA
{
public void doThing()
{
print();
}
public void print()
{
System.out.println("A");
}
}
class ClassB extends ClassA
{
public void print()
{
System.out.println("B");
}
}
}


Is there anyway I can write doThing() so that it always calls the ClassA version of print so that when the program runs it prints “A” instead of “B”


no, you cannot. You will brake LSP (Liskov substitution principle)


[quote name='Telastyn' timestamp='1325713684' post='4899714']
Why would you want to?

In general, if you run into this sort of thing where it's hard to do something in the language, it's a hint not to do that.

do you know how using

Polymorphism caused a problem in one of my programs when a constructor called the wrong function. I've settled the problem, but I would like to be able to avoid in the future.
[/quote]

post an example of that constructor issue... do you remember how constructors works with subclassing and the role of the "super" keyword?

Share this post


Link to post
Share on other sites

[quote name='Telastyn' timestamp='1325713684' post='4899714']
Why would you want to?

In general, if you run into this sort of thing where it's hard to do something in the language, it's a hint not to do that.


Polymorphism caused a problem in one of my programs when a constructor called the wrong function. I've settled the problem, but I would like to be able to avoid in the future.
[/quote]

How'd you settle the problem?

By not calling functions of anything but parameters in the constructor (or eliminating the need in your design)? Good, avoid it in the future by following that general rule.

Share this post


Link to post
Share on other sites

post an example of that constructor issue... do you remember how constructors works with subclassing and the role of the "super" keyword?



The problem was that the overwriting function was using objects in the the derived class before they had a chance to initialize. I used a null check to solve it. It was a simple fix, but I just thought it might be useful to know how to explicitly choose which version to use just in case a more complex situation arises.

Share this post


Link to post
Share on other sites

The problem was that the overwriting function was using objects in the the derived class before they had a chance to initialize. I used a null check to solve it.

While that may work well enough for your current needs, calling polymorphic functions from base class constructors is generally a crappy idea, precisely for the reason you have stated: the derived class will not yet be initialised when the method is called.

If you can't avoid this practice entirely, make sure you document that the functions must check for class initialisation - otherwise you or some other programmer is likely to run afoul of the issue a year or two down the line...

Share this post


Link to post
Share on other sites
Sounds like a poor abstraction was the root of your constructor problem. Inheritance is an appropriate tool is LSP is upheld.

Share this post


Link to post
Share on other sites
Inheritance is the deepest coupling between classes. When modifying the child or parent classes, you must be aware of the implications across this inheritance hierarchy.

For some problems, an alternative solution can be to break the polymorphic aspects of the class into a separate interface. This way, there is no requirement for the implementor to extend your class - they can just plug in another class that implements the polymorphic behaviour.

As mentioned, using the final keyword can help by allowing the base class designer to specify which functions are designed to be overridden.


The problem was that the overwriting function was using objects in the the derived class before they had a chance to initialize. I used a null check to solve it. It was a simple fix, but I just thought it might be useful to know how to explicitly choose which version to use just in case a more complex situation arises.
[/quote]
Adding a null check sounds brittle, I wouldn't recommend it.

This is another solution:

public class Parent {

public Parent() {
doFoo();
}

private void doFoo() {
// parent logic...
}

public void foo() {
doFoo();
}

}

public class Child extends Parent {

@Override
public void foo() {
// child logic...
}

}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!