mariofalcao
mariofalcao

Reputation: 61

Java Accessing subclasses methods/variables from abstract class

This code is not mine and i need to add some improvements to it, but i'm stuck in this problem.

I have an abstract class "CallNode" and a lot of subclasses, one of them is "Call". The "Checker" class is intercepting missed calls, but return them as CallNode. My problem is that i need to get the id of this call, but i can't access it by CallNode.

Do you have any suggestions to solve this problem?

I let you the code, so that you can better understand the problem:

public abstract class CallNode {
    public abstract CallNode hasMissingCall();
}

public class Call extends CallNode {
    public int id;

    // Simplification of method
    public CallNode hasMissingCall() {  
        if (true)
            return this;
        // ...
    }
}

public class Checker{
    private static CallNode rootExpected;

    CallNode missing = rootExpected.hasMissingCall();

    System.out.println( missing.id ); // THE PROBLEM!!!
}

Thank's in advance!!!

Upvotes: 2

Views: 13022

Answers (4)

Rohit Jain
Rohit Jain

Reputation: 213193

You should never directly access your fields.

In general the fields should be declared private and you should have public accessor methods to access them.

If you can modify your classes, then add a method getId() in both abstract CallNode class and Call class. And in Call class have this method return your this.id. This will do the job for you.

So, add this method to your Call class: -

public int getId() {
    return this.id;
}

Let this method be abstract in your Abstract class.

public abstract class CallNode {
    public abstract CallNode hasMissingCall();
    public abstract int getId();
}

And invoke it using : -

missing.getId();

This will call the getId() of your Call class.

This code is not mine and i need to add some improvements to it,

PS: - One improvement you really need to add is, change the hasMissingCall to getMissingCall as it is returning you a missed call. Always follow naming conventions in your code.
Remember, you don't write code for yourself, but you write them for others to use and maintain.

Upvotes: 2

Anton Bessonov
Anton Bessonov

Reputation: 9803

You can specify absract method getId() in CallNode and implement it in children. Then you an access it in your Checker.

public abstract class CallNode {
    public abstract CallNode hasMissingCall();
    public abstract int getId();
}

public class Checker{
    private static CallNode rootExpected;

    CallNode missing = rootExpected.hasMissingCall();

    System.out.println( missing.getId() );
}

public class Call extends CallNode {
    public int id; // better set private modifier
    public int getId() {
        return id;
    }
    ...
}

Upvotes: 0

Heisenbug
Heisenbug

Reputation: 39164

Define a template method returning the id in the abstract class:

public abstract class CallNode {
    public abstract CallNode hasMissingCall();

    public abstract int getId();
}

let subclass implement it:

public class Call extends CallNode {
    public int id;

    // Simplification of method
    public CallNode hasMissingCall() {  
        if (true)
            return this;
        // ...
    }
    public int getId()
    {
         return this.id;
    }
}

That's an option. Personally I'll move the id field upward in the CallNode class, since I think it's supposed to be unique and shared by all subclasses.

Upvotes: 4

Vlad
Vlad

Reputation: 18633

You could cast down to Call:

System.out.println( ((Call) missing).id );

That's if you can't change the other classes, and if you know missing will be an instance of Call.

Upvotes: 2

Related Questions