4
public abstract class CommonClass {

      abstract void send(<what should i put here???>) {}
    }   

 public class ClassA extends CommonClass {

      void send(List<Comments> commentsList) {
            // do stuff
      }
    }

 public class ClassB extends CommonClass {

      void send(List<Post> postList) {
            // do stuff
      }
    }

I am new to OODP, I am trying to have a method that is able to take in any kind of List data so that I can abstract things out. How can i do this?

Michiel Leegwater
  • 1,172
  • 4
  • 11
  • 27
Ninja Dude
  • 1,332
  • 4
  • 27
  • 54

3 Answers3

7

You could make it generic on some type T. Like,

public abstract class CommonClass<T> {
    abstract void send(List<T> al);
}   

And then, to implement it - use the generic. Like,

public class ClassA extends CommonClass<Comments> {
    @Override
    void send(List<Comments> commentsList) {
        // do stuff
    }
}

public class ClassB extends CommonClass<Post> {
    @Override
    void send(List<Post> postList) {
        // do stuff
    }
}

Also, as discussed in the comments, your class names could be improved to be more intuitive; something like,

public abstract class AbstractSender<T> {
    abstract void send(List<T> al);
}

and then

public class CommentSender extends AbstractSender<Comment> {
    @Override
    void send(List<Comment> commentsList) {
        // do stuff
    }
}

public class PostSender extends AbstractSender<Post> {
    @Override
    void send(List<Post> postList) {
        // do stuff
    }
}

That has the advantage(s) of being more readable and easier to reason about (I can tell what a PostSender does by reading the name, ClassB not so much).

Finally, this looks like a case where an interface would work since your abstract class is purely virtual (and should be preferred since you can implement multiple interface, but can only extend from a single parent class);

public interface ISender<T> {
   void send(List<T> al);
}

public class CommentSender implements ISender<Comment> {
    @Override
    void send(List<Comment> commentsList) {
        // do stuff
    }
}

public class PostSender implements ISender<Post> {
    @Override
    void send(List<Post> postList) {
        // do stuff
    }
}
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • I am using Springboot, why does it complain that "Cannnot resolve symbol T"? – Ninja Dude Aug 23 '19 at 06:52
  • 2
    @Desmond did you define T to be a type parameter in your CommonClass and did you define in your classes inheriting from CommonClass what T has to be? (Double check with answer above) – Remco Buddelmeijer Aug 23 '19 at 06:54
  • 2
    @Desmond What Java compiler level have you set? Generics require Java 5+ (which was released in 2004). Also, did you use the code **exactly** as in my answer? – Elliott Frisch Aug 23 '19 at 06:55
1

In order to achieve this, you can take multiple approaches, I would suggest looking into Generics: https://docs.oracle.com/javase/tutorial/java/generics/index.html

With that said, there is one approach that is the most elegant and simple: you can supply a List<T> where T is a generic type.

public abstract class CommonClass<T> {

      abstract void send(List<T>) {}

}   

 public class ClassA extends CommonClass<Comment> {

      void send(List<Comments> commentsList) {
            // do stuff
      }
}

 public class ClassB extends CommonClass<Post> {

      void send(List<Post> postList) {
            // do stuff
      }
}
0

You can do that with the help of generics. https://www.tutorialspoint.com/java/java_generics.htm


Example

The abstract class

public abstract class CommonClass {
    public abstract <T> void send(List<T> data);
}

Its child

public class Child extends CommonClass {

    public <T> void send(List<T> data) {
        // code here
    }
}

Retrieving the list's contents

Retrieving the generified list's contents is similar to retrieving any list's contents. In the scope of the method, "T" is a type of object contained in the list.

for (T t : data) {
    // to check if t is a string
    if (t instanceof String) {
        // code
    }
}

You can also use lambdas to retrieve every element in the list.

BrokenEarth
  • 128
  • 1
  • 10
  • Why would you introduce your own generic parameter when there is no need for this? This can also introduce problems in the future, as probably there is logic for a specific Type (Class), now you restrict the user of this. – Remco Buddelmeijer Aug 23 '19 at 07:05
  • Well I assumed that the he won't need to use the specific type outside of the class since he didn't mention. But yes, it's better to generify the class if there is a necessity use it in different methods and fields. – BrokenEarth Aug 23 '19 at 07:12