luismartinezs
luismartinezs

Reputation: 309

Can I have access to a field of a child object from inside a method which is not overridden by the child class?

I am trying to implement the "Space Challenge" program in java.

See EDIT at the bottom for more clarity

The instructions ask you to write a Class Rocket and child classes U1 and U2.

The child classes have fields specific to these, being rocketWeight and maxWeight. Their values have to be different for each of the child classes.

The parent class Rocket has a method canCarry which needs to check the weight of the rocket. This method is inherited by U1 and U2 but NOT overridden.

Then I call the canCarry method, e.g. u1.canCarry(arguments), the method inside itself looks at the variable this.rocketWeight and this.maxWeight, but I have checked that instead of having the value u1.rocketWeight and u1.maxWeight (as I would like them to have), they have value 0.

I think my problem is that I don't know how to have access to a variable from a child object from inside a method of the parent class.

This is the call to the method. The object u1 is of class U1, which is a child class of Rocket:

u1.canCarry(itemList.get(i))

itemList.get(i) is an object that has a field weight

This is the method itself, which is declared inside the class Rocket:

@Override
public boolean canCarry(Item item) {
    return ((this.weightRocket + item.weight) < this.maxWeight);
}

If I print this.weightRocket and this.maxWeight inside the method, both are 0. Outside the method both have the expected value. item.weight also has the value I would expect.

I'm sure this is very basic stuff, I just started with java one week ago.

Thanks

EDIT: a comment below let me know that there's not enough code so I took a look at best practices for asking questions.

The next code snippets show a simplified version of what I'm trying to do.

Rocket.java: contains one method canCarry

public class Rocket {

    int maxWeight;

    boolean canCarry(int itemWeight){
        return itemWeight < this.maxWeight;
    }

}

U1.java: sets the value of maxWeight for an object of this child class

public class U1 extends Rocket {

    int maxWeight = 18;

}

U2.java: same as U1

public class U2 extends Rocket{

    int maxWeight = 23;

}

Main.java: calls canCarry method for objects of class U1 and U2. I would like that the value maxWeight inside the method canCarry is the one defined in the children classes, but it uses the one in the parent class, despite that the objects u1 and u2 are of class U1 and U2.

public class Main {

    public static void main(String[] args) {

        int itemWeight = 20;

        U1 u1 = new U1();
        U2 u2 = new U2();

        if(u1.canCarry(itemWeight)){
            System.out.println("Launch rocket 1!");
        } else {
            System.out.println("Rocket 1 can't launch");
        }

        if(u2.canCarry(itemWeight)){
            System.out.println("Launch rocket 2!");
        } else {
            System.out.println("Rocket 2 can't launch");
        }

    }
}

From the descriptin of the problem it looks like I'm supposed to do this.

The problem: https://classroom.udacity.com/courses/ud283/lessons/2b5bc57f-de73-45a4-b3a7-8dcc8da2f178/concepts/b8b57dc5-2eb8-4834-8e96-4956fc322f50

Verbatim: Create a class Rocket (...) carry and canCarry should be implemented here and will not need to be overridden in the U1 and U2 classes.

Any idea how to deal with this?

Thanks

EDIT: does it have something to do with creating constructors for each of the classes? I didn't do it but I know that java creates a default constructor if you don't

Upvotes: 0

Views: 727

Answers (3)

Daisy Day
Daisy Day

Reputation: 688

Make macWeight in the super class a protected Integer. In the sub classes set the value in a constrictor.

public u1 () {
      this.maxWeight = 18;
}

Etc.

Much more explicit, safer and will work.

Upvotes: 0

Ralf Kleberhoff
Ralf Kleberhoff

Reputation: 7290

There is no (straightforward) way for a superclass method to access subclass fields or methods, but there's no need for that in your situation.

Your mistake is to introduce a new field maxWeight in e.g. your subclass U1. This means that a U1 instance has two fields with the same name maxWeight, one only visible to methods in the Rocket class, and one only visible to methods in the U1 class.

You'd better only have one maxWeight field, visible to Rocket and to its subclasses, and initialize it differently in U1 and U2. You can do that like this:

public class U1 extends Rocket {
    public U1() {
        maxWeight = 18;
    }
}
public class U2 extends Rocket {
    public U2() {
        maxWeight = 23;
    }
}

Then everything will work as expected.

Upvotes: 0

luismartinezs
luismartinezs

Reputation: 309

I solved my own question. I had to give value to the fields in a constructor.

This is the code that works as intended:

Rocket.java

public class Rocket {

    int maxWeight;

    Rocket(){
        maxWeight = 0;
    }

    boolean canCarry(int itemWeight){
        return itemWeight < this.maxWeight;
    }

}

U1.java:

public class U1 extends Rocket {

    U1() {
        maxWeight = 18;
    }

}

U2.java:

public class U2 extends Rocket{

    U2() {
        maxWeight = 23;
    }

}

Main.java:

public class Main {

    public static void main(String[] args) {

        int itemWeight = 20;

        U1 u1 = new U1();
        U2 u2 = new U2();

        if(u1.canCarry(itemWeight)){
            System.out.println("Launch rocket 1!");
        } else {
            System.out.println("Rocket 1 can't launch");
        }

        if(u2.canCarry(itemWeight)){
            System.out.println("Launch rocket 2!");
        } else {
            System.out.println("Rocket 2 can't launch");
        }

    }
}

Upvotes: 1

Related Questions