当前位置: 首页 > 知识库问答 >
问题:

扩展抽象类的类如何使用自己的变量?

岳允晨
2023-03-14

我有两个类,它们使用了几个相等的方法,所以我想我可以使用一个抽象类而不是一个接口来允许抽象类有方法体,并减少其他类中代码的重复。但是在运行我的主函数时,我得到一个错误,说x是“null”,我认为这是因为它使用了抽象类中的空变量。但是对于抽象类中的方法,我需要声明方法使用的变量,那么如何让它使用子类中的变量呢?具体来说,错误出现在底部的agamefughts setPosition()中。x=x

这是我的代码:

abstract class AGameFigures {
public Rectangle hitbox;
int action;
ICollision collision;
float tileHeight, tileWidth;
float spriteHeight, spriteWidth;
float velocityY;

public AGameFigures(){
    this.hitbox = hitbox;
    this.action = action;
    this.collision = collision;
    this.tileHeight = tileHeight;
    this.tileWidth =tileWidth;
    this.spriteHeight = spriteHeight;
    this.spriteWidth = spriteWidth;
    this.velocityY = 0;
}

public void update(float delta) {
    float oldY = hitbox.y;
    hitbox.y += velocityY;
    velocityY -= (25 * delta);

    boolean collisionDown = false;
    boolean collisionUpwards = false;

    if(velocityY < 0) {
        collisionDown = collision.collidesDownwards(hitbox.x, hitbox.y);
    } else if(velocityY > 0) {
        collisionUpwards = collision.collidesUpwards(hitbox.x, hitbox.y);
    }
    if(collisionDown) {
        hitbox.y = (int) (oldY / tileHeight) * tileHeight;
        velocityY = 0;
    }
    if(collisionUpwards) {
        hitbox.y = (int) ((hitbox.y+spriteHeight/2) / tileHeight) * tileHeight;
        if(velocityY > 0)
            velocityY = 0;
        velocityY -= (25 * delta);
    }
}
public void setPosition(float x, float y) {
    hitbox.x = x;
    hitbox.y = y;
}

abstract void moveLeft(float delta);

abstract void moveRight(float delta);

public void setVelocityY(float newVelY) {
    velocityY = newVelY;
}
public void jump() {
    if (velocityY == 0)
        velocityY = 7;

}
public int hits(Rectangle r) {
    if(hitbox.overlaps(r))
        return 1;
    return -1;
}

}

public class GamePlayer extends AGameFigures{

public Rectangle hitbox;
int action;
float tileHeight, tileWidth;
float spriteHeight, spriteWidth;
ICollision collision;
float velocityY;


public GamePlayer(float spriteHeight, float spriteWidth, ICollision collision) {
    hitbox = new Rectangle(0.0f, 0.0f, 128.0f, 128.0f);
    velocityY = 0;
    hitbox.x = 0; hitbox.y = 0;
    tileWidth = collision.getTileWidth(); tileHeight = collision.getTileHeight();
    this.spriteHeight = spriteHeight; this.spriteWidth = spriteWidth;
    this.collision = collision;
}

public void action(int type, float x, float y) {
    if(type == 1) {
        velocityY = 0;
        setPosition(hitbox.x, y);
    }
}

@Override
public void moveLeft(float delta) {
    hitbox.x -= (200 * delta);  // delta == "change of time" "for fluid change om motion"
    if(collision.collidesLeftwards(hitbox.x, hitbox.y)) {
        hitbox.x = (int) (hitbox.x / tileWidth) * tileWidth + spriteWidth;
    }
}
@Override
public void moveRight(float delta) {
    hitbox.x += (200 * delta);  // (value) * delta, endre value for å endre movementspeed
    if(collision.collidesRightwards(hitbox.x, hitbox.y)) {
        hitbox.x = (int) (hitbox.x / tileWidth) * tileWidth;
    }
}

}


共有3个答案

松涵容
2023-03-14

我认为你的问题在于抽象类的构造函数。变量将始终为空。

您需要在构造函数中提供参数:

public AGameFigures(Hitbox hitbox, int action, ICollision collision, float tileHeight, float tileWidth, float spriteHeight, float spriteWith, float velocityY){
    this.hitbox = hitbox;
    this.action = action;
    this.collision = collision;
    this.tileHeight = tileHeight;
    this.tileWidth =tileWidth;
    this.spriteHeight = spriteHeight;
    this.spriteWidth = spriteWidth;
    this.velocityY = 0;
}

而且,您不需要重复继承的变量。

王才英
2023-03-14

为什么你要把sames归入超类和子类

皇甫俊雅
2023-03-14

AGameFIG构造函数:

public AGameFigures(){
    this.hitbox = hitbox;
    ... 
}

没有传递给构造函数的参数,因此,hitbox引用类实例字段,该字段为空。构造函数中的这行代码:

this.hitbox = hitbox;

实际上:

this.hitbox = null;

所以后来遇到了一个空端口。需要更新构造函数以传递参数:

public AGameFigures(Rectangle hitbox, ...){
    this.hitbox = hitbox;
    ... 
}

子类需要提供构造函数参数值。

GamePlayer定义了自己的hitbox,这可能会引起一些混乱hitbox应该从GamePlayer中删除,只需依赖基类即可。

检查编译器警告,不要(通常)忽略它们!

 类似资料:
  • 问题内容: 假设我们需要使用一个名为“ BaseNode”的类来实现不同类型的树,从该类派生其他类型的Node,并且它假定具有一个自己类型的实例变量,通常看起来像这样: 现在,如果我要为具有更多成员的AVL树派生Node: 原始(&)节点成员仍然会类型我实施AVL树,其防止。谁能告诉我如何解决这一继承问题?谢谢! 问题答案: 解决方案1- 每次访问时,都将其转换为。您可以在其中编写访问器以使其更加

  • 问题内容: 有这样的事情: 抽象类: 和扩展器: 我想要的是扩展,因为如果不处理它,然后尝试在中处理它。例如add- 但同时让类处理默认值,例如。 这是完全错误的方法吗? 到目前为止,我所做的就是添加一个接口。通常: 在课堂上: 在课堂上: 这看起来像是可用的设计吗? 并且,主要问题: 有没有什么好办法扩展该类,以便可以使用与in 中相同的切换方法?我想知道的是,有没有一个更好的设计,第二个是是否

  • 本文向大家介绍C#扩展抽象基类,包括了C#扩展抽象基类的使用技巧和注意事项,需要的朋友参考一下 示例 与接口(可以描述为实现合同)不同,抽象类充当扩展的合同。 抽象类无法实例化,必须对其进行扩展,然后可以实例化生成的类(或派生类)。 抽象类用于提供通用实现 上面的示例显示了实现Car的任何扩展类如何自动接收HonkHorn方法。这意味着任何开发新汽车的开发人员都无需担心它将如何鸣笛。

  • 问题内容: 我之前了解到抽象类可以扩展具体类。尽管我没从JAVA设计师那里看到原因,但是没关系。我还了解到,扩展具体类的抽象类可以使重写的方法抽象。为什么?您可以提供有用的用例吗?我正在尝试学习设计模式,我不想错过任何东西。 这是示例: 问题答案: 如果我有一组想要默认实现的类(以便它们可以从扩展),并且想要强制提供自己的实现(在这种情况下使其抽象为子类会强制执行此操作。) 当然,此示例中的另一种

  • 我想创建一个自定义的树数据结构,只有节点,我可以迭代他们。然后,我可以扩展这个类,并有非常基本的树 我已经开始工作了,但是当我试图扩展Node类时,问题就来了。对于扩展类,继承的迭代器方法仍然返回节点迭代器,这意味着我每次都要强制转换。下面是我遇到的问题的一个基本示例。让我们建立一个包含整数的树: 是否有一种简单的方法可以解决这个问题,而不需要将iterator()方法从Node类复制到Integ

  • 问题内容: 我正在阅读另一个SO问题,即Swift do-try-catch语法。在他的回答中, rickster 为OP的自定义类创建了扩展。 Konrad77 评论说,这是“保持代码整洁的好方法。” 我尊重他们的知识,这使我相信我在自己的代码中遗漏了一点。 除了为我创建的类创建扩展之外,还有其他好处(除了整洁)还是原因?我可以将相同的功能直接放入类中。如果我是唯一使用该类的人,或者其他人将使用