I've to create a simple self-made ActiveRecord class for my project.
Only stuck on the problem that I have a getModel() in my Player class, which is being extended by a ActiveRecord class.
When I want to use the getModel() method from my ActiveRecord class, I cant use it cause it's not the same type. I don't want to reference Player here, because I want to use multiple models.
Anyone has a solution?
Ok so I got something up:
abstract class ActiveRecord<T> {
private T model;
public T getModel() {
return this.model;
}
}
public class Player extends ActiveRecord<Player> {
}
public class Event extends ActiveRecord<Event> {
}
But when I try to output this.model in my ActiveRecord class, it return null.
What is wrong here?
Your method definition needs to do something like this
public Class<? extends ActiveRecord> getModel();
Meaning of this is that the return type is of class that extends ActiveRecord. When you do this to the child it would return Player.class as Player extends ActiveRecord.
A brief note if getModel return an object of that class then you should remove Class from the method function
public <? extends ActiveRecord> getModel();
So if I understand well you have a super class called ActiveRecord and a subclass Player, which has a method getModel.
If you want to use ActiveRecord as reference type then you need to have a getModel method in that class as well if you want to access that method. If you are never going to instantiate an ActiveRecord as such you can make it abstract and define the getModel method abstract. If you don't have any implementation logic in ActiveRecord you could make it an interface as well.
public abstract class ActiveRecord {
public abstract Model getModel();
}
public class Player extends ActiveRecord {
#Override
public Model getModel() {
...
}
}
You're making life way too hard for yourself. Java already does reflection for you.
class Parent {
// class content
}
class ChildA extends Parent {
// class content
}
class ChildB extends Parent {
// class content
}
Parent firstInstance = new ChildA();
Parent secondInstance = new ChildB();
Class typeOfFirst = firstInstance.getClass();
Class typeOfSecond = secondInstance.getClass();
As for your null pointer error, in Java (Unlike c++ for example) you have to explicitly initialise every variable with new. Just having private T model; doesn't create an instance of it.
Related
I have a class called Car, and an extention of Car, called Mazdamx5. Can I create a class that extends Mazdamx5 that contains the properties of Car, but also contains the modified or overridden properties of Mazdamx5, or will this only cause complications? Oh, yeah, forgot the important part. How do I do all this with Car and Mazdamx5 in a different package than my new extention? By import?
You can certainly have class hierarchies like this, but you should consider your design implications a bit closer. Having deeply nested inheritance like that isn't necessary in a lot of cases.
If you want each class to have shared fields, then use protected instead of private for their declaration.
This is entirely legal:
public class Car {
}
public class Mazdamx5 extends Car {
}
public class SomeOtherCar extends Mazdamx5 {
}
Try it out. Perfectly valid to create another class that extends Mazdamx5.
I provide the code example
class Car{
void carDrive() {
S.O.P("car drive");
}
}
class Mazdamx5 extends Car{
void drive() {
S.O.P("drive 2");
}
}
class Car2 extends Mazdamx5 {
void drive() {
S.O.P("Car 2 drive");
}
}
In this case, this class Car2 extends Mazdamx5, overrides method properties of Mazdamx5(drive method), and contins method properties of car(carDrive)
I'm having a bunch of classes that I can not change; all these classes have a common ancestor (other than Object) that declares and implements the majority of their properties and methods.
Let's say, we have an inheritance tree like this (for illustration only):
class Vehicle
class Bicycle extends Vehicle
class Skateboard extends Vehicle
class Boat extends Vehicle
class Car extends Vehicle
class Aircraft extends Vehicle
class Jetplane extends Aircraft
class Helicopter extends Aircraft
...
class Truck extends Vehicle
...
While class Vehicle is actually more like an abstract class (it is not really, but it is never instantiated on its own behalf), objects of class Aircraft are created occasionally.
Now the point: the objects can have interrelationships that are not reflected by the classes. Since it is quite a bouquet of classes and the collection is subject to change every once in a while, it is not practical to maintain a subclass for each of the classes that implement the missing behavior.
My approach is therefore to have one class that serves as a wrapper for the above classes.
The constructor takes as a parameter the class of the respective object, which is then instantiated using reflection.
class VehicleW
{
// fields
public boolean isInitialized=false;
private Vehicle fVehicle;
...
// constructors
public VehicleW(Class aClass, ...)
{
Class VehicleClass = Vehicle.class;
if (!VehicleClass.isAssignableFrom(aClass))
return;
// <the reflection magic here>
...
// and on success mark this object as usable
isInitialized=true;
}
}
A constructor without arguments doesn't really make sense here. But now class Aircraft and its subclasses want some extra properties, so I thought I could establish a class AircraftW extends VehicleW that takes care of them.
The modification then looks like this:
// fields
private Aircraft fAircraft;
// constructors
public AircraftW(Class aClass, ...)
{
Class AircraftClass = AirCraft.class;
if (!AircraftClass.isAssignableFrom(aClass))
return;
// <the reflection magic here>
...
// and on success mark this object as usable
isInitialized=true;
}
But this fails, because Java intelligently inserts a call to the parameterless constructor of the ancestor, which is not present (and doesn't make sense, as already said).
It also doesn't make sense to call the parameterized super(), because I initialize a field of class Vehicle then. Okay, I can later in my AircraftW() just set that field to null, but that doesn't seem right.
Is there a way around this? Or am I taking an absolutely wrong approach? I thought about generics, but I can't seem to find a point using it. Interfaces? I'm not that much of a Java expert, so any recommendations are welcome.
Edit (not unsolved (to avoid the term solved)) Well, below you find a working program. I can't put it down as an answer, because Thomas led me to this code... with his answer... which I accepted as the solution... I can't see what's wrong with that.
Thanks, Thomas, for pointing me in the right direction.
For the sceptical, here the complete source code of a test program:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class Vehicle { public Vehicle(){} }
class Bicycle extends Vehicle { public Bicycle(){} }
class Skateboard extends Vehicle { public Skateboard(){} }
class Boat extends Vehicle { public Boat(){} }
class Car extends Vehicle { public Car(){} }
class Aircraft extends Vehicle { public Aircraft(){} }
class Jetplane extends Aircraft { public Jetplane(){} }
class Helicopter extends Aircraft { public Helicopter(){} }
class Truck extends Vehicle { public Truck(){} }
class VehicleW
{
protected Vehicle fVehicle=null;
public boolean isInitialized=false;
public VehicleW(Class aClass)
{
if (checkVehicle(aClass))
if ((fVehicle=makeVehicle(aClass))!=null)
isInitialized=true;
}
protected boolean checkVehicle(Class aClass)
{
Class tClass = Vehicle.class;
return (tClass.isAssignableFrom(aClass));
}
protected Vehicle makeVehicle(Class aClass)
{
Vehicle tVehicle = null;
System.out.format("trying to create %s\n",aClass.toString());
Constructor c;
try
{
c=aClass.getConstructor();
}
catch(NoSuchMethodException e)
{
System.out.format(" no constructor found\n");
return null;
}
try
{
tVehicle=(Vehicle)c.newInstance();
}
catch(InvocationTargetException e)
{
System.out.println(e.toString());
}
catch(InstantiationException e)
{
System.out.println(e.toString());
}
catch(IllegalAccessException e)
{
System.out.println(e.toString());
}
return tVehicle;
}
public Vehicle getVehicle()
{
if (!isInitialized)
return null;
return fVehicle;
}
public Class getWClass()
{
if (!isInitialized)
return null;
return fVehicle.getClass();
}
}
class AircraftW extends VehicleW
{
public AircraftW(Class aClass)
{
super(aClass);
/*
Class tClass=Aircraft.class;
if (!tClass.isAssignableFrom(aClass))
return;
isInitialized=true;
*/
}
#Override
protected boolean checkVehicle(Class aClass)
{
Class tClass = Aircraft.class;
return (tClass.isAssignableFrom(aClass));
}
}
class program
{
public static void tellme(VehicleW vx)
{
String s = "failed";
if (vx.getVehicle()!=null)
s="succeeded";
System.out.format(" making %s for %s %s\n",
vx.getWClass(),vx.getClass(),s);
}
public static void main(String[] args)
{
VehicleW v1, v2, v3;
AircraftW a1, a2, a3;
v1=new VehicleW(Bicycle.class);
tellme(v1);
v2=new VehicleW(Boat.class);
tellme(v2);
v3=new VehicleW(Helicopter.class);
tellme(v3);
a1=new AircraftW(Helicopter.class);
tellme(a1);
a2=new AircraftW(Aircraft.class);
tellme(a2);
a3=new AircraftW(Truck.class);
tellme(a3);
return;
}
}
and the output:
trying to create class Bicycle
making class Bicycle for class VehicleW succeeded
trying to create class Boat
making class Boat for class VehicleW succeeded
trying to create class Helicopter
making class Helicopter for class VehicleW succeeded
trying to create class Helicopter
making class Helicopter for class AircraftW succeeded
trying to create class Aircraft
making class Aircraft for class AircraftW succeeded
making null for class AircraftW failed
This sounds a lot like the factory pattern so you might want to look into that.
What you basically would do is something like this:
class VehicleFactory {
public static Vehicle createAircraft( /*Aircraft specific parameters*/) {
//build and return Aircraft, you can call your reflection magic here
}
public static Vehicle createBoat( /*Boatspecific parameters*/) {
//build and return Boat, you can call your reflection magic here
}
}
Additionally, you might want to look into the builder pattern.
In your approach there are several issues:
Prematurely returning from a constructor would still kept the created object, it might just not be properly initialized (you're using an attribute to signal full initialization but what do you do with uninitialized objects besides removing them? In that case initialized should not be a property of the objects or wrappers themselves).
If you have such a high number of subclasses you might want to check what the differences are. It might be a more flexible approach to use composition instead of inheritance.
Example of the last point:
class Vehicle {
VehicleType type; //e.g. Aircraft, Boat, Car
Set<Features> features; //e.g. 2 wheels, 4 wheels, wings etc.
Behavior behavior; //Class to implement specific behavior, depending on your needs
}
class AircraftBehavior extends Behavior {
void fly() {
//implements flying mechanic
}
//method overridden/implemented from Behavior
#Override
void move() {
fly();
}
}
//create an aircraft
Vehicle aircraft = new Vehicle( VehicleType.AIRCRAFT, new HashSet<Feature>(new WingsFeature()), new AircraftBehavior());
The last part would also be predestined for using the factor or builder pattern.
When child class can not full fill the contract of constructor with parent class. Then at same place exists a design defect.
The issue/reason can be that the child class is not valid as a child class or the parent class has to many functionalities.
For your example is really hard to tell what is breaking the contract. But the best and most flexible thing to work with are interfaces.
You claim that you are not an expert in Java. Interfaces are just a concept in Object Oriented programming in case you look for any carrier in this area you should be familiar with them. SO this might the time for you to learn more about interfaces and software design.
I'm working in some GWT application in which I have a hierarchy where I have an abstract presenter with some common functionality of derived classes. Something like:
public abstract class MyAbstractPresenter<T extends MyAbstractPresenter.CustomDisplay> extends Presenter<T>
{
public interface CustomDisplay extends View
{
//some methods
}
//I want to inject this element
#Inject
private CustomObject myObj;
public MyAbstractPresenter(T display)
{
super(display);
}
}
All the subclasses get injected properly. However, I want to be able to inject that particular field without having it to add it in the constructor of the subclasses. I tried to do field injection as you see , but it doesn't work as it is the subclasses the one that get injected.
Is there a proper way to achieve this Injection without letting the subclasses know about the existence of the field?
Apparently, as for the moment, there is no support for this type of behavior in GIN. A workaround would be to inject the required field in the concrete classes constructors even when they don't need it. Something like:
public abstract class MyAbstractPresenter<T extends MyAbstractPresenter.CustomDisplay> extends Presenter<T>
{
public interface CustomDisplay extends View
{
//some methods
}
//I wanted to inject this element
private final CustomObject myObj;
public MyAbstractPresenter(T display, CustomObject obj)
{
super(display);
myObj = obj;
}
}
Then in any class that extends this abstract implementation, I would have to pass it on construction.
public abstract class MyConcretePresenter extends MyAbstractPresenter<MyConcretePresenter.CustomDisplay>
{
public interface CustomDisplay extends MyAbstractPresenter.CustomDisplay
{
//some methods
}
#Inject //it would get injected here instead.
public MyConcretePresenter(CustomDisplay display, CustomObject obj)
{
super(display, obj);
}
}
I have a class component
abstract class Component{
private componentType m_type;
public Component(componentType type)
{
m_type = type;
}
}
and 2 subclasses
class AmplifierComponent extends Component{
public AmplifierComponent()
{
super(componentType.Amp);
System.out.print(this.m_type);
}
}
class AttenuatorComponent extends Component{
public AttenuatorComponent()
{
super(componentType.Att);
System.out.print(this.m_type);
}
}
my problems are:
1.i can't instantiate any kind of component because m_type isn't visible(what that means?)
2.i need to make an array of all the components the user has insert to the chain. i can't manage to create an array of Component class.
can someone help me with the design?
or with some workarounds?
Thanks in advance
I don't understand why you need the type member. This looks redundant. You can instead simply do:
abstract class Component{
}
class AttenuatorComponent extends Component{
public AttenuatorComponent() {
// calls the default super constructor
}
}
and rely on polymorphism for your classes to behave appropriately. Having a type member to identify a hierarchy type is unnecessary when you've declared the corresponding classes. If you do have a member variable that is required to be visible in subclasses but not by clients, then you can make it protected rather than private.
Component could be an interface if there's no functionality/data associated with it.
Your array declaration would look like
Component[] components = new Component[20];
components[0] = new AttenuatorComponent();
Polymorphism would mean that you can iterate through this array of components, calling appropriate methods declared on (but not necessarily implemented by) the Component, and the suitable subclass methods would be called.
Set m_type to protected to be able to see it from child classes.
abstract class Component {
private componentType m_type;
public Component(componentType type)
{
m_type = type;
}
public componentType getType()
{
return this.m_type;
}
}
class AmplifierComponent extends Component{
public AmplifierComponent()
{
super(componentType.Amp);
System.out.print(super.getType());
}
}
class AttenuatorComponent extends Component{
public AttenuatorComponent()
{
super(componentType.Att);
System.out.print(super.getType());
}
}
That way you can read m_type, but cannot change it.
You could also make the getType() command protected, so it is only reachable through the classes which inherit it.
I have this super class which extends from another class
public abstract class AbstractDOEMessageFinderAction extends BasicObjectFinder {
public Object performBasicSearch() {
// works fine because getQuery is defined in BasicObjectFinder
return getQuery();
}
The other class is ISIRFinderAction which extends from AbstractDOEMessageDashboardAction
ISIRFinderAction extends AbstractDOEMessageDashboardAction {
// My aim is to make sure this method works so that I will make
// the super class's performBasicSearch() method abstract.
public Object performBasicSearch() {
// this one doesnt even compile but it extends AbstractDOEMessageDashboardAction
// which in turn extends BasicObjectFinder
return getQuery();
}
}
Am I missing something? Why is getQuery not working. I thought it would search it in the class hierarchy.
The second class extends AbstractDOEMessageDashboardAction not AbstractDOEMessageFinderAction.
Does AbstractDOEMessageDashboardAction also extend BasicObjectFinder?
(Note, AbstractDOEMessageDashboardAction is ofcourse not the same as AbstractDOEMessageFinderAction).