Java abstract class not working as expected [duplicate] - java

Excuse any minor syntax errors or whatnot, I'm experiencing this with a Jitsi module and not being super familiar with Java want to confirm what is going on and why and how it should be fixed.
public abstract class A
{
public A()
{
this.load();
}
protected void load()
{
}
}
public class B extends A
{
private String testString = null;
public B()
{
super();
}
#Override
protected void load()
{
testString = "test";
}
}
The application is doing this when creating an instance of the class B using a load class by name method:
Calls overridden load() in class B
Initializes variables (calls "private string testString = null" according to debugger), nulling them out.
Is this expected Java behavior? What could cause this? It's a Java 1.6 application running on the 1.7 JDK.

Is this expected Java behavior?
Yes.
What could cause this?
Your invocation of non-final overridden method in non-final super class constructor.
Let's see what happens step-by-step:
You create an instance of B.
B() calls super class constructor - A(), to initialize the super class members.
A() now invokes a non-final method which is overridden in B class, as a part of initialization.
Since the instance in the context is of B class, the method load() invoked is of B class.
load() initializes the B class instance field - testString.
The super class constructor finishes job, and returns (Assuming chaining of constructor till Object class have been finished)
The B() constructor starts executing further, initializing it's own member.
Now, as a part of initilization process, B overwrites the previous written value in testString, and re-initializes it to null.
Moral: Never call a non-final public method of a non-final class in it's constructor.

This is a common problem-pattern with initialization-on-construction, and can frequently be found in infrastructure code & home-made DAOs.
The assignment to 'null' is unneeded & can be removed.
If that's not enough as a quick patch, then: Move all the post-construction init to a separate method, and wrap it all in a "static method" pseudo-constructor.
And if you're doing DAO stuff, it's really good to distinguish between "load" and "create", since these are completely different instantiations. Define separate "static constructor" methods & perhaps separate internal inits, for these.
abstract public class A {
protected void initAfterCreate() {}
}
public class B {
#Override
protected void initAfterCreate() {
this.testString = "test";
}
// static constructors;
// --
static public B createB() {
B result = new B();
result.initAfterCreate();
}
}
Demonstrating load/create separation for a DAO:
public class Order {
protected int id;
protected boolean dbExists;
static public load (int id) {
Order result = new Order( id, true);
// populate from SQL query..
return result;
}
static public create() {
// allocate a key.
int id = KeyAlloc.allocate( "Order");
Order result = new Order( id, false);
}
// internal constructor; not for external access.
//
protected Order (int id, boolean dbExists) {
this.id = id;
this.dbExists = dbExists;
}
}

Related

Why does calling a method from base class calls the child method?

I'm a student, learning Java. I know, protected means access from children or the same package. Here we inherit and override a protected method. And after such an action, whenever the base class wants to call its own method it calls the new overridden one from the subclass. I've been debugging this for a while and marked the execution order with comments. But I can't understand why doesn't it call the base method when I clearly call that from inside the base class constructor?
public class Solution {
public static void main(String[] args) {
new B(); // first
}
public static class A {
public A() {
initialize(); // third
}
protected void initialize() {
System.out.println("class A"); // we never go here
}
}
public static class B extends A {
public B() {
super(); // second
initialize(); // fifth
}
protected void initialize() {
System.out.println("class B"); // fourth, sixth
}
}
}
That's a task from one website, so basically the solution is to change access modifier of the initialize method from protected to private. But I still fail to understand why is the problem happening.
What you're trying to do is defeat the purpose of polymorphism. You can, but you have to make the call specifically. Add a Boolean to your method and call the super.initialize(Boolean). Again, this defeats polymorphism and the extending class HAS to know about the super class. NOT VERY ELEGANT.
public class Solution {
public static void main(String[] args) {
new B(); // first
}
public static class A {
public static boolean USE_SUPER = true;
public A() {
initialize(USE_SUPER);
}
protected void initialize(boolean unusedHere) {
System.out.println("class A");
}
}
public static class B extends A {
public static boolean USE_EXTENDED = false;
public B() {
super();
initialize(USE_EXTENDED);
}
protected void initialize(boolean useSuper) {
if (useSuper)
super.initialize(useSuper);
else
System.out.println("class B");
}
}
}
As Dakoda answered, the root cause is polymorphism. That means we may create child objects, but refer to them as their parent type and when we call the methods of the parent layer we actually refer to the child's methods.
In my case, I create a child object (marked //first) B, which has its own body of the initialize method. One nuance of the inheritance is that it doesn't include constructors, so I can call the parent's constructor (marked //second). Inside the parent's constructor, I call the initialize method - that is the polymorphism because I call the method of the child from its parent abstraction layer.
Here is the answer to the question - this happens, because we only allocated memory for a B instance, that means, we took A as our base and started to extend it (while we can overwrite anything inside). The only two things we did are:
We created a constructor (it wasn't included in the base, as mentioned above)
We overwrote the initialize method code. The code for this method that is inside the base is now lost for this object.
This concept of polymorphism is designed that way and there is no way for us to access the base method unless we specifically create an object that is either A itself or a child that doesn't overwrite this method.

Java: Best practice - Callback vs member class

In Java, what code to call a method in a singleton would be better practice, and why?
Please note that the following code is psudocode, not necessarily compilable code.
I ask this, as Method 2 (calling a method directly) is easier to implement in code, but not as often seen from my experience.
I'm developing for Android, but I suppose this question could apply to any Java program.
Something happens in class B. A method in Class A must be called.
Method 1: Interface registered in ClassA is called from ClassB
public class ClassA
{
// Member class B object
ClassB mClassBObject = new ClassB();
// Singleton has a private constructor
private ClassA(){}
public void onCreate() // Or main, or whatever method...
{
// Set callback for ClassB
mClassBObject.setOnSomethingHappened
(
new OnSomethingHappened()
{
public void callback()
{
// Do something in Class A called in Class B
}
}
);
}
}
public class ClassB
{
// Registered member callback
OnSomethingHappened mCallback;
// Interface for callback
public interface OnSomethingHappened()
{
public void callback();
}
// Method to set callback for this object
public void setOnSomethingHappened(OnSomethingHappened callback)
{
mCallback = callback;
}
// A method that invokes the callback in Class A
private void someMethod()
{
if (mCallback != null)
{
mCallback.callback();
}
}
}
Method 2: Calling a method directly from ClassA in ClassB
// We could also call a static method, but in this example, we are assuming a Singleton.
public class ClassA
{
// Reference to self
private static mSelf;
// Singleton has a private constructor
private ClassA(){}
public void onCreate() // Or main, etc
{
mSelf = this; // Store a reference to this Singleton class
}
public void someMethod()
{
// Do something in ClassA
}
public static getSelf()
{
return mSelf;
}
}
public class ClassB
{
// Code...
private void someMethodInClassB()
{
// Get ClassA to call
ClassA classAObject = ClassA.getSelf();
if (classAObject != null)
{
// Call method in ClassA
classAObject.someMethod();
}
}
}
It really depends on which way you want the dependency chain to go. I'm going to generalize the pattern I think you're trying to describe.
I'm the second example, B depends on A. As you mentioned, this is simpler, since what we're trying to setup is exactly that relationship.
In the first example, A depends on B. Technically this could be written so that A and B both depend on C (the callback mechanism). This kind of setup is popular as it reduces coupling between the components (A and B), allowing more flexibility for future changes.
The way you have written it doesn't quite capture this reduction of coupling in a "best practice" sort of way though... You'll find good examples where B represents a library or third party component, and A is your code. Clearly the library can't depend directly on your code, so this style of dependency inversion is used.

overriding protected method of Superclass

In the below example why does the String b prints null and String c prints "gg".
Correct me if I am wrong, whenever a subclass (BClass) overrides a protected method (i.e initClass()) of the superclass (AClass).If you instantiate the subclass. The superclass must make use of overriden method specified by the subclass.
public class Example {
public class AClass {
private String a;
public AClass() {
initClass();
}
protected void initClass() {
a = "randomtext";
}
}
public class BClass extends AClass {
private String b = null;
private String c;
#Override
protected void initClass() {
b = "omg!";
c = "gg";
}
public void bValue() {
System.out.println(b); // prints null
System.out.println(c); // prints "gg"
}
}
public static void main(String[] args) {
Example.BClass b = new Example().new BClass();
b.bValue();
}
}
As of the JSF 12.5
In the example you can see the execution order. The first steps are the callings of the Constructor down to the Object constructor.
Afterwards this happens:
Next, all initializers for the instance variables of class [...] are executed.
Since your instance variable b is initialized to null it will be null again afterwards
This is happening because the superclass constructor is called before the fields of ClassB is initialized. Hence the initClass() method is called which sets b = "omg!" but then again when the super class constructor returns, b is initialized to the value declared in ClassB which is null.
To debug, put a break point and go step by step, you will find that b is first set to null and then changes to omg! and then comes back to null.
There have been already given several correct answers about what's happening. I just wanted to add that it is generally bad practice to call overridden methods from constructor (except of course if you know exactly what you are doing). As you can see, the subclass may not be completely initialised at the time its instance method is invoked (subclass constructor logic has not been executed yet, so effectively overridden method is invoked on an unconstructed object which is dangerous) which might lead to confusions like the one described in this question.
It is much better to write initialisation logic in the constructor and if it is too long then divide it between several private methods invoked from the constructor.
This is happening like this because, first constructor of AClass, which set value of b = omg! and c=gg. After that When BClass gets load in memory it set b=null and c remain as it is which is gg, this is happening because, because in BClass, for b you are doing declaration as well as initialization and for c you are doing only declaration, so as c is already in the memory it even won't get it's default value and as you are not doing any initialization for c, it remain with it's earlier state.
I believe that this example explains the issue:
public class Main {
private static class PrintOnCreate {
public PrintOnCreate(String message) {
System.out.println(message);
}
}
private static class BaseClass {
private PrintOnCreate member =
new PrintOnCreate("BaseClass: member initialization");
static {
System.out.println("BaseClass: static initialization");
}
public BaseClass() {
System.out.println("BaseClass: constructor");
memberCalledFromConstructor();
}
public void memberCalledFromConstructor() {
System.out.println("BaseClass: member called from constructor");
}
}
private static class DerivedClass extends BaseClass {
private PrintOnCreate member =
new PrintOnCreate("DerivedClass: member initialization");
static {
System.out.println("DerivedClass: static initialization");
}
public DerivedClass() {
System.out.println("DerivedClass: constructor");
}
#Override
public void memberCalledFromConstructor() {
System.out.println("DerivedClass: member called from constructor");
}
}
public static void main (String[] args) {
BaseClass obj = new DerivedClass();
}
}
The output from this program is:
BaseClass: static initialization
DerivedClass: static initialization
BaseClass: member initialization
BaseClass: constructor
DerivedClass: member called from constructor
DerivedClass: member initialization
DerivedClass: constructor
... which demonstrates that the derived class's members are initialized after the base class's constructor (and the invocation of the derived class's member function have completed). This also demonstrates a key danger of invoking an overridable function from a constructor, namely that the function can be invoked before the members of the class on which it depends have been initialized. For this reason, constructors should generally avoid invoking member functions (and, when they do, those functions should either be final or static, so that they either depend only on the current class which has been initialized or on none of the instance variables).

Java inheritance: Reducing visibility in a constructor vs inherited method

In the following code, the constructor of Child has reduced visibility from public to private, which is allowed. The inherited methods, such as test(), cannot have reduced visibility. Why does Java operate this way?
class Parent {
public Parent(){}
public void test()
{
System.out.print("parent test executed!");
}
}
class Child extends Parent{
private Child(){}
private void test(){
System.out.print("child test executed!");
}
}
Constructors are not inherited, so Child() doesn't override Parent().
As for the methods, if you have (if Child() were public)
Parent p = new Child();
p.test();
Had it been allowed, this would be invoking a private method. So narrowing the access while overriding is not permitted.
When extending a class you are stating that your class is an extension of the parent class ("IS-A" relationship). What this means is that your class will have all methods of your parent class. This is the same as implementing an interface in java except you gain the method definitions (and fields) from your parent and not just methods declared in the interface. In interfaces constructors are not present because they are not methods. Constructors are special as they belong entirely to the class they are declared on. They declare how to construct only themselves.
In order to construct an object you must know that objects class.
class A {
private message;
private A() {
message = "You created an A";
}
public A(String message) {
this.message = message;
}
public void printMessage() {
System.out.println(message);
}
public static A createAnA() {
return new A();
}
}
class B extends A {
public B() {
super("You created a B");
}
}
A anA = new B(); // This will work
A anotherA = new A(); // This is not allowed as the constructor is private
A yetAnotherA = A.createAnA(); // This works too
So when we constructed B we can say that it is an A. Even though the constructor A is private this is due the constructor not being a part of the interface. The only thing we are saying about B when we assign it to a field of type A is that it has the methods of declared in A. In this case printMessage and createAnA.
That is why you can make the constructor private without changing the definition of the class. Now, why are you not allowed to make the method private when overriding a parents signature. This comes to having varying definitions of the [class].method(). Let's say that you could make your method private. Let's say that you declared a printMssage in the B class. Your reasoning is that you want that method for your use only inside the method and you want your parents printMessage to be used when called externally. Now, you wrote a method like this in the B class.
public void adjustMessage(String additional) {
message = getMessage() + additional();
}
Which version of get message would be executed? Your private one or the public one of your parents? The Java dispatcher would of course choose the public one as it is the one declared in the interface. So we we look at this example we can see if you did make your method have different a lower privilege your method could never be dispatched too which would just make things confusing for the reader.
This is a very good question.

Calling method from constructor

Excuse any minor syntax errors or whatnot, I'm experiencing this with a Jitsi module and not being super familiar with Java want to confirm what is going on and why and how it should be fixed.
public abstract class A
{
public A()
{
this.load();
}
protected void load()
{
}
}
public class B extends A
{
private String testString = null;
public B()
{
super();
}
#Override
protected void load()
{
testString = "test";
}
}
The application is doing this when creating an instance of the class B using a load class by name method:
Calls overridden load() in class B
Initializes variables (calls "private string testString = null" according to debugger), nulling them out.
Is this expected Java behavior? What could cause this? It's a Java 1.6 application running on the 1.7 JDK.
Is this expected Java behavior?
Yes.
What could cause this?
Your invocation of non-final overridden method in non-final super class constructor.
Let's see what happens step-by-step:
You create an instance of B.
B() calls super class constructor - A(), to initialize the super class members.
A() now invokes a non-final method which is overridden in B class, as a part of initialization.
Since the instance in the context is of B class, the method load() invoked is of B class.
load() initializes the B class instance field - testString.
The super class constructor finishes job, and returns (Assuming chaining of constructor till Object class have been finished)
The B() constructor starts executing further, initializing it's own member.
Now, as a part of initilization process, B overwrites the previous written value in testString, and re-initializes it to null.
Moral: Never call a non-final public method of a non-final class in it's constructor.
This is a common problem-pattern with initialization-on-construction, and can frequently be found in infrastructure code & home-made DAOs.
The assignment to 'null' is unneeded & can be removed.
If that's not enough as a quick patch, then: Move all the post-construction init to a separate method, and wrap it all in a "static method" pseudo-constructor.
And if you're doing DAO stuff, it's really good to distinguish between "load" and "create", since these are completely different instantiations. Define separate "static constructor" methods & perhaps separate internal inits, for these.
abstract public class A {
protected void initAfterCreate() {}
}
public class B {
#Override
protected void initAfterCreate() {
this.testString = "test";
}
// static constructors;
// --
static public B createB() {
B result = new B();
result.initAfterCreate();
}
}
Demonstrating load/create separation for a DAO:
public class Order {
protected int id;
protected boolean dbExists;
static public load (int id) {
Order result = new Order( id, true);
// populate from SQL query..
return result;
}
static public create() {
// allocate a key.
int id = KeyAlloc.allocate( "Order");
Order result = new Order( id, false);
}
// internal constructor; not for external access.
//
protected Order (int id, boolean dbExists) {
this.id = id;
this.dbExists = dbExists;
}
}

Categories

Resources