How to call a method in a class hierarchy? - java

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).

Related

Java : generic type with type parameters?

I have a class like this :
public class MyClass <T extends Model1, X extends Model2> {
private CommonMessage<T,X> someMethod() {
....
}
}
Now I have a customized message type MyMessage extends CommonMessage, so I want to know how to have generic type that still having T and X as parameters ? For example :
public class MyClass <M extends CommonMessage, T extends Model1, X extends Model2> {
private M<T,X> someMethod() {
....
}
}
Short answer:
First of all as CommonMessage is generic, extending it in a non-generic way is very bad so you should have done M extends CommonMessage<T, X> And this way because type parameter passed to CommonMessage at class declaration you should not mention this parameter type again at method return type so method return type should be M.
Long answer:
I know you do know this definitions but sometimes we as human forget simple things. First we should consider what generics are created for, with generics we can create classes with different parameter types, this parameter types will be provided when they are extended by another class or when we create new instance of them with new() operator, so when we are writing our class we don't know the exact type for those parameter and we want to delay this decision until later, it is contradictory to something you are doing in your class because here your method is private and you can't change its implementation in your child class(the class which inherited from your class). But know we can change your implementation to something like this which will be compiled well:
public class MyClass<M extends CommonMessage<T, X>, T extends Model1, X extends Model2> {
private M method1(){
...
}
}
public class CommonMessage<T, X>{
}
public class MyMessage<T, X> extends CommonMessage<T, X>{
}
public class Model1{
}
public class Model2{
}
although this implementation will be compiled the problem is that when you are writing your private method(method1) you don't know what is the type of M at the time of writing this class because it will be passed when we want to create new instance of this class or when we inherit another class from this class. so what type of Object do you want to create and return in your method1? the only thing that you know here is that its type is M which extends CommonMessage but you don't know what the exact type of M is at the time of writing your private method(method1)!
And on the top of that you can't delegate this decision to your subclass(because this method is private). Now the question is that why it is allowed and compiled well when we don't know the exact type of M? for a moment forget this question I will make it clear after explaining correct approach. so what is the correct approach? Think about it, the person who write subclass does know exactly what the type of parameter M is and they can create appropriate instance of M in implementation of method1 to return from this method. so why not delegate this decision to subclass and making this method abstract? This completely make senses. in a nutshell we have some implementation like this:
public abstract class MyClass<M extends CommonMessage<T, X>, T extends Model1, X extends Model2> {
public abstract M method1();
}
public class CommonMessage<T, X>{
}
public class MyMessage<T, X> extends CommonMessage<T, X>{
}
public class Model1{
}
public class Model2{
}
now lets get back to our question why first program that I suggested to you compiled well? why we are allowed to have private method that its return type is generic that will be passed at instanciation or inheritance time?
because there are a lot of situations that make it correct and appropriate.
one situation is that our private method call another public method which return the appropriate type, like this:
public abstract class MyClass<M extends CommonMessage<T, X>, T extends Model1, X extends Model2> {
private M method1(){
return method2();
}
abstract M method2();
}
public class CommonMessage<T, X>{
}
public class MyMessage<T, X> extends CommonMessage<T, X>{
}
public class Model1{
}
public class Model2{
}

How do I augment the constructor of a child class?

I have a class that extends another class. I need to run additional code in the constructor of my child class. How do I do this?
//MyClass.class
//This is what i want to do
public class MyClass extends BaseClass {
constructor() {
super(); // EDIT (thanks)
// stuff?
}
}
Please help.
should be:
/MyClass.class
//This is what i want to do
public class MyClass extends BaseClass {
MyClass() {
super(); // no need for constructor here, just super()
// stuff?
}
}
Simply call super(). This will call the super class's constructor. See Can an abstract class have a constructor?

Generic interface in Java

Is it possible to have something like that? I'm trying to force any class extending this one to implement an interface that extends BaseHomeListView
public abstract class BaseHomeFragment<T extends BaseHomeListView> extends BaseRecyclerViewFragment implements T
I'm trying to implement MVP pattern in Android for some fragments which only display lists.
So basically the view has to rendersList, that's why it is in the base interface, however I still want to allow each fragment to have add more methods as they need
public interface BaseHomeListView<T> extends LoadDataView, LoadMoreView<T> {
void renderList(Collection<T> items);
}
The only sensible thing you can do is the following:
public abstract class BaseHomeFragment<T>
extends BaseRecyclerViewFragment
implements BaseHomeListView<T>
And then if you have something like
public interface FancyHomeListView extends BaseHomeListView<Fancy> {
}
Then you can just have a fragment like
public class FancyHomeFragment
extends BaseHomeFragment<Fancy>
implements FancyHomeListView {
//...
}
Assuming you want to change the implementation of the interface's methods in every subclass, but not the arguments of such methods, or decouple the business code of the fragment's views, it would be more reasonable to add a generic instance of such interface as a member of your fragment class.
public abstract class BaseHomeFragment<T extends BaseHomeListView> extends BaseRecyclerViewFragment {
/*the class information can be used against a factory method to get an instance of the interface*/
private Class<T> myInterfaceClass;
protected T myInterfaceInstance;
public void setMyInterFaceInstance(T instance){
myInterfaceInstance = instance;
}
public BaseHomeFragment(Class<T> initializeClass){
myInterfaceClass = initializeClass;
myInterfaceInstance = interfaceFactory(myInterfaceClass);
}
//TODO: use the interface instance.
}
now, in every subclass, you'll need to add the interface subclass as an argument to super:
public class myAppHomeFragment extends BaseHomeFragment<AppHomeListView>{
public myAppHomeFragment(){
super(AppHomeListView.class);
setMyInterFaceInstance(new AppHomeListView{
//Method overloading
});
}
//TODO: Use the interface's new methods if necessary.
}
a little example of your factory method:
public static <T extends BaseHomeListView> T interfaceFactory(Class<T> aClass){
if(aClass.getSimpleName().equals("someclass")){
//TODO
return new someclass;
}
return null;
}

Get child model from parent class

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.

Java Generics: Require generic to be subclass of a certain type

I have an abstract generic class:
public abstract class AbstractMessageHandler<T extends AbstractMessageHandler>
{
public abstract List<String> getTypesOfMessages();
public abstract void handleMessage(String message, CometClient client);
public T setResponseValues(AbstractMessage request, T response )
{
response.setCompanyId(request.getCompanyId());
response.setMessageGroup(request.getMessageGroup());
response.setUserId(request.getUserId());
response.setTimeStamp(AbstractMessage.getCurrentTimeStamp());
return response;
}
}
I need the generic subclass to be a subclass of this class. In otherwords, the generic must be a subclass of AbstractMessageHandler. This however gives me compilation issues. Can anyone let me know what I am doing wrong?
Thanks
You need to follow the example of the Enum class:
public abstract class AbstractMessageHandler<T extends AbstractMessageHandler<T>>
In your generic definition you can do <T extends SomeClass>
For example:
abstract class Processor<T extends String> {
abstract T process();
}
In your case, it looks like T should extend some Response class, and not AbstractMessageHandler.
From the code given, it doesn't seem like there's any need to make the class generic. How about a generic method instead (I've even made it static, as it doesn't seem that you need to use the current object at all):
public abstract class AbstractMessageHandler
{
public static <T extends AbstractMessageHandler> T setResponseValues(AbstractMessage request, T response )
{
response.setCompanyId(request.getCompanyId());
response.setMessageGroup(request.getMessageGroup());
response.setUserId(request.getUserId());
response.setTimeStamp(AbstractMessage.getCurrentTimeStamp());
return response;
}
}
Or even better, just define a method on AbstractMessageHandler that operates on the current object. Then you don't need this static method, and you don't have this weird parameter that you always return.
public abstract class AbstractMessageHandler
{
public void setResponseValues(AbstractMessage request)
{
setCompanyId(request.getCompanyId());
setMessageGroup(request.getMessageGroup());
setUserId(request.getUserId());
setTimeStamp(AbstractMessage.getCurrentTimeStamp());
}
}

Categories