I'm having a problem in Java. I have a method that can be extended. The problem is, that this method calls other methods of the class, and these can be extended as well.
Consider the following class:
public class Foo {
protected int xLast;
public updateMe(int x, int y) {
updateX(x);
}
protected updateX(int x) {
this.xLast = x;
}
}
This class is extended by the following class:
public class Bar extends Foo {
protected int xAverage = 0;
protected int xCount = 0;
protected int y;
public updateMe(int x, int y) {
super.updateMe(x, y);
updateX(x);
updateY(x);
}
protected updateX(int x) {
this.xAverage = (this.xAverage * this.xCount) + x;
this.xCount++;
this.xAverage /= xCount;
}
protected updateY(int y) {
this.y = y;
}
}
And also by this class:
public class Abc extends Foo {
}
When I do the following:
Foo myBar = new Bar();
myBar.updateMe(1, 2);
The Foo.updateX method is not called, but the Bar.updateX method is called twice. There are several solutions, some don't work well or are quite ugly:
In Bar.updateX call super.updateX. This will cause both updateX methods to be called twice.
Remove the updateX call in Foo.updateMe, forcing the extending classes to call super.updateX. This will cause the class Abc to have useless code that it doesn't need, or else the Abc class will not call updateX at all.
Rename the methods so that they do not override each other. This will work, but is not safe (in the future this might be forgotten and lead to problems) and is not enforced by the language.
I am aware that this is somewhat of a code-smell, but I see no better way to do this.
Basically I am looking to do something like this: in Foo.updateMe I would like to call Foo.updateX specifically, and not just the polymorph-ed updateX.
I believe that something like the new method keyword in C# can solve my problems, but Java doesn't appear to have one, or any other way to accomplish this.
Edit:
In the end I chose just to rename the offending method. I have a just one method that causes this problem, and the solution suggested here, although sound from a design point-of-view will make this particular code harder to understand and maintain.
I'd do this:
Remove updateX() call from Bar.updateMe() since updateX() is already called by super.updateMe().
Call super.updateX() from Bar.updateX() since the method with the same name is supposed to extend functionality, not replace it.
In this case Abc won't have to be changed and both updateX() methods will be called once.
Java , all instance method calls are called by means of dynamic binding. As far as I know, there is no elegant way to accomplish what you want.
If you dont care about principles and elegance, you can check class of an instance at Foo.
public updateMe(int x, int y) {
if (getClass()==Foo.class)
updateX(x);
}
Eli, it seems that you would like to cancel OOP. First it is bad. If you need this change your design. Java is pure object oriented language and therefore all calls are polymorphic. If you extended your class and overrode some if its functionality it means that you need this and therefore this functionality should be called. This is the reason that updateX() from Bar is called.
BTW to do what you want you should create static method and call it this way: Foo.updateX().
You could also make updateX() private. Then a subclass that implements updateX() is "hiding", not "overriding" the method.
Drawbacks:
Since updateX() is conceptually part of a Template pattern, it really "feels" like it should be protected.
You can't put
abstract private void updateX();
in the superclass to force users to implement it.
All implementations of updateMe() must always remember to call updateX()
Possible Drawback and possible advantage:
All of the private updateMe() methods will get called. (for me this this was desired, YMMV)
I recently faced this problem and chose this solution, though I considered renaming the methods and something very close to the (getClass()== MyFoo.class) trick. IMO all are reasonable.
Related
I was looking at other questions on SO, but I didn't really see an explanation for my question. I read that calling a constructor from another constructor (using the this keyword) was valid, but I didn't understand why it was valid.
Previously, I thought that only one constructor could act per object. Constructor chaining seems to break this logic, in that while calling one constructor, it runs another in conjunction to the original, targeted constructor. Why does constructor chaining work?
We chain (call) one constructor from other within the same class so that we can avoid code duplication. Without chaining every constructor, we end up repeating business details and that leads to code duplication and hard to maintain the code as well.
Imagine you are creating a Bus.
public class Bus {
int noOfSeats;
String busColor;
public Bus() {
this(40); //// Using another constructor and proceeding with default values..
}
public Bus(int seats) {
this(seats,"red"); // Using another constructor and proceeding..
}
public Bus(int seats, String color) {
this.noOfSeats = seats;
this.busColor = color;
}
}
And the person using this class can use only constructor at a time, where as you are using chaining internally. Imagine that you have a method which initializes things with default values and calling it in the constructor. There's nothing wrong in that, right?
Just to clarify, the person who is creating the object is calling only one constructor. The invoked constructor calls others which is internal to that class.
Delegated constructors reduce the amount of duplicate code, since you can exploit the functionality set up in one constructor by calling it from another one.
Until this feature was designed into languages, we had to rely on "initialisation"-type functions that were called from constructors. That was a pain for two reasons (i) you could never guarantee that the functions were only called from constructors, and (ii) calling class methods from constructors is always a design "smell".
It allows to clarify the logic and reduce the code.
Is nesting constructors (or factory methods) good, or should each do all init work
It's reasonable to chain constructors together, the version with fewer parameters calls the version with more parameters. It makes very clear what's happening, and all the real "logic" (beyond the default values) is in a single place. For example:
public class Foo {
private static final int DEFAULT_X =10;
private static final int DEFAULT_Y =20;
private int x;
private int y;
private int precomputedValue;
public Foo(int x, int y) {
this.x = x;
this.y = y;
precomputedValue = x * y;
}
public Foo(int x) {
this(x, DEFAULT_Y);
}
public Foo() {
this(DEFAULT_X, DEFAULT_Y)
}
}
Not a Java dev here, but in Python this is also allowed and pretty much normal.
Whenever you inherit a class, you might want to call the parent class's constructor prior adding your own stuff-and-recipes.
This allows you to benefit the parent class's construction features. Whenever you do not know exactly what the parent class does you most of the time always call it first in order to avoid the parent's class features and methods being broken.
The fact that the confusion originates from every instance should call one ctor is absolutely right. The constructor chained another is used to avoid code duplication and simplicity because copying same code is really overhead. Sometimes maybe we need two constructors, first one just takes two parameters the other one takes three parameters. But, three parameters-ctor uses same variables of two parameters-ctor. Do you prefer copy-paste same assignmets or merely call the other ctor by this?
As a supplement to the other answers, I would like to share another use for calling a constructor from a constructor that I use often.
Another strategy of constructor chaining that I find useful is providing default implementations / auto-injection for Interfaces.
public class Foo {
private readonly ILogger _logger;
//Default implementation for most cases
public Foo() : this(new DefaultLoggerImplementation()) {}
//DI Constructor that allows for different implementations of ILogger
//(Or Mocks in testing)
public Foo(ILogger logger)
{
_logger = logger;
}
public void Log(string message)
{
_logger.log(message);
}
}
This way if you have a default implementation for an interface it is auto injected via new Foo()
If you have a case with different ILogger behavior it is easily injectable, this also promotes the ability to Mock the interface in your unit testing framework.
I mean, obviously, there is no benefit on the polymorphic side,
and declaring (all of) these methods as final would prevent me from overriding them.
And I know IT IS possible to do, and the compiler doesn't prevent you from doing it.
I would love to get a usage example...
There are some marginal cases where such design, if perhaps not optimal, could at least be motivated. For example, you may have a system of classes, all subclasses of a common parent, where each subclass implements a further interface. There may be a set of interfaces with different formalities, but the same essential function.
In that particalar case it wouldn't hurt to make all the methods final and let each subclass add its own methods which make use of them.
I'd say it's part of the "core" component. You build something and you design the architecture, and you know that that method should never be changed.
The abstract class could have package access to some internal methods.
In this case we have
an incomplete class
functionality has to stay the same and grants secured access to the internal model
That is all we need to declare a type abstract and all its methods final. Consider as an example a Panel class that holds the graphics, but not always offers a method to actually make it draw itself - subclasses can have different drawing behaviourse. On the other hand it can offer a final protected DrawBuffer makeCircle() or something like that which, for some reason, has to access the internal model to make a DrawBuffer.
The JIT can take benefit when some methods declared in such way, when it cannot be overridden. (static, private, final, in final class)
let's imagine you have classes:
abstract class A {
public void doSomething() {
// default and only realization;
}
}
class B extends A { ... }
Then you write something like:
A a = MyAFactory.createA();
a.doSomething();
When method cannot be known to be final, and there is possible (even if not loaded just now) overridings, compiler makes second line to invoke virtual method. I.e. first it will determine which exactly class A, then looking in virtual method table, and only then call to particular methods.
But! If method is known as it cannot be overridden, then compiler can place to this point direct call to A.doSomething().
So, it is recommended to make method final unless you need them to be overridden.
Let's imagine class like this:
abstract class C {
public abstract int getMin();
public abstract int getMax();
public final int getSize() {
return getMax() - getMin();
}
}
in this example, it is obvious behavior of getSize() and hardly to imagine when it needs to be changed. So, declaring it final, not only gives a benefit by discarding virtual invocation mechanism, but also protects from unintended override of method with particular and predefined behavior.
public class ExtAA extends AA {
static int iTime;
public static void main(String argv[]) {
ExtAA d = new ExtAA();
d.func(iTime);
}
public static void func(int iTime) {
System.out.println(iTime);
}
public ExtAA() { }
}
class AA {
public AA() { System.out.println("AA"); }
}
prints:
AA
0
I would have expected public ExtAA() { } to override the constructor for AA and thus not print AA, just 0. Could someone explain in what way I am wrong, and if I'd want to override the constructor how could I ?
P.S. It is completely possible that my question is stupid, but I don't get what public ExtAA() { } should or could do. This was at a test, I messed up and I'd like to know what's actually happening (yes, I did go into debug and go over it step by step, I just don't know why new ExtAA uses AA instead of it's own defined constructor)
Constructor of super class in Java is always called. You can't stop that. You can just control which constructor is called if there are more of them.
Please consider reading some basic tutorial of Java, this is elementary thing of Java OOP.
Implicitly your constructor looks like this:
public ExtAA() {
super(); // Constructor of super class call, always first line of code in child constructor
}
An object has the fields of its own class plus all fields of its parent class, grandparent class, all the way up to the root class Object. It's necessary to initialize all fields, therefore all constructors must be called! The Java compiler automatically inserts the necessary constructor calls in the process of constructor chaining, or you can do it explicitly.
Imagine if you could skip a constructor from a base. It could leave the parent part of an object in an extremely unstable state.
Think about a situation where a base class does some kind of meaningful initialization in the constructor. If that doesn't get done, then suddenly the base class part of your object is in crazy-town. This is almost certainly why Java decided to work like this.
As a super trivial example, imagine if you had a SortedArrayList class that extends ArrayList. If SortedArrayList somehow didn't call any of the ArrayList constructors, do you think the internals of the object would make sense? Somewhere there would be a nulled out data structure meaning things would crash and burn. In certain situations it might make sense to override a constructor, but apparently the Java people felt that the risk of accidentally doing it wasn't worth the ability (and it very rarely makes sense in a well designed class graph -- if the child class doesn't depend on the base class in some way, then why is it a child class to begin with?).
I would like to design class A implements interface C and reduce the visibility of a method (declared in C)to make it secure from outer world, make one of the methods in interface implemented in class A as private (reducing visibility in class A). I have to do this for security reason, how can I do this, is there a workaround. We do know that by default, the interface has public members. But there is no option for me, can someone help me. Thanks in advance.
--
So , there is no way, to have a class implement method from interface and make it private. And all classes that implement any interface's method will always have public methods?
No, you can't reduce the visibility of a method in an interface. What would you expect to happen if someone wrote:
C foo = new A();
foo.methodDeclaredPrivateInA();
? As far as the compiler is concerned, everything with a reference to an implementation of C has the right to call any methods within it - that's what Liskov's Substitution Principle is all about.
If you don't want to implement the whole of a public interface, don't implement it - or throw exceptions if you absolutely must.
It's also worth noting that the accessibility provided in source code is rarely a good security measure. If your class is running in a VM which in turn gets to determine its own permissions, anyone can make members visible via reflection.
You can't reduce the visibility of the method of an interface in Java. Is it acceptable for you to implement the method by throwing a java.lang.UnsupportedOperationException?
You cannot reduce visiblity because you could write something along the lines of
C newC = new A();
This approach worked for me. Any new function added to PrivateInterface would break still break PublicSampleClass
private interface PrivateInterface {
void fooBar();
}
public class PublicSampleClass {
private final listenerInterface = new PrivateInterface {
public void fooBar() {
PublicSampleClass.this.fooBar();
}
};
protected void fooBar() {
// Non public implementation
}
}
Referring here
A is a precompiled Java class (I also have the source file)
B is a Java class that I am authoring
B extends A.
How can logic be implemented such that A can call the methods that B has.
The following are the conditions:
I don't want to touch A(only as a
last option though that is if no
other solution exists).
I don't want to use reflection.
As stated, if needed I could modify A.
What could be the possible solution either way?
Class A should define the methods it's going to call (probably as abstract ones, and A should be an abstract class, per Paul Haahr's excellent guide); B can (in fact to be concrete MUST, if the method are abstract) override those methods. Now, calls to those methods from other methods in A, when happening in an instance of class B, go to B's overrides.
The overall design pattern is known as Template Method; the methods to be overridden are often called "hook methods", and the method performing the calls, the "organizing method".
Yes it seems that if you override the super/base-classes's functions, calls to those functions in the base class will go to the child/derived class. Seems like a bad design in my opinion, but there you go.
class Base
{
public void foo()
{
doStuff();
}
public void doStuff()
{
print("base");
}
}
class Derived extends Base
{
#Override
public void doStuff()
{
print("derived");
}
}
new Derived().foo(); // Prints "derived".
Obviously all of Derived's methods have to be already defined in Base, but to do it otherwise (without introspection) would be logically impossible.
I would be rather hesitant to do this. Please correct me if I am wrong and then I will delete, but it sounds like you want to maintain an A object along with a B object. If they indeed are not the same object, the "tying together" (that's a scientific term) you'll have to do would be pretty ugly.