Java 爪哇:我怎样才能使一个球表现得像一个弹跳的弹性球?
我有两门课Java 爪哇:我怎样才能使一个球表现得像一个弹跳的弹性球?,java,Java,我有两门课BouncingBall,还有一门叫做ElasticBall。这两个类都扩展了实现名为Ball的接口的BallImpl public interface Ball { int DEFAULT_RADIUS = 50; int radius(); Point center(); void update(); } public class BouncingBall extends BallImpl { public static final in
BouncingBall
,还有一门叫做ElasticBall
。这两个类都扩展了实现名为Ball
的接口的BallImpl
public interface Ball {
int DEFAULT_RADIUS = 50;
int radius();
Point center();
void update();
}
public class BouncingBall extends BallImpl {
public static final int MOVEMENT_SPEED = 12;
static final int DOWN = 1;
static final int UP = -1;
private int direction;
BouncingBall(int x, int y, int direction) {
super(x, y);
this.direction = direction;
}
@Override
public void update() {
direction = reverseDirectionIfNecessary();
y = move();
}
private int reverseDirectionIfNecessary() {
if (movingTooHigh() || movingTooLow()) {
return switchDirection();
}
return this.direction;
}
private boolean movingTooLow() {
return y + radius >= BallWorld.BOX_HEIGHT && movingDown();
}
private boolean movingTooHigh() {
return y - radius <= 0 && movingUp();
}
private int switchDirection() {
return movingDown() ? UP : DOWN;
}
private int move() {
return y + (MOVEMENT_SPEED * direction);
}
private boolean movingDown() {
return direction == DOWN;
}
private boolean movingUp() {
return direction == UP;
}
}
public class ElasticBall extends BallImpl {
public static final int GROWTH_RATE = 2;
static final int GROW = 1;
static final int SHRINK = -1;
private int growthDirection;
ElasticBall(int x, int y, int radius, int growthDirection) {
super(x, y, radius);
this.growthDirection = growthDirection;
}
@Override
public void update() {
growthDirection = reverseGrowthDirectionIfNecessary();
radius = next();
}
private int reverseGrowthDirectionIfNecessary() {
if (growingTooBig() || shrinkingTooSmall()) {
return switchDirection();
}
return this.growthDirection;
}
private boolean shrinkingTooSmall() {
return radius <= 0 && shrinking();
}
private boolean growingTooBig() {
return radius >= Ball.DEFAULT_RADIUS && growing();
}
private int switchDirection() {
return growing() ? SHRINK : GROW;
}
private int next() {
return radius + (GROWTH_RATE * growthDirection);
}
private boolean shrinking() {
return growthDirection == SHRINK;
}
private boolean growing() {
return growthDirection == GROW;
}
}
公共接口球{
int默认_半径=50;
int半径();
点中心();
无效更新();
}
公共类弹跳球扩展BallImpl{
公共静态最终整数移动速度=12;
静态最终整数向下=1;
静态最终整型=-1;
私人int方向;
弹跳球(整数x,整数y,整数方向){
super(x,y);
这个方向=方向;
}
@凌驾
公共无效更新(){
方向=反转方向(如有必要)();
y=移动();
}
私有int reverseDirectionIfEssential(){
if(movingTooHigh()| | movingTooLow()){
返回开关方向();
}
返回这个方向;
}
私有布尔movingTooLow(){
返回y+半径>=BallWorld.BOX_高度和向下移动();
}
私有布尔值movingTooHigh(){
返回y-radius一旦您分离了层次结构,就无法在java中合并它们
这是一个设计问题:如果您知道ElasticBall
和BouncingBall
可以组合在一起,那么您应该创建两个接口Elastic
和Bouncing
,这两个接口都是扩展接口Ball
,使用对这两个接口都有效的常用方法
然后,可以将公共方法实现设置为一个公共抽象类,比如说AbstractBall
。在这一点上,您最终可以详细介绍三个实现:
ElasticBall扩展了AbstractBall实现了弹性
BouncingBall extendis AbstractBall实现反弹
ElasticBouncingBall扩展AbstractBall实现弹性反弹
通过这种方式,您将能够控制在每个方法中要做什么,重用代码来处理常见的内容(在抽象类中)
public interface Ball {
int DEFAULT_RADIUS = 50;
int radius();
Point center();
void update();
}
public class BouncingBall extends BallImpl {
public static final int MOVEMENT_SPEED = 12;
static final int DOWN = 1;
static final int UP = -1;
private int direction;
BouncingBall(int x, int y, int direction) {
super(x, y);
this.direction = direction;
}
@Override
public void update() {
direction = reverseDirectionIfNecessary();
y = move();
}
private int reverseDirectionIfNecessary() {
if (movingTooHigh() || movingTooLow()) {
return switchDirection();
}
return this.direction;
}
private boolean movingTooLow() {
return y + radius >= BallWorld.BOX_HEIGHT && movingDown();
}
private boolean movingTooHigh() {
return y - radius <= 0 && movingUp();
}
private int switchDirection() {
return movingDown() ? UP : DOWN;
}
private int move() {
return y + (MOVEMENT_SPEED * direction);
}
private boolean movingDown() {
return direction == DOWN;
}
private boolean movingUp() {
return direction == UP;
}
}
public class ElasticBall extends BallImpl {
public static final int GROWTH_RATE = 2;
static final int GROW = 1;
static final int SHRINK = -1;
private int growthDirection;
ElasticBall(int x, int y, int radius, int growthDirection) {
super(x, y, radius);
this.growthDirection = growthDirection;
}
@Override
public void update() {
growthDirection = reverseGrowthDirectionIfNecessary();
radius = next();
}
private int reverseGrowthDirectionIfNecessary() {
if (growingTooBig() || shrinkingTooSmall()) {
return switchDirection();
}
return this.growthDirection;
}
private boolean shrinkingTooSmall() {
return radius <= 0 && shrinking();
}
private boolean growingTooBig() {
return radius >= Ball.DEFAULT_RADIUS && growing();
}
private int switchDirection() {
return growing() ? SHRINK : GROW;
}
private int next() {
return radius + (GROWTH_RATE * growthDirection);
}
private boolean shrinking() {
return growthDirection == SHRINK;
}
private boolean growing() {
return growthDirection == GROW;
}
}
公共类BallImpl实现Ball{
列出行为=。。。
@凌驾
公共无效更新(){
behavior.forEach(behavior->behavior.update(this));
}
...
}
公共接口行为{
作废更新(BallImpl BallImpl);
}
然后,把你的弹性和弹跳逻辑写成行为。你不能从其中一个继承BouncingElasticBall
,而不必有两个超类吗?为什么你需要它们都分开?从设计的角度来看,你可以有ElasticBall
和BouncingBall
实现Ball
inteFace而不是扩展一个超类。从物理学的角度来看,我不知道如何立即使球反弹。这种要求很愚蠢。提出解决方案的最好方法是,像往常一样,组合。如果你现在想要一个重新更新的弹跳球和一个黄色的弹跳球怎么办?要创建所有的类呢S:直到所有的组合都被覆盖了。不:使用组合。有一个球,你可以重复使用并完成它。告诉任何设计它的人,他/她不理解OOP的概念。它是面向对象的编程,而不是全对象编程。考虑一下你的问题。听起来你是在问物理,但是A。实际上,这实际上是一个“如何进行适当的OO设计”问题。关键在于你的问题:当你想要行为时,你应该立即思考界面。注意:在模式语言中,这被称为访客模式。在我看来,你的答案是解决原始问题的最佳选择。我甚至会创建一个ComposedBallBehavior
,来完成这个问题r-loop,只允许类中有一个BallBehavior
,而不允许它们的列表。