Question

I am trying to write an abstract class that extends another abstract class. The super class is Expression:

public abstract class Expression {
    String expression;

    /*Empty Constructor for Expression object */
    public Expression(){
    }

    /*Constructor for Expression object with String expression*/
    public Expression(String expression){
        this.expression = new String(expression);
    }

and the extends class is CompoundExpression that has two variables from type Expression in it:

public abstract class CompoundExpression extends Expression {
    Expression firstOperand, secondOperand;

    public CompoundExpression(Expression first, Expression second){
        String strFirst = first.expression;
        String strSecond = second.expression;

        this.firstOperand = super(strFirst);
        this.secondOperand = super(strSecond);
    }
}

I figure I am doing it the wrong way cause it isn't working... Can someone help me understand why? And how I can do it the right way?

I thought maybe to write it this way:

public abstract class CompoundExpression extends Expression {

    Expression firstOperand, secondOperand;

    public CompoundExpression(Expression first, Expression second){

        this.firstOperand.expression = first.expression;
        this.secondOperand.expression = second.expression;
    }
}

What do you think?

Was it helpful?

Solution

In this case you seem to be both encapsulating and extending. Both are reasonable things to do but this is a mish-mash of the two. Which one you want depends on your specific use case so I shall explain both

Extending

This is a parent child relationship. In this case the child is a parent. Such as a Cat is a mammel. This would be achieved as follows

public abstract class CompoundExpression extends Expression {


    public CompoundExpression(String first){
        super(first);
    }

    //Other methods that make this class different from the parent class
}

Encapsulating

This is a "has a" relationship. For example a cat "has a" leg. In this case you do not need to use the "extends" keyword

public abstract class CompoundExpression{

    Expression firstOperand, secondOperand;

    public CompoundExpression(Expression first, Expression second){

        this.firstOperand = first;
        this.secondOperand = second;
    }

    //other methods to use the encapsulated Expressions
}

Extending and encapsulating the same class

This has its uses but is far less common than the above two; you need to be very careful, but as you mentioned it you can both extend a class and encapsulate one or more of that class. An analogy for this might be that a FemaleCat both is a cat and can contain cats (in the form of kittens). When doing this always act as if it is "a coincidence" that the class you encapsulate and the class you extend are the same

This would be as follows

public abstract class CompoundExpression extends Expression{

    Expression firstOperand, secondOperand;

    public CompoundExpression(String myString, Expression first, Expression second){

        super(myString);
        this.firstOperand = first;
        this.secondOperand = second;
    }

    //other methods to make this class unique

}

As I say, I personally have never done this and it should not be considered the "default" way to encapsulation. Make sure you really know what you are doing before doing this

Conclusion

Given that a single CompoundExpression contains 2 seperate Expressions I suspect you want an encapsulating relationship

OTHER TIPS

The Expression objects you pass to the constructor of CompoundExpression are created already. There is no need to call the parent constructor (and in fact, that's illegal in that place).

Replace

this.firstOperand = super(strFirst);
this.secondOperand = super(strSecond);

simply by

this.firstOperand = first;
this.secondOperand = second;

Another possibility is to construct the Expression objects in this constructor. Then you don't need to pass Expressions but simply strings:

public CompoundExpression(String strFirst, String strSecond){
    this.firstOperand = new Expression(strFirst);
    this.secondOperand = new Expression(strSecond);
}

It's all a matter of what you're trying to achieve.

you can't do this:

this.firstOperand = super(strFirst);
this.secondOperand = super(strSecond);

you are calling a constructor by super (which is not possible, since super should always be first) and you are trying to use a constructor of an abstract class directly, which is also impossible.

what you need to do, is to have a class which is not abstract that will implement "Expression", and then just call it:

this.firstOperand = new ExpressionImpl(strFirst);
this.secondOperand = new ExpressionImpl(strSecond);

also, in that case, you do not need to extend Expression in your CompoundExpression class.

good luck!

I see you have a bit of confusion. Extension is one thing. What you want I guess is another. This is extension:

public class Point2D {
    int x;
    int y;

    public Point2D(int x, int y) {
        this.x = x;
        this.y = y;
    }


    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

}

the class Point3D is extending the previous one

public class Point3D extends Point2D{

    int z;

    public Point3D(int z, int x, int y) {
        super(x, y);
        this.z = z;
    }

    public int getZ() {
        return z;
    }

    public void setZ(int z) {
        this.z = z;
    }

}

You just want a simple POJO which is using the Expression class you have defined previously. Nothing more than it, just encapsulating the type you defined..

public abstract class CompoundExpression{

    Expression firstOperand, secondOperand;

    public CompoundExpression(Expression first, Expression second){

        this.firstOperand = new Expression(strFirst);
        this.secondOperand = new Expression(strSecond);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top