i have one class implemeting two different interfaces ,example:
public interface SortList{
void Sort();
search();
delete();
}
public interface unSortedList{
search();
delete();
}
class List implements ordenedList,unordenedList{}
I wanted to switch between ordened interface or not ordened list,thank you for your help.
You have to make 2 different class like OrderedList and UnorderedList. Implements are just a guarantee you have implemented those mehtots. So you have to make a switch case or if else in your methods or you have to make two different class.
I don't know what meaning you put behind "Ordened" and "UnOrdened", and if it makes sens to have a class implementing both, but anyway, here is an example on how you can use multiple implementations of interfaces, trying to keep up with your stuff.
I suppose by ordered the Java meaning as explained here, which is not sorted.
Let's say an Ordered interface gives the possibility to access some object (of type T) by index and to search or find for a given object:
public interface Ordered<T> {
T getNth(int i);
T find(T o);
}
Let's say an UnOrdered interface provides only the way to find an object:
public interface UnOrdered<T> {
T find(T o);
}
Now we can defined a class that implements both interfaces:
public class MyList<T> implements Ordered<T>, UnOrdered<T> {
List<T> theList;
public MyList(T...a) {
theList = Arrays.asList(a);
}
// The list of objects are neither sorted nor hashed.
// Only way to find an object is to iterate through the list
public T find(T o) {
for (T e : theList) {
if (e.equals(o)) {
return e;
}
}
return null;
}
public T getNth(int i) {
return theList.get(i);
}
}
public static void main(String[] args) {
MyList<Integer> mylist = new MyList<>(2,8,6,1,7,3,5,9,10,4);
System.out.println(mylist.getNth(3));
// => print 1
System.out.println(mylist.find(3));
// => print 3
System.out.println(mylist.find(42));
// => print null
}
You could have done a better job in describing the problem and what you are trying to solve for, assuming that I understood the problem, you can achieve this with Java 8 Default methods here is how
public interface UrdenedList{
void ordenate();
default T search(){
// default implementation here
}
default void delete(){
// default implementation here
}
}
public interface UnordenedList{
default T search(){
// default implementation here
}
default void delete(){
// default implementation here
}
}
I wanted to switch between ordened interface or not ordened list,thank
you for your help.
class List implements OrdenedList,UnordenedList{
void ordenate(){
// implementation here
}
T search(){
if(condition)
return OrdenedList.search();
else
return UnordenedList.search();
}
}
void delete(){
if(condition)
OrdenedList.delete();
else
UnordenedList.delete();
}
}
Notice Resolving conflicts by Explicitly choosing to call methods from interfaces OrdenedList, and OrdenedList
Related
I've interface MyInterface and two classes ( Summary, Detail) are implementing this, and overriding compareTo.
A third class DetailMe is extending Detail
Another class (MyApi) is using List<MyInterface> , and complaining for Collections.sort , what am i doing wrong ?
public class Summmary implements MyInterface, Comparable<Summary> {
private Detail detail;
public Summary(Detail detail) {
this.detail = detail;
}
// properties
// methods
#Override
public int compareTo(Summary o) {
// Do work
}
}
==
public class Detail implements MyInterface, Comparable<Detail> {
// properties
// methods
#Override
public int compareTo(Detail o) {
// Do Detail work
}
}
==
public class DetailMe extends Detail {
// Do work
}
==
public class MyApi {
private List<MyInterface> myList;
public MyApi(List<MyInterface> myList) {
this.myList = myList
Collections.sort(this.myList); // COMPLIATION ERROR
}
}
You need to ensure (in a way the compiler knows of) that the list only contains one type of object, because your objects can't compare with each other.
So, your list must be either a List<Summmary> or a List<Detail>.
That is, unless you define the ordering of mixed elements, but then both classes would have to implement public int compareTo(MyInterface o).
In Java, one can allow an interface-specified function to return a Comparable simply by using a return type of Comparable. This isn't particularly useful, however, since there's no guarantee that two different implementations of this interface will return Comparables that can be compared to each other. Is there some way of doing this?
To illustrate my question, let's say we're making a class that stores objects and automatically 1) groups them and 2) sorts these groups. So something like:
GroupList.java
public class GroupList<T extends Groupable> {
private HashMap<Comparable, T[]> data;
public void add(T e) {
Comparable group = e.getGroup();
if(!data.containsKey(group)) { /* make new group for the element */ }
/* add element to matching group */
}
public T[][] get() {
/* return all the data, with the sets ordered by their Comparable */
}
}
Groupable.java
public interface Groupable {
public Comparable getGroup();
}
This runs into the aforementioned problem, however, which means that things like this are possible:
Class A implements Groupable {
String datestamp;
public Comparable getGroup() { return datestamp; }
}
Class B implements Groupable {
Date datestamp;
public Comparable getGroup() { return datestamp; }
}
This is further complicated by the fact that while all the Comparables must work with each other, I do not know ahead of time what they will be.
You could make the Comparable subclass a generic parameter, too.
Something like
public interface Groupable<G extends Comparable<G>> {
public G getGroup();
}
public class GroupList<G extends Comparable<G>> {
private HashMap<G, Groupable<G>[]> data;
public void add(Groupable<G> e) {
G group = e.getGroup();
if(!data.containsKey(group)) { /* make new group for the element */ }
/* add element to matching group */
}
public Groupable<G>[][] get() {
/* return all the data, with the sets ordered by their Comparable */
}
}
In this case, if you have class A implements Groupable<String>, and class B implements Groupable<Date>, you can't mix them in the same GroupList, but you can still mix a different class with the same grouping class, e.g. class C implements Groupable<String>
GroupList<String> groupList = new GroupList<String>();
groupList.add(new A()); //ok
groupList.add(new B()); //compile error
groupList.add(new C()); //ok
So I have 3 classes:
Item
GroupItem extends Item
ProductItem extends Item
I am passing a array of Item objects to a class and want to do separate things depending on their class type.
Would using instanceof be an acceptable way of doing this or should I have an internal boolean isGroup() method which will be set on initialisation of the specified sub-class.
class Item {
protected boolean isGroup = false;
public boolean isGroupItem() { return isGroup; }
}
class GroupItem extends Item {
public GroupItem() {
isGroup = true;
}
}
class ProductItem extends Item {
public ProductItem() {
isGroup = false;
}
}
class Promotion {
// Item can be either a group or a list of items
private List<Item> items = new LinkedList<Item>;
public void addItem(Item itemObj) {
items.addItem(itemObj);
}
public List<Item> getItems() {
return items;
}
}
class Checker {
// Items retrieved from Promotion and passed from another class as array
public Checker(Item[] items) {
// either
if(items[0] instanceof GroupItem) {
// Do something ...
}
// or
if(items[0].isGroupItem()) {
// Do something ...
}
}
}
So my questions are:
instanceof or method?
if method, in Item or Promotion?
and, Why? (Just so i can better understand the reasoning)
Thanks in advance
Use different methods on the actual type you want to pass as parameter.
Usually, using instance of means that there is something wrong in your model.
If you need to have different behaviors for different subtypes, it means that you are not really using the parent type. In addition, you are compelled to know the implementation details, which should not be the case.
If the inheritance you have is only a technical one, try to use composition instead of inheritance.
This is the exact place where you should use instanceOf operator .
The instanceof operator compares an object to a specified type. You
can use it to test if an object is an instance of a class, an instance
of a subclass, or an instance of a class that implements a particular
interface.
There is no point to skatch a new method or some boolean property to do this stuff. You can easily identify specific Object of GroupItem by check instanceOf.
you can also use GroupItem.class.isInstance(items[0]) to check the same. like -
if(GroupItem.class.isInstance(items[0])) {
// Do something ...
}
I guess I would try to define why I need to know if it is a group at this point.
Let's say it is to decide if one Item is eligible for a promotion and the promotion rules might change: then I would use instanceof, because you don't want the promotion rules logic to "pollute" your basic objects.
If being a group is an important property of your item and is useful in various contexts (not just the promotion rules), I would include it at the Item level.
The instaceOf operator is a better choice but I would also consider to use the Visitor pattern.
interface Item{
void accept(CheckerVisitor checker);
}
class GroupItem implements Item{
void accept(CheckerVisitor checker){
checker.visit(this);
}
}
class OtherItem implements Item{
void accept(CheckerVisitor checker){
checker.visit(this);
}
}
class CheckerVisitor{
void visit(GroupItem groupItem){
//do specific things to GroupItem
}
void visit(OtherItem otherItem){}
}
class MyClassOfItems{
List<Item> items = ...;
for(Item item : items){
item.accept(new CheckerVisitor());
}
}
So after reading this i chose a different path for my solution. Thanks for everyone who helped.
The solution I chose allows me to not even be bothered with what sub-type the object is (thanks to Assylias and Balázs Mária Németh for making me rethink my structure) as I use abstract classes to just get the information i need.
abstract class Item {
public Item(...) {
initialise();
createSQLSegment();
}
protected String SQLSegment = "";
protected abstract void createSQLSegment();
public String getSQLSegment() {
return SQLSegment;
}
...
}
// Concrete class creates response
class GroupItem extends Item {
...
// Concrete method
protected void createSQLStatement() {
SQLStatement = "...SQL...";
}
}
class ProductItem extends Item {
...
// Concrete method
protected void createSQLSegment() {
SQLSegment = "...SQL..."
}
}
class Promotion {
// Item can be either a group or a list of items? extends Item>;
public void addItem(Item itemObj) {
items.addItem(itemObj);
}
public List<Item> getItems() {
return items;
}
}
class Checker {
// Items retrieved from Promotion and passed from another class as array
public Checker(Item[] items) {
...
for(Item item : Items) {
addPreparedSQLToBatch(item);
}
}
private void addPreparedItemToBatch(Item item) {
...
// No need to know concrete class
SQLString += Item.getSQLSegment();
...
}
}
Thanks again to everyone.
Comments welcome, I'm always learning :-)
I want to run certain tests in Lists. The Lists can contain entirely different classes.
I have one method to check the consistency of the list - not null, not empty, no more than x elements. This is common to all the lists. Then I want to test each of the objects, using overloading.
The idea would be something like:
public static <T> void check(List<T> list) {
//do general checks
for (T element : list) {
check(element);
}
}
and then
public static void check(SomeType element) {...}
public static void check(SomeOtherType element) {...}
But I also had to add a method like this:
public static void check(T element) {...}
And this was called at runtime - not my other methods with the specific classes. Although the class was exactly the same. I'm evidently missing some generics understanding.
Now if I don't use the general method at all and try to solve it this way:
public static void check(List<SomeType> list) {...}
public static void check(List<SomeOtherType> list) {...}
Compiler error - "Method check(List) has the same erasure check(List) as another method..."
So is there any elegant solution for this? I could just use different method names but would like to know how it's possible without that.
Thanks!
This isn't something about generics that you're missing. Java does not have double dispatch. The call to check must be resolved at compile-time, and check(T) is the only match since the compiler can't tell if T is SomeType or SomeOtherType in a given scenario. It needs to choose one method to call that will work for all possible Ts.
This is sometimes solved using the visitor pattern.
The problem should be solved by the caller. When it instanciate your class with a concrete type for T, it should also pass an instance of Checker<T> with the same concrete type:
public class SomeClass<T> {
private List<T> list;
private Checker<T> checker;
public SomeClass(Checker<T> checker) {
this.checker = checker;
}
public void check() {
checker.check(list);
}
}
public interface Checker<T> {
public void check(List<T> list);
}
...
SomeClass<Foo> someClass = new SomeClass<Foo>(new Checker<Foo>() {
#Override
public void check(List<Foo> list) {
// do whatever you want here
}
});
You can use instanceof to dispatch:
public static <T> void check(List<T> list) {
for (T element : list) {
check(element);
}
}
public static void check(T t) {
if (t instanceof SomeType) {
SomeType someType = (SomeType) t;
// code for SomeType ...
} else if (t instanceof OtherType) {
OtherType otherType = (OtherType) t;
// code for OtherType ...
} else {
// we got a type that we don't have a method for
}
}
With generics, the type parameter is actually erased during compilation, and the list object don't know anything about the static type of the object it contains. Since it doesn't know it, it can not use overloading to call methods with different parameters, because Java doesn't support multiple dispatch.
You have then three choices:
Make your objects implement a Checked interface with a check method that does the check logic. Downside is that the check logic is now dispersed in several places and it is not practical if you have objects of classes you don't have control of.
Use instanceof to call explicitly the check methods according to the dynamic type of the object. Downside is you potentially end up with a big if/else block a bit harder to maintain.
Implement the visitor pattern. Downside is that you have to change the object classes too, but the check logic stay in a single place.
Since the type of the variable is lost in check(List<T> list) you have two options:
1. Do different things by checking runtime type
check(T element) {
if (element.getClass().equals(SomeType.class)) {
check((SomeType) element);
} elseif (element.getClass().equals(SomeOtherType.class)) {
check((SomeOtherType) element);
}
This can be made a little more sophisticated, for example by wrapping each check in a Callable and using a Map<Class, Callable>
This is similar to visitor pattern.
2. Calling a virtual method on the element to be checked itself
If the checking logic can be pushed to the object to be checked itself (this is not necessarily a bad thing) then you don't need to check types:
interface Checkable { void check(); }
class SomeType implements Checkable { .... }
class SomeOtherType implements Checkable { .... }
Then:
public static <T extends Checkable> void check(List<T> list) {
for (T element : list) {
element.check();
}
}
These are the only two options, any implementation has to be a variation on one of these
Hello I'm wondering what would be some more elegant alternatives to something like this:
class Base...
class A extends Base...
class B extends Base...
//iterator of colection containing mixed As and Bs i want to remowe Bs and do omething with As
while(iterator.hasNext()) {
Base next = iterator.next();
if(next instanceof A) // do something
if(next instanceof B)
iterator.remove();
}
Sow what are the alternatives...
Thank you for advices.
edit: Base class may have many subclasses not just two and their numbers may grow in time
You can create methods in Base and override them in A and B.
For example:
class Base{
public boolean shouldRemove(){
return false;
}
public void doSomething(){
}
}
class A extends Base{
#Override
public void doSomething() {
}
}
class B extends Base{
#Override
public boolean shouldRemove() {
return true;
}
}
and then you don't need know what class the object is an instance of:
while(iterator.hasNext()) {
Base next = iterator.next();
if(next.shouldRemove()){
iterator.remove();
}
else{
next.doSomething();
}
}
Do you really need to remove them from the list? Why don't you just have the method to do something in the Base class (doing nothing) and then just override it do to what you want on class A.
class Base{
public void doSomething(){
}
}
class A extends Base{
#Override
public void doSomething(){
// do something
}
}
Then you could just iterate over the list and calling the method doSomething on all objects.
for(Base base : list) {
base.doSomething();
}
This way only the classes that have overridden the doSomething() method will actually do something. All the other classes will just execute the dummy implementation in the Base class.
If Base was an abstract class you could declare the doSomething() as abstract and have the extending classes implement it. With this approach all classes would have to implement the method and classes for which you don't want any computation to be performed you would just provide a dummy implementation of that method. Alternatively you could even create an interface with the doSomething() method and have (which could even be a better decision) and have the Base class implement it, given that only the extending classes would actually implement the method.
instanceof is a good way to filter objects by type - and that's what you want to do. You have a mixed collection and so you need some kind of filter, either filter the input (store nothing but As) or filter the output (process nothing but As).
If you just don't like "instanceof", you could use an enum to specify the type and add a final method to get the type at Base:
enum Type { ATYPE, BTYPE };
public Base {
final private Type type;
public Base(Type type) { this.type = type; }
public Type getType() { return type; }
// ...
}
public A {
public A() { super(Type.ATYPE); }
}
while(iterator.hasNext()) {
Base next = iterator.next();
switch (next.getType) {
case ATYPE: // do something and break
case BTYPE: iterator.remove(next); break;
}
}
i think is very short and clear solution and has no alternatives (without code growing),
just add else if instead of if in second case
Also you can split code on function calls, and if statement will not be huge
Another solution is to create Map of delegates that will be called. Like this:
interface ISimpleDelegate{ void doSomeLogic(Base b) }
`Map delegates = new HashMap();
After this add your logic as anonymous classes that realizes ISimpleDelegate.
delegates.put(A.class, new ISimpleDelegate() { //write your logic here });
I hope that the idea is clear
And in your loop you just call delegates:
while(iterator.hasNext()) {
Base next = iterator.next();
delegates.get(next.getClass()).doSomeLogic(next);
}
In general, a nice solution to avoid instanceof is to use the so-called visitor pattern.
For this pattern, you need an additional interface (the Visitor), an implementation of it that contains the code you want to execute and an additional method in all classes of your hierarchy, so this might be overkill in small cases (but it is very handy if there is not only A and B, but more types).
In your case it would look like this:
interface Visitor {
void visit(A a);
void visit(B b);
}
class Base {
abstract accept(Visitor v);
}
class A extends Base {
accept(Visitor v) {
v.visit(this);
}
}
class B extends Base {
accept(Visitor v) {
v.visit(this);
}
}
class MyVisitor implements Visitor {
visit(A a) {
doSomethingWithA(a);
}
visit(B b) {
doSomethingWithB(b);
}
}
It is used like this:
MyVisitor v = new MyVisitor();
while(iterator.hasNext()) {
Base next = iterator.next();
next.accept(v);
}
An advantage is that you have to write most of the code only once. If you want to do other things with A and B in another place of your program, just write another implementation of Visitor. You don't need to modify Base, A and B as you would if you'd add doSomething() to these classes.
Edit:
If the number of sub-classes increases, you need to change all your existing implementations of Visitor. However, at least the compiler tells you about that. With instanceof you might end up forgetting a place where you need to add a handling clause. This can at most be detected at runtime, whereas the visitor pattern gives you compile-time safety.