Is it possible to create an array of static classes in Java?
For example:
SceneObject[] scenes = {Loading.class, Menu.class};
// Loading and Menu extend SceneObject
We need to call static methods via the array, not instantiate them.
EDIT:
The following is what we are trying to accomplish. We could alternatively use many switches, but it sounds redundant to add every object to every switch in every method.
package net.bitworm.gameengine;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import net.bitworm.scenes.*;
public class SceneController {
public enum Scene{
LOADING_SCENE,
MENU,
SCENE_1
}
public static SceneObject[] scenes = {new Loading(), new Menu()};
public volatile static Scene currentScene = Scene.LOADING_SCENE;
public static void setScene(Scene newScene){
currentScene = newScene;
System.out.println("Switched to " + currentScene.toString());
}
public static void update(GameContainer container, int delta){
scenes[currentScene.ordinal()].update(container, delta);
}
public static void render(GameContainer container, Graphics g){
scenes[currentScene.ordinal()].render(container, g);
}
public static void mouseMoved(int oldx, int oldy, int newx, int newy){
scenes[currentScene.ordinal()].mouseMoved(oldx, oldy, newx, newy);
}
public static void mousePressed(int button, int x, int y){
scenes[currentScene.ordinal()].mousePressed(button, x, y);;
}
public static void mouseReleased(int button, int x, int y){
scenes[currentScene.ordinal()].mouseReleased(button, x, y);
}
public static void mouseWheelMoved(int change){
scenes[currentScene.ordinal()].mouseWheelMoved(change);
}
public static void keyPressed(int key, char c){
scenes[currentScene.ordinal()].keyPressed(key, c);
}
public static void keyReleased(int key, char c){
scenes[currentScene.ordinal()].keyReleased(key, c);
}
You need to differentiate between classes and objects. For example, you might have:
SceneObject[] scenes = { new Loading(), new Menu() };
or
Class[] classes = { Loading.class, Menu.class };
It's not clear from your question which you mean, but hopefully that should satisfy either case... note that you can't have generic arrays, so with the Class[] you can't specify that each class must extend SceneObject.
EDIT: Now we've got a bit more information, it sounds like you've got this:
abstract class SceneObject {}
class Menu extends SceneObject {
static void foo() {
}
static void bar() {
}
}
class Loading extends SceneObject {
static void foo() {
}
static void bar() {
}
}
The two foo methods here are completely unrelated - you can't use polymorphism to call them, because they're static methods. If you want to use polymorphism - i.e. call a method knowing which signature you want to call, but with an implementation that depends on the target of the call - you need instance methods:
abstract class SceneObject {
abstract void foo() {
}
abstract void foo() {
}
}
class Menu extends SceneObject {
#Override void foo() {
}
#Override void bar() {
}
}
class Loading extends SceneObject {
#Override void foo() {
}
#Override void bar() {
}
}
Then you can write:
SceneObject[] scenes = { new Loading(), new Menu() };
...
for (SceneObject scene : scenes) {
scene.foo();
scene.bar();
}
Other than making an array of classes that extend SceneObject, we can make a container for these objects:
//a container that holds only the classes of SceneObject
public class ClassBox<T extends SceneObject> {
private Class<T> theClass;
public ClassBox(Class<T> theClass) {
this.theClass = theClass;
}
public Class getTheClass() { //'getClass()' method is reserved, we use a more unique name
return theClass;
}
}
//testing classes
abstract class SceneObject {}
class Loading extends SceneObject {}
class Menu extends SceneObject {}
class noExtends1 {}
//testing
public void main() {
ClassBox[] scenes = {new ClassBox<>(Loading.class), new ClassBox<>(Menu.class)}; //these classes extend SceneObject
// ClassBox[] sceneserror = {new ClassBox<>(Loading.class), new ClassBox<>(noExtends1.class)}; //gives error because 2nd array elem is not extending, so I commented it
Log.v("custom log.v call", String.valueOf(Loading.class));
Log.v("custom log.v call", String.valueOf(Menu.class));
Log.v("custom log.v call", String.valueOf(scenes[0].getTheClass()));
Log.v("custom log.v call", String.valueOf(scenes[1].getTheClass()));
//result is:
//V/custom log.v call: class me2.iwanttobealeader.pie$Loading
//V/custom log.v call: class me2.iwanttobealeader.pie$Menu
//V/custom log.v call: class me2.iwanttobealeader.pie$Loading
//V/custom log.v call: class me2.iwanttobealeader.pie$Menu
}
This answer has the benefit of specifying multiple criteria of inheritance for example:
public class ClassBox<T extends Fragment & FR_DbRequests.SynchListener>
//now it must implement the abstract class SyncListener and extend Fragment
But also the disadvantage of instantiating an additional object ,namely the container+variable containing the class, instead of just the variable containing the class.
Related
I have 2 subclass extended from the same superclass, and 3 objects will be created and store into an array of the superclass. I am wondering how can I call a subclass method by a superclass object, I try to convert the data type from Ship to CruiseShip or CargoShip but it does not work. If anyone can help I will be appreciated that.
Here is the superclass:
public class Ship {
private String name;
private String year;
public Ship() {}
public Ship(String n,String y) {...}
public void setName() {...}
public void setYear() {...}
public void getName() {...}
public void getYear() {...}
}
These two subclass basically are there same.
public class CruiseShip extends Ship {
private int passenger;
public CruiseShip() {}
public CruiseShip() {...}
public void setPassenager() {...}
public int getPassenager() {...}
public Strting showInfo() {this.getName()...etc}
}
public class CargoShip extends Ship {
private int capacity;
public CargoShip() {}
public CargoShip() {...}
public void setCapacity() {...}
public int getCapacity() {...}
public Strting showInfo() {this.getName()...etc}
}
Here is the main method:
public class report {
public static void main(String[] args) {
Ship[] shipList new Ship[3];
for (int i=0;i<3;i++) {//using for loop to create 3 objects randomly and pass into array}
for (int i=0;i<3;i++) {
if (shipList[i] instanceof CruiseShip) {
((CruiseShip)shipList[i]).showInfo(); //This way is not work.
}
else {
((CargoShip)shipList[i]).showInfo(); //This way is not work.
}
Take a look at Polymorphisms and Late Bindig. Basically late binding says that the appropriate method to be executed is determined at runtime based on the actual type of the object. So
class Ship {
public String showInfo() {return "I'm a ship";}
}
class CruiseShip extends Ship {
public String showInfo() {return "I'm a cruiseShip";}
}
class CargoShip extends Ship {
public String showInfo() {return "I'm a cargoShip";}
}
class Main {
public static void main(String argv[]) {
Ship[] ships = new Ship[]{new Ship(), new CargoShip(), new CruiseShip()};
for (Ship ship: ships) {
System.out.println(ship.showInfo());
// I'm a ship
// I'm a cargoShip
// I'm a cruiseShip
}
}
}
I'm not sure about the question you are trying to ask,
but this may answer the question you did ask.
public abstract class Ship
{
public final boolean hoot()
{
return implementHoot();
}
protected abstract boolean implementHoot();
}
public class BlamShip
extends Ship
{
protected boolean implementHoot()
{
return true;
}
}
Subclass methods (overrides) are automatically called even if the reference is of type super-class. You don't have to do anything.
public class MyTest {
public static void main(final String[] args) {
B b = new B();
b.print();
}
}
class A {
private final int x = 5;
protected int getX() {
return x;
}
public void print() {
System.out.println(getX());
}
}
class B extends A {
private final int x = 10;
#Override
protected int getX() {
return x;
}
}
In this example, I need to print subclass value in the parent class.
It is working fine. No issue.
Now it is printing 10.
But I do not want to define that property in the parent class A.
Because in this example this x datatype is very simple. So no issue.
But in real-time I want to use other datatype which may be another Class variable or List<something> which have huge data.
So ultimately I do not wish to store that value in Class A.
Because it is redundant data. It will slow down in my Hibernate thing.
Please let me know, how to achieve this without declaring variable in parent class. But I still need to use subclass variable in parent class.
make abstract your class A and the getX(); method.
public class Test {
public static void main(final String[] args) {
B b = new B();
b.print();
}
}
abstract class A {
protected abstract int getX();
public void print() {
System.out.println(getX());
}
}
class B extends A {
private final int x = 10;
#Override
protected int getX() {
return x;
}
}
and override the toString method in place of your print method
#Override
public String toString() {
return String.valueOf(getX());
}
the final code
public class Test {
public static void main(final String[] args) {
B b = new B();
System.out.println(b);
}
}
abstract class A {
protected abstract int getX();
#Override
public String toString() {
return String.valueOf(getX());
}
}
class B extends A {
private static final int X = 10;
#Override
protected int getX() {
return X;
}
}
you could also define as static your x variable
But as say Andrew Tobilko you can consider also to use an interface if A doesn't represent a stateful entity.
It's certainly the best solution for your case, mix the use of an interface and an abstract class
public class Test {
public static void main(final String[] args) {
B b = new B();
System.out.println(b);
}
}
interface MyInterface {
int getX();
}
abstract class A implements MyInterface{
#Override
public String toString() {
return String.valueOf(getX());
}
}
class B extends A {
private static final int X = 10;
#Override
public int getX() {
return X;
}
}
You need the getX within the parent class, but you don't have information enough to implement this method there.
You can declare this class as abstract and mark the method with abstract as well. Doing that, you are handing the responsibility of method implementation over its subclasses and preventing from parent field declaration.
If the A doesn't describe any state (only actions/methods), you should consider replacing it with an interface. At the current state, it is the case.
You could make the parent class abstract, eliminate the property in the parent class, make getX() abstract, and then leave print() as concrete. Then just use the concrete implementation of getX() in the child class.
interface Example{
void methodExample();
}
class Y{
void do(Example x) { }
}
class X{
void methodX() {
Y y = new Y();
y.do(new Example() {
public void methodExample() {
System.out.println("methodExample");
}
});
}
}
I want to create a main class and call methodExample. How would I do that?
Since your class implements Example interface, and because void methodExample() is present on that interface, all you need to do is to reference the object by its interface, and call its method:
class Y{
public void doIt(Example x) {
x.methodExample();
}
}
The above works, because objects of all classes implementing Example, including all anonymous implementations, are known at compile time to implement methodExample().
If you don't have access to class Y then, the only way to do is to override doIt() itself first, using anonymous inner class and then, call the overridden method, e.g.:
class X {
void methodX() {
Y y = new Y() {
#Override
void doIt(Example x) {
x.methodExample();
}
};
y.doIt(new Example() {
public void methodExample() {
System.out.println("methodExample");
}
});
}
}
To call this, you can simply do:
public static void main(String[] args) throws Exception {
X x = new X();
x.methodX();
}
I also done this example creating object for both class and call the method is there anyway to override the baseclass?
class Car {
void Max() {
System.out.println("Audi");
}
}
class Speed extends Car {
void Max() {
System.out.println("300");
}
public static void main(String args[]) {
Speed s=new Speed();
s.Max();
}
}
At the risk of being called a "give me the repz" type person...hopefully this helps:
This first class is a BaseClass, you can create a new one by writing:
BaseClass myBaseClass = new BaseClass();
public class BaseClass {
private int aNumber; //This global variable is private and so cannot be overwritten.
int anotherNumber; //This global variable is package scope and so can be accessed by sub-classes in the same package.
protected yetAnotherNumber; //This variable is accessible by any subclasses.
public int numberAvailableToEveryone; //This global variable is accessible to anyone and everyone.
public BaseClass() {} //This is a constructor (no return type)
private void myPrivateMethod() {} //This method cannot be overwritten
void packageScopeMethod() {}
protected void thisMethodCanBeOverwrittenBySubClasses() {}
public void theWorldCanCallMe() {} //extendable to the world, not much different than protected scope tbh
}
Now, to overwrite a method you can create an anonymous class like so:
BaseClass myAnonymousClass = new BaseClass() {
public void theWorldCanCallMe() {
//in here you can override the method to do whatever you want.
}
}
or you could define a subclass like so:
public class SubClass extends BaseClass {
#Override
public void tehWorldCanCallMe() {
//again your new code goes here
}
}
and then instantiate it like so:
SubClass myClassThatOverridesAMethod = new SubClass();
A car example closer to your code:
class Car {
private String name;
int speed = 100;
Car(String name) { //This is the base classes constructor
this.name = name;
}
String max() {
return speed;
}
void run() {
System.out.println(name);
System.out.println(max()); //will print the base speed unless overridden
}
}
class Audi extends Car {
Audi() {
super("Audi")
}
}
class Speed extends Car {
Speed() {
super("Speed");
}
#Override
String max() {
speed = 300;
return speed;
}
public static void main(String args[]) {
Speed s=new Speed();
s.run();
}
}
i'm trying to write anonymous inner class
interface Face{
void seeThis(String what);
}
class Eyes {
public void show(Face f){}
}
public class Seen {
public void test() {
Eyes e = new Eyes();
e.show(new Face() {
#Override
public void seeThis(String what){
System.out.print(what);
}
});
public static void main(String[] args) {
Seen s = new Seen();
s.test();
}
}
How to call seeThis() and how to pass parameter to it?
Method seeThis() belongs to Face class, which instance is anonymous and thus cannot be reached without storing reference to it. If you want to store a reference, you can do this in the following way:
public class Seen {
public Face face;
....
this.face = new Face() { ... };
e.show(this.face);
And then,
Seen s = new Seen();
s.face.seeThis();
Now, regarding passing the parameter. You have two options - declare parameter outside of anonymous class and make it final in order to be reachable by this anonymous class, or replace anonymous class with normal one and pass the parameter to its constructor:
Approach one:
final int parameter = 5;
...(new Face() {
#Override
public void seeThis() {
System.out.println(parameter);
}
});
Approach two:
public class MyFace implements Face() {
private final int parameter;
public MyFace(int parameter) {
this.parameter = parameter;
}
#Override
public void seeThis() {
System.out.println(parameter);
}
}
Then,
...
e.show(new MyFace(10));