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...
}
| improve this question | | | | |
  • 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. – Dan Pichelman Mar 28 '16 at 21:53
  • Hi, I modified it some...this is my first post, so thanks for the help. – benzeneAlanine Mar 28 '16 at 22:18
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.

| improve this answer | | | | |
  • 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? – benzeneAlanine Mar 28 '16 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. – Marjan Venema Mar 29 '16 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 Mar 29 '16 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.

| improve this answer | | | | |
  • 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. – benzeneAlanine Mar 28 '16 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 Mar 29 '16 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;
    }

}
| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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