I have 2 classes: FinishButton and ChangeSpeedButton.
FinishButton is the parent class, but it is from a different package and it is a subclass of another class.
It has 2 constructors:
public class FinishButton extends Button {
public FinishButton(Point...points) {
super(Response.SLOW,Type.HOLD,points);
}
public FinishButton() {
this(new Point(width-75,height-75),
new Point(width-75,height-15),
new Point(width-15,height-15),
new Point(width-15,height-75));
}
public void function() {
nextPanel();
}
public void draw(Graphics g) {
super.draw(g);
this.xpoints[0] = 0;
g.setColor(Defaults.GRAPHIC_COLOR);
int[] xPoints = {
width-45-(int)((20*Math.sqrt(3))/2),
width-45-(int)((20*Math.sqrt(3))/2),
width-45+(int)((20*Math.sqrt(3))/2)
},
yPoints = {
height-65,height-25,height-45
};
int nPoints = 3;
g.fillPolygon(xPoints, yPoints, nPoints);
}
}
These classes are works in progress but ChangeSpeedButton looks like this:
public class ChangeSpeedButton extends FinishButton {
public ChangeSpeedButton() {
super(new Point(width/2-30,height-75),
new Point(width/2-30,height-15),
new Point(width/2+30,height-15),
new Point(width/2+30,height-75));
}
}
The weird thing is that FinishButton handles the varargs perfectly when overloading its own constructor, but for some reason on ChangeSpeedButton's constructor, Eclipse is telling me to
either "remove arguments to match 'FinishButton()'" or "Change
constructor 'FinishButton()': Add parameters
'Point,Point,Point,Point'".
Does anyone know why it's giving me an error on ChangeSpeedButton?
Edit: I added the full classes. And as requested, here is the Point class:
public class Point {
private double x,y;
public double getX() { return x; }
public double getY() { return y; }
public Point() {
this(0,0);
}
public Point(double x,double y) {
this.x = x;
this.y = y;
}
public String toString() {
return "Point: ("+x+", "+y+")";
}
}
Maybe it has to do with the fact that the Button classes are nested classes?
Oh my goodness. I'm so dumb. I had 2 FinishButton files open and even though I saved one of them with the correct changes, the ChangeSpeedButton only looked at the outdated file.
Related
In my project I came across this problem, where I have an abstract class of Entity, and it's children are Player, Shot and Enemy. I want to check for collision between them. A separate Physics class is doing the collision evaluation with the following code:
public class Physics {
private static int height = 32;
private static int width = 32;
public static void collision(Entity entity, LinkedList<Entity> eList) {
for (int i = 0; i<eList.size(); i++) {
if (entity.getBounds(width, height).intersects(eList.get(i).getBounds(width, height))) {
entity.collidesWith(eList.get(i));
}
}
}
}
The linkedList contains both Shots and Enemies, and yet for some reason, the collision only calls the collidesWith(Entity entity) method, instead of the collidesWith(Shot b) or collidesWith(Enemy e).
edit: The mentioned classes (with only the code that I think would matter from them in this case)
Entity:
public abstract class Entity {
protected double x;
protected double y;
public Entity (double x, double y) {
this.x = x;
this.y = y;
}
public abstract void tick();
public double getX() { return x; }
public double getY() { return y; }
public Rectangle getBounds(int width, int height) {
return new Rectangle((int)x, (int)y, width, height);
}
public abstract void collidesWith(Entity e);
public abstract void collidesWith(Enemy e);
public abstract void collidesWith(Shot s);
Player:
public class Player extends Entity {
private boolean alive;
private int gameWidth, gameHeight;
private GameController gCont;
private Textures textures;
public Player( String name, int x, int y, int gameWidth, int gameHeight, Textures textures, GameController gCont) {
super(x,y);
this.name = name;
this.score = 0;
this.gameWidth = gameWidth;
this.gameHeight = gameHeight;
this.gCont = gCont;
this.textures = textures;
this.alive = true;
}
public void tick() {
gCont.collisionCheck(this);
}
public void collidesWith(Enemy e) {
System.out.println("Player collides with enemy");
this.alive = false;
}
public void collidesWith(Shot s) {
return;
}
public void collidesWith(Entity e) {
System.out.println("collided with entity");
return;
}
Shot
public class Shot extends Entity {
private Textures textures;
private GameController gCont;
public Shot(double x, double y, Textures textures, GameController gCont) {
super(x, y);
this.textures = textures;
this.gCont = gCont;
}
public void tick() {
x+=10;
gCont.collisionCheck(this);
}
public void collidesWith(Entity e) {
return;
}
public void collidesWith(Enemy e) {
gCont.removeEntity(e);
gCont.removeEntity(this);
gCont.addScore();
}
#Override
public void collidesWith(Shot s) {
return;
}
Enemy
public class Enemy extends Entity {
private int speed;
public Enemy(double x, double y) {
super(x, y);
Random random = new Random();
speed = random.nextInt(3)+1;
}
public void tick() {
x-=speed;
}
public void collidesWith(Entity e) {
return;
}
#Override
public void collidesWith(Enemy e) {
return;
}
#Override
public void collidesWith(Shot s) {
return;
}
How can I get it to call to the correct functions?
Look into Java's Generics. I think you could use something like this:
public abstract class Entity<T> {
protected double x;
protected double y;
public Entity (double x, double y) {
this.x = x;
this.y = y;
}
public abstract void tick();
public double getX() { return x; }
public double getY() { return y; }
public Rectangle getBounds(int width, int height) {
return new Rectangle((int)x, (int)y, width, height);
}
public abstract void collidesWith(T e);
}
Might be wrong, I am new to answering questions on stackoverflow.
Hope this gives you some clarity:
entity.collidesWith(eList.get(i));
eList.get(i) in that line, in your Physics class Entity returns an an object of type Entity.
This is because it is defined like that:
LinkedList<Entity> eList
That means that if you have an overload that takes that Entity it would just call that method. This is exactly what I see in your code. You have a method overload for "collidesWith" with Argument: Entity.
In all of the children classes of Entity.
I think you should read more about "Java Polymorphism".
For me the Entity class knowing about Enemy and Shot is wrong.
Why don't you remove these two methods from Entity and subclasses:
public abstract void collidesWith(Enemy e);
public abstract void collidesWith(Shot s);
And keep and implement only:
public abstract void collidesWith(Entity e);
If you need to know the type of Entity e passed as argument, you can use reflection, but this is bad design. It is better to implement collidesWith in such way that it doesn't need to know the exact type of the passed argument.
I think a solution other than Generic type as specified by Jamie Bisotti, is to use an interface and a switch to check which class is what.
This is the interface that declares a method that all entities that can collide must have:
public interface Collidable {
public boolean collidesWith(Collidable entity);
}
Then each class that you want to be able to collide has to implement that:
public class Enemy extends Entity implements Collidable {
private int speed;
public Enemy(double x, double y) {
super(x, y);
Random random = new Random();
speed = random.nextInt(3)+1;
}
public void tick() {
x-=speed;
}
#Override
public void collidesWith(Collidable e) {
if (e.getClass().equals(Shot.class)) {
// DO SOMETHING, I am colliding with a shot
} else if(e.getClass().equals(Enemy.class)) {
// I am colliding with an Enemy
}
. . . etc
}
I prefer to use Interfaces so I can specify each behaviour. At the moment it seems to be all simple and everything can be extended from the Entity abstract class, but there will be a moment when you will differentiate each entity by many other feature.
For example a flying enemy, a walking enemy, ecc ecc and you can specify each feature with an interface.
In this case, the interface is also very simple. But you could specify many methods that you want to be implemented such as
public boolean canCollide();
public boolean isAlive(); //if the entity is already dead you might want not to stop a bullet
public boolean isAnimatingDeath(); //if the entity is animating death could collide with another antity because of its exploding animation, maybe you want to avoid that.
You can implement som method in the abstract Entity class, but that abstract entity shouldn't know about its children. This is the reason to implement some methods using the generic "Collidable" type as input, directly in the children.
I have 2 enums which look similar:
public enum enum1{
A(1,1),
B(2,2);
private final int x,y;
enum1(int x,int y){
this.x=x;
this.y=y;
}
int func(){ return this.x+this.y; }
}
public enum enum2{
C(3,3),
D(4,4);
private final int x,y;
enum2(int x,int y){
this.x=x;
this.y=y;
}
int func(){ return this.x+this.y;}
}
public class test{
void method(enum1 e){ /*something using func*/ }
void method(enum2 e){ /*something using func*/ }
}
How do I abstract the functionality of these enums in an interface and use only one method in the test class instead of two by passing the interface.
Edit: I don't want the enums to be merged. I need separate enums.
One thing is for sure: as long as x and y are private and there's no way to read them from outside the class - you would have to implement the same method for each enum. If you allow the reasonable change to add accessors to these fields in the enums, then you can use an interface's default method to implement the umbrella behavior:
interface Addable {
int getX();
int getY();
default int add() {
return getX() + getY();
}
}
enum Enum1 implements Addable {
A(1, 1), B(2, 2);
private final int x, y;
Enum1(int x, int y) {
this.x = x;
this.y = y;
}
#Override
public int getX() {
return x;
}
#Override
public int getY() {
return y;
}
}
Then you can make a call like Enum1.B.add() which will give 4. As for your test class:
public class Test {
void method(Addable e) { e.add(); }
}
is now valid for anything that implements Addable.
If you're worried about bloating the code, I recommend using Lombok:
#RequiredArgsConstructor
enum Enum1 implements Addable {
A(1, 1), B(2, 2);
#Getter
private final int x, y;
}
Note: type names should start with an uppercase. enum1 and test shoud be Enum1 and Test.
Create an interface that is implemented by each enum, only 'problem' the method must be public:
public interface Inter {
public void func();
}
public enum Enum1 implements Inter {
A(1,1),
B(2,2);
private final int x,y;
Enum1(int x,int y) {
this.x=x;
this.y=y;
}
#Overwrite
public int func() { return this.x+this.y; }
}
public enum Enum2 implements Inter {
...
#Overwrite
public int func() { ... }
}
public class Test {
void method(Inter e) {
// something using func
int sum = e.func();
}
}
main class->>>
public class scoreMain {
public static void main(String[] args) {
// Football Score board
Score scoreObject = new Score();
Score scoreObject1 = new Score(1);
Score scoreObject2 = new Score(1,2);
Score scoreObject3 = new Score(1,2,3);
}
}
and constructor class -->>>
public class Score {
public void Score()
{
Score(0,0,0);
}
public void Score(int x)
{
Score(x,0,0);
}
public void Score(int x,int y)
{
Score(x,y,0);
}
public String Score(int x,int y,int z)
{
Score(x,y,z);
return String.format("%d/%d%d",x,y,z);
}
}
but it shows error when creating objects ...
the constructor score(int) is undefined
the constructor score(int int ) is undefined
the constructor score(int int int ) is undefined
Constructors do not return anything. Not String nor void or anything else. You should just change the constructors as follows:
public class Score {
public Score() {
this(0,0,0);
}
public Score(int x) {
this(x,0,0);
}
public Score(int x,int y){
this(x,y,0);
}
public Score(int x,int y,int z) {
Score(x,y,z); // Not sure what's this - you can't do a recursive constructor call. Doesn't make any sense
return String.format("%d/%d%d",x,y,z); // Remove the return statment.
}
}
Also notice to not only not do a return on any value, but also you have a recursive call for the constructor in the last overloaded constructor. It doesn't make any sense and won't work.
BTW - the correct way of overloading constructors is by calling this() inside the overloads and have only one implementation. Look at this question for further details.
In your code, there are only methods, no constructors. Constructors have no return type.
Example:
public class Score {
public Score()
{
this(0,0,0);
}
public Score(int x)
{
this(x,0,0);
}
public Score(int x,int y)
{
this(x,y,0);
}
public Score(int x,int y,int z)
{
//??
//constructors cannot return anything!
//return String.format("%d/%d%d",x,y,z);
}
}
Also, to invoke other constructor of the same class, you should use keyword this, not class name.
So, first constructor would look like this
public void Score()
{
this(0,0,0);
}
Also, what you have here is a method, not a constructor. Constructors don't have return types
public abstract class SuperClass {
public int x, y;
public static int z;
}
I want every subclass of SuperClass to have the static variable z. Naturally z will contain a different value for each subclass. I'm hoping to avoid defining z in every subclass, since it's going to be a functional dependancy of values x and y; Is this possible?
Unlike instance variables that are "one per instance", static variables are not "one per subclass" - they are "one per declaring class". In other words, subclasses of SuperClass share SuperClass.z, but they cannot "override" it on a class-by-class basis.
It does not mean that you cannot implement it yourself: on way to make your own per-subclass storage of integers is adding a static Map<Class,int> zs to SuperClass, with optional functions for accessing the data:
public abstract class SuperClass {
public int x, y;
private static Map<Class,Integer> zs = new HashMap<Class,Integer>();
protected static int getZ(Class c) {
Integer res = zs.get(c);
return res == null ? -1 : res.intValue();
}
protected static void setZ(Class c, int v) {
zs.put(c, v);
}
}
class SubClassOne extends SuperClass {
public int getZ() {
return SuperClass.getZ(SubClassOne.class);
}
}
class SubClassTwo extends SuperClass {
public int getZ() {
return SuperClass.getZ(SubClassTwo.class);
}
}
Probably the best way to do this is to have a z() method or similar in the abstract class, and override the method in the subclasses you want.
Example:
public abstract class SuperClass {
public int x, y;
protected int z() {
return 42; // protected so only subclasses can see it - change if required
}
}
public class SubClassOne extends SuperClass {
public void foo() {
// do something...
int z = z();
// something else...
}
}
public class SubClassTwo extends SuperClass {
#Override
protected int z() {
return 1;
}
// use z() accordingly
}
if i understand you correctly then do
public abstract class SuperClass {
public int x, y, z;
public SuperClass(int z) {
this.z = z;
}
}
then any class that extends this class inherits z;
Im currently making a simple pluginable program. My problem is that I don't want to let plugin access all base-plugin fields/methods. For example:
public abstract class BasePlugin {
private int x; //Mysterious x
public abstract void update(); //update func that may need x, but can't change it
protected final int getX() {return x;} //x accessor
}
And that would work unless you realize that there is no way to set x.
What can I do? I want to make subclass (plugin) unable to change x, but let it read the value. Value should be accesible at least once when creating (that would be enough).
EDIT: Constructor works in most cases, but what if I have for example:
public abstract class BasePlugin {
private List<int> x; //Mysterious x
public abstract void update(); //update func that may need x, but can't change it
protected final List<int> getX() {return x;} //x accessor
public BasePlugin(List<int> y) {x = y;}
}
public class Plugin {
public Plugin(List<int> y)
{
super(y);
y.remove(0); //Will it work?
}
}
An abstract class is permitted to have a constructor, so you can create a parameterless constructor for BasePlugin:
public abstract class BasePlugin {
private int x; //Mysterious x
public BasePlugin() {
x = 42;
}
public abstract void update(); //update func that may need x, but can't change it
protected final int getX() {return x;} //x accessor
}
And now when a plugin is created, x is set to 42. You don't even need to make any code changes to the plugins to make them use this constructor.
To answer the edited question: If x is a List and you don't want the plugins to modify it, your constructor should be copying it and wrapping it in an unmodifiable list. Otherwise, any plugin can call getX().add(myObject).
public BasePlugin(List<int> y) {
List<int> temp = new ArrayList<int>();
Collections.copy(temp, y); // shallow copy of the list
this.x = Collections.unmodifiableList(temp);
}
Now if the plugin's constructor is
public Plugin(List<int> y)
{
super(y);
y.remove(0); //Will it work?
}
It will have no effect on the BasePlugin's list.
You can add a constructor to get your property initialized by the subclasses:
public abstract class BasePlugin {
private int x; //Mysterious x
public BasePlugin(int x) {
this.x = x;
}
public abstract void update(); //update func that may need x, but can't change it
protected final int getX() {return x;} //x accessor
}
You can use Constructor Injection.
public abstract class BasePlugin{
private int x;
public BasePlugin(int x){
this.x=x;
}
public abstract void update(); //update func that may need x, but can't change it
protected final int getX() {return x;} //x accessor
}
And in your childs
public class Plugin extends BasePlugin{
public Plugin(int x){
super(x);
}
}