I've been struggling a couple of days trying to understand how the code below works.
I simply have: an abstract class:
public abstract class Screen {
protected final Game game;
public Screen(Game game) {
this.game = game;
}
public abstract void update(float deltaTime);
public abstract void paint(float deltaTime);
public abstract void pause();
public abstract void resume();
public abstract void dispose();
public abstract void backButton();
}
and an interface:
public interface Game {
public void setScreen(Screen screen);
public Screen getInitScreen();
}
I understood that the interface methods have no body because they say what classes can do, not how.
Then, when I call the method below from a class that extends the Screen abstract class:
game.getInitScreen();
What exactly this method will return? A new Screen? But there is nothing on this Screen class...no canvas, no SurfaceView...what's the point of such call?
Because, at run-time, there will be a class that provides a concrete implementation of a Screen. Exactly what that class is could be determined with something like game.getInitScreen().getClass().getName()
Related
I'm handling the rendering of my player object inside my Player class. My Player class extends an Entity class which is only responsible for handling physics interactions with other objects for now. My render method in my Player class looks like this:
public class Player extends Entity {
...
#Override
public void render(SpriteBatch batch) {
batch.draw(image, pos.x, pos.y, getWidth(), getHeight());
System.out.println("Player render called");
}
...
}
and the render function inside the Entity class is an abstract.
public abstract void render (SpriteBatch batch);
I have a very similar setup to render my game's map, which works with no issues. However, despite calling super.render(); inside my main class, which extends Game, the render method inside my Player class is not being called. What is going wrong here?
Main class:
public class Main extends Game {
...
#Override
public void create(){
player.create();
}
...
#Override
public void render(){
...
super.render();
}
}
Those are the only significant pieces in the Main class for what I'm trying to accomplish.
I want to call a method of an abstract class from abstract class called by inherit class.
Abstract class:
public abstract class Abstract {
protected void updateMotionY(float deltaTime) {
System.out.println("Abstrcat updateMotionY");
}
public void update(float deltaTime) {
this.updateMotionY(deltaTime);
}
}
Inherit class:
public class Obj extends Abstract {
#Override
protected void updateMotionY(float deltaTime) {
System.out.println("updateMotionY");
super.updateMotionY(deltaTime);
}
#Override
public void update(float deltaTime) {
super.update(deltaTime);
}
}
Main method class:
public static void main(String[] args) {
(new Obj()).update(10.0f);
}
Whenever I try to call new Obj().update() method in main class, it prints "updateMotionY" and "Abstrcat updateMotionY". I want to get only "Abstrcat updateMotionY".
Can anyone tell me how to resolve this problem?
I think you are using abstract in a very wrong way. Your base class should rather look like this:
public abstract class Abstract {
protected abstract void updateMotionY(float deltaTime);
public final void update(float deltaTime) {
this.updateMotionY(deltaTime);
}
}
Notes:
there is no point putting print "is abstract" into an abstract method. The java language has a keyword to express this fact.
subclasses should only be about implementing the abstract method(s) (probably in different ways). You absolutely do not want that subclasses change the implementation of other methods of the base class. Your base class defines a contract - and subclasses should adhere to that (as outlined by the Liskov Substitution Principle).
In other words: put the common parts solely in the base class, and make sure that you have to necessary abstract methods in there to do that. But avoid implementing methods more than once. That only leads to confusion and strange bugs.
(new Obj()).update(10.0f) calls Obj::update which calls Abstract::update which calls this.updateMotionY. Because this is an instance of Obj, this calls Obj::updateMotionY.
This prints "updateMotionY".
This then calls super.updateMotionY(deltaTime) which is Abstract::updateMotionY.
This prints "Abstrcat updateMotionY".
That's the end of the call hierarchy and everything unwinds.
Fundamentally your confusion seems to stem from the fact that this.updateMotionY(deltaTime); in the Abstract class resolves to updateMotionY in the Obj class. That's basically the whole point of polymorphism.
One thing you could do is to add a private method (so that it cant be overridden) which contains the actual implementation, and defer to it:
public abstract class Abstract {
private void motionY(float dt)
{
System.out.println("Abstrcat updateMotionY");
}
protected void updateMotionY(float deltaTime) {
motionY(deltaTime);
}
public void update(float deltaTime) {
motionY(deltaTime);
}
}
If you only want to execute the abstracts superclass' method, then the simple solution is to just call super.updateMotionY instead of super.update in your Obj class
public class Obj extends Abstract {
#Override
protected void updateMotionY(float deltaTime) {
System.out.println("updateMotionY: ");
super.updateMotionY(deltaTime);
}
#Override
public void update(float deltaTime) {
super.updateMotionY(deltaTime);
}
}
You cannot create an instance of Abstract class so you're creating an instance of Obj class. Since your requirement is only to call method of Abstract class then why did you override the method updateMotionY
For your requirement this is what you need to do
Abstract class:
public abstract class Abstract {
protected void updateMotionY(float deltaTime) {
System.out.println("Abstrcat updateMotionY");
}
public void update(float deltaTime) {
this.updateMotionY(deltaTime);
}
}
Inherit class:
public class Obj extends Abstract{
/*#Override
protected void updateMotionY(float deltaTime) {
System.out.println("updateMotionY");
super.updateMotionY(deltaTime);
}*/
#Override
public void update(float deltaTime) {
super.update(deltaTime);
}
}
I have commented the overridden code which will give you the required result.
Also, the answer given by https://stackoverflow.com/users/8466177/steven-laan will also work.
I'm taking a tutorial on building a simple behavior Ai. It's 'brain' class is abstract and contains states as in "running","success","failure". Now in the my ai unit - droid class i have a method to start the brain of the droid up.
public void update(){
if(Routine.getState()==null){
Routine.start();
}
Routine.act(this, board);
}
Now this isn't possible in java because it's a static reference to a non-static method.
The routine abstract class that i'm trying to reference to here goes like this :
public abstract class Routine {
public enum RoutineState{
Success,
Failure,
Running
}
protected RoutineState state;
protected Routine() { }
public void start(){
this.state = RoutineState.Running;
}
public abstract void reset();
public abstract void act(droid droid, board board);
public void succed(){
this.state = RoutineState.Success;
}
public void Fail(){
this.state = RoutineState.Failure;
}
public boolean isSuccess(){
return state.equals(RoutineState.Success);
}
public boolean isFailure(){
return state.equals(RoutineState.Failure);
}
public boolean isRunning(){
return state.equals(RoutineState.Running);
}
public RoutineState getState(){
return state;
}
}
I've tried copying the method to one of the classes that extends the Routine, but that doesn't work either the same problem comes up.
The static requirement is especially difficult on start() and act() that contain this. and are initializers.
I can only make the method update() like it is, in the routine where i initialize the droid and the board it will be acting on - but i don't see this quite like the solution i'd like to have.
For sure, you can reference an abstract class and call its abstract classes, but the object you exactly reference should be an extender of the abstract class.
For example, create a list of different objects, all extending one abstract class.
public abstract class ExAbstract { public abstract void abstractmethod() {...} }
public class ExampleA extends ExAbstract { #Override... }
public class ExampleB extends ExAbstract { #Override... }
...
List<ExAbstract> list = new ArrayList<>();
list.add(new ExampleA());
list.add(new ExampleB());
...
And then, you can call abstract method on it.
for (ExAbstract test : list){
test.abstractmethod();
}
(Or Java 8)
list.forEach(ExAbstract::abstractmethod);
But if object wasn't extending abstact, and it was abstract itself, it would give an error.
EDIT: In your case, with Routine class, you should make a constructor for it, and then make a new object. (I see you have a constructor already...) If you want to use a method without creating an object, use static
In Routine.java:
public Routine(ExampleArg a){
this.a = a;
}
In your Routine call:
Routine r = new Routine(a);
r.start();
I know this is a very simple question, but I have been working in Python for quite a long time and now that I must go back to Java, I seem to have problems changing the chip and wrapping my head around Java's basic polymorphism.
Is it possible to overwrite (implement, to be precise) a class' abstract method in Java using one of the inherited classes as argument?
Let me explain with a very simple example (following the "almost official" example with shapes)
class Shape {}
class Circle extends Shape {}
class Triangle extends Shape {}
abstract class ShapeDrawer {
abstract void draw(Shape s);
}
class CircleDrawer extends ShapeDrawer {
void draw(Circle c){
System.out.println("Drawing circle");
}
}
Is there any way of having Java identifying the draw method in the CircleDrawer class as the implementation of the abstract draw in ShapeDrawer? (The Circle class extends from Shape after all)
Otherwise put: What I'd like is that the draw method of the CircleDrawer class accepts only instances of type Circle, but at the same time, I'd like to tell the Java compiler that the void draw(Circle c) is actually the implementation of the abstract method abstract void draw(Shape s) located in its parent class.
Thank you in advance.
You can solve your problem by means of generics:
public abstract class ShapeDrawer<T extends Shape> {
public abstract void draw(T shape);
}
public class CircleDrawer extends ShapeDrawer<Circle> {
public void draw(Circle circle) { ... }
}
You can't and there is a very good reason why you can't. Take this declaration
public abstract class ShapeDrawer {
public abstract void draw(Shape s);
}
Now take some code that receives a ShapeDrawer and tries to use it:
public void foo(ShapeDrawer drawer, Shape shape) {
drawer.draw(shape);
}
This code should work because the declaration of ShapeDrawer promises that whoever implements it will provide a method called draw() and that method can deal with any Shape.
But if you were allowed to do this:
public class CircleDrawer extends ShapeDrawer {
public void draw(Circle c) {...}
}
That would no longer hold true, your CircleDrawer would be unable to satisfy the promise that it can deal with any Shape.
However imagine this declaration:
public abstract class ShapeCreator {
public abstract Shape create();
}
public class CircleCreator extends ShapeCreator {
public Circle create() {...}
}
Would this work?
Yes, it would(provided that you use Java 5 or later), because unlike the first declaration, what ShapeCreator promises is that it will have a method called create(), which will return a Shape. Since Circle is a Shape, a subclass of ShapeCreator can decide to return only Circles, no promises are broken.
So how do you achieve what you want? See loonytune's answer :)
Not technically, but you can do a hack around it for the functionality you specified.
public abstract ShapeDrawer {
public abstract void draw(Shape s);
}
public CircleDrawer extends ShapeDrawer {
public void draw(Shape s){
if (s instanceof Circle) {
System.out.println("Drawing circle");
}
}
}
No, Java method signatures must match exactly, you can't use subtypes, or you'll overload a method instead of overriding it.
You can return a subtype, but that's it, and return types aren't part of a method signature.
I am a beginner java programmer learning step by step how to code with Java.
I have this code that is an implementation of an interface in java.
Please assist me in debugging it.
Here is the interface:
package ke.munyiri.me;
public interface Hp {
public void scrollUp (int increment);
public void scrollDown (int decrement);
public void rightClick();
public void leftClick ();
}
and here is its implementation:
/**
*
*/
package ke.munyiri.me;
/**
* #author MUNYIRI
*
*/
public abstract class Mouse implements Hp {
char manufacturer;
char type;
static int scroll;
boolean click;
public static void main(String[] args){
public void scrollUp(int increment){
scroll = scroll + increment;
System.out.println("The mouse is scrolling up");
}
public void scrollDown (int decrement){
int scrollDown = scroll - decrement;
System.out.println("The mouse is scrolling down");
}
public void rightClick(){
boolean rightClick = true;
System.out.println("The mouse is right Clicking");
}
public leftClick(){
boolean leftClick = true;
System.out.println("The mouse is left Clicking");
}
}
}
You have compile errors in your code. You can't declare methods inside a another method. In your code You have override interface methods inside your main method. Take them out of the main method scope. Like this
public abstract class Mouse implements Hp {
char manufacturer;
char type;
static int scroll;
boolean click;
public static void main(String[] args){
}
public void scrollUp(int increment){
scroll = scroll + increment;
System.out.println("The mouse is scrolling up");
}
public void scrollDown (int decrement){
int scrollDown = scroll - decrement;
System.out.println("The mouse is scrolling down");
}
public void rightClick(){
boolean rightClick = true;
System.out.println("The mouse is right Clicking");
}
public void leftClick(){
boolean leftClick = true;
System.out.println("The mouse is left Clicking");
}
}
There are issues in your code. You can't declare another method inside a method.
Change your structure
public MyClass implements MyInterface{
public static void main(String[] args){
}
public void myMethod1(){
}
}
So you defined an Interface and an abstract class but no concrete class. Your implementation can't be used on it's own but requires a further 'implementation' class or you could remove the abstract keyword from your class definition. This keyword isn't needed as you don't have any abstract methods in your class.
Well and as others have pointed out, your main method (which you don't need) misses it's closing bracket.
Before Learning the concept of interface , You should have to learn basic . i.e you cannot have methods implemented inside another method, And to Know about interface first you should have knowledge about what is Abstract and Concrete.
ABSTRACT CLASS
public abstract class GraphicObject {
// declare fields
// declare nonabstract methods
abstract void draw();
}
An abstract class is a class that is declared abstract—it may or may not include abstract methods. Abstract classes cannot be instantiated, but they can be subclassed.
An abstract method is a method that is declared without an implementation.
CONCRETE CLASS
An abstract class is meant to be used as the base class from which other classes are derived. The derived class is expected to provide implementations for the methods that are not implemented in the base class. A derived class that implements all the missing functionality is called a concrete class .
public class Graph implements GraphicObject{
public void draw()
{
//defination
}