2

I'm trying to create a parent class with a constructor that takes a single int as a parameter. I also need to derive a child class that creates two instances of the parent class using a constructor that takes two ints. I know I use the "super" keyword to use the constructor from the parent class, but how can I use the second int in the child constructor to call the same parent constructor? I can't use "super" twice, so is there any other way to use the second parameter? I know that I could just call the child constructor twice from the main method, but I specifically need a child constructor that takes two parameters and creates two objects of the parent class. Thanks.

public class Int 
{   
    public int numberOne;

    public Int(int numberHere)
    {
        numberOne = numberHere;
    }

    //methods...
}   



public class Rational extends Int
{
    Int numerNum;
    Int denomNum;

    public Rational(int oneHere, int twoHere)
    {
        super(oneHere);
    }

    //methods...
}
2
  • I think your code example may be missing a few "}"s. Can you edit the question and add them? Also, if every line starts with 4 spaces your code will be formatted better. Commented Mar 28, 2016 at 21:53
  • Hi, I modified it some...this is my first post, so thanks for the help. Commented Mar 28, 2016 at 22:18

3 Answers 3

11

You're trying to use inheritance when you need to be using composition.

Use this as a starting point instead:

public class Rational {

    private Int numerator;
    private Int denominator;

    public Rational(int num, int den) {
        numerator = new Int(num);
        denominator = new Int(den);
    }
}

As a general rule of thumb, inheritance is best used for "Is-a" relationships. Ask yourself, "Is a rational number an integer?" The answer is clearly no.

3
  • Wow! Awesome. Thank you so much. This worked. So, if I don't extend or import another class, how does the compiler know where to look for the Int class? Commented Mar 28, 2016 at 22:19
  • 1
    @K.Nes: Would the compiler really use different means to find the int class when you instantiate it rather than extend it? If it can find it, it can find it, regardless of what your code does with it. Commented Mar 29, 2016 at 6:07
  • @K.Nes, it depends on the language, but in Java, the key is that the compiler keeps a list of all types that are in scope for the current file. If both classes are part of the same package and the same project, then they are already in the same scope. It doesn't matter whether you use the class or inherit from it--the compiler does the same thing to find out what class you are referring to.
    – riwalk
    Commented Mar 29, 2016 at 15:32
2

By inheritance, you model a "is-a" relationship. By making the Rational be a subclass of Integer, you are basically saying that the Rational IS A Integer (is it?).

Moreover, the constructor of an object or of it's superclass is used to initialize that object. You cannot use the constructor to initialize multiple objects.

What you really want to do is to model a "has-a" relationship. A Rational has 2 integers: a denominator and a numerator. Which you can model by having 2 Int members.

2
  • Thanks very much. I knew I was not understanding something correctly. Can you explain how the compiler knows where to find the Int class if I don't extend or import it? Thanks. Commented Mar 28, 2016 at 22:21
  • The simple explanation is that the compiler has something known as "classpaths", which is basically a set of paths where to look for files that may contain the class it's looking for.
    – Paul92
    Commented Mar 29, 2016 at 16:07
2

The problem is that you are abusing inheritance to model something that is not an “is a” relationship. A rational number “is not an integer”. It's also not two integers – besides the fact that in Java you can only derive from exactly one class. On the contrary, a rational number “has two” integers: the numerator and the denominator. There are signs in your code that you already recognized this, but not to the full extent. In short, remove the inheritance relationship and simply assign the two members.

public final class Int {

    private final int value;

    public Int(final int val) {
        this.value = val;
    }

}

public final class Rational {

    private final Int numerator;
    private final Int denominator;

    public Rational(final int numer, final int denom) {
        this.numerator = new Int(numer);
        this.denominator = new Int(demom);
    }

}

Actually, instead of new'ing up the Int objects, I'd prefer them to be passed in to the constructor.

public final class Rational {

    private final Int numerator;
    private final Int denominator;

    public Rational(final Int numer, final Int denom) {
        this.numerator = numer;
        this.denominator = demom;
    }

}
0

Not the answer you're looking for? Browse other questions tagged or ask your own question.