在Java中用超类的两个参数扩展类

在Java中用超类的两个参数扩展类,java,abstract,extends,Java,Abstract,Extends,我正在尝试编写一个扩展另一个抽象类的抽象类。超类是表达式: public abstract class Expression { String expression; /*Empty Constructor for Expression object */ public Expression(){ } /*Constructor for Expression object with String expression*/ public Expr

我正在尝试编写一个扩展另一个抽象类的抽象类。超类是
表达式

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);
    }
extends类是
CompoundExpression
,其中包含两个类型
Expression
的变量:

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);
    }
}
我想我做得不对,因为它不起作用。。。有人能帮我理解为什么吗?我怎样才能用正确的方法来做呢

我想也许可以这样写:

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;
    }
}

你认为呢?

传递给
componeexpression
构造函数的
表达式
对象已经创建好了。不需要调用父构造函数(事实上,在那个地方这是非法的)

替换

this.firstOperand = super(strFirst);
this.secondOperand = super(strSecond);
简单地说

this.firstOperand = first;
this.secondOperand = second;
另一种可能是在此构造函数中构造
表达式
对象。然后不需要传递
表达式
s,只需传递字符串:

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

这完全取决于你想要实现什么。

在这种情况下,你似乎既在封装又在扩展。两者都是合理的做法,但这是两者的混搭。您想要哪一个取决于您的特定用例,因此我将解释这两个

延伸 这是一种父子关系。在这种情况下,子对象是父对象。例如猫是一只母猫。这将通过以下方式实现

public abstract class CompoundExpression extends Expression {


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

    //Other methods that make this class different from the parent class
}
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

}
封装 这是一种“有”的关系。例如,一只猫有一条腿。在这种情况下,您不需要使用“extends”关键字

扩展和封装同一类 这有它的用途,但远不如上述两种常见;您需要非常小心,但正如您所提到的,您既可以扩展一个类,也可以封装该类的一个或多个。这方面的一个类比可能是,一只母猫既是一只猫,也可以包含猫(以小猫的形式)。在执行此操作时,始终表现为封装的类和扩展的类是相同的“巧合”

具体如下

public abstract class CompoundExpression extends Expression {


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

    //Other methods that make this class different from the parent class
}
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

}
正如我所说,我个人从来没有这样做过,它不应该被认为是封装的“默认”方式。在做这件事之前,确保你真的知道自己在做什么

结论 考虑到单个CompoundExpression包含两个独立的表达式,我怀疑您想要一个封装关系

您不能这样做:

this.firstOperand = super(strFirst);
this.secondOperand = super(strSecond);
您通过super调用构造函数(这是不可能的,因为super应该总是第一个),并且您试图直接使用抽象类的构造函数,这也是不可能的

您需要做的是创建一个非抽象类来实现“表达式”,然后调用它:

this.firstOperand = new ExpressionImpl(strFirst);
this.secondOperand = new ExpressionImpl(strSecond);
另外,在这种情况下,您不需要在CompoundExpression类中扩展表达式


祝你好运

我看你有点困惑。 扩展是一回事。我想你想要的是另一个。 这是分机:

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;
    }

}
Point3D
正在扩展上一个类

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;
    }

}
您只需要一个简单的
POJO
,它使用前面定义的
Expression
类。只需封装您定义的类型

public abstract class CompoundExpression{

    Expression firstOperand, secondOperand;

    public CompoundExpression(Expression first, Expression second){

        this.firstOperand = new Expression(strFirst);
        this.secondOperand = new Expression(strSecond);
    }
}

您似乎是在封装而不是扩展。这两种方法都是合理的,但这是两种方法的混合。你能解释一下我在哪里封装和在哪里扩展吗?两者之间的区别是否清楚?你的编辑可以。请记住,super()构造函数仍然在构造函数的顶部被调用,即使您没有将其显式化。如果
Expression
没有
Expression()
构造函数,则必须显式选择一个构造函数。因此,我需要扩展类并封装它:D因为我想使用超类的所有方法,并在子类中封装两个超类实例。这是合理的???@YuvalLevy这不是不可能的,但它是非常不寻常的。在这两种情况下,你都需要考虑这两种行为;将扩展和封装为单独的操作,几乎是“巧合”,您正在扩展的类也是您正在扩展的类encapsulating@YuvalLevy我已经添加了一个关于如何实现这一点的部分,但是请确保它确实是您想要的——扩展和封装并不罕见。这只是一个简单的问题(无论父类是抽象类还是接口,这与该模式都毫不相关)。@Heuster Fair。然而,我担心OP会进入一些技术上可行但他们可能不理解的东西(为了扩展而扩展,实际上只是封装)。我已经淡化了它的不寻常之处