I came across this code in an exercise for declaring an abstract class:
import java.util.ArrayList;
public abstract class Box {
public abstract void add(Item item);
public void add(ArrayList<Item> items) {
for (Item item : items) {
Box.this.add(item);
}
}
public abstract boolean isInBox(Item item);
}
I am not able to understand what the add(ArrayList<Item> item) method does. I get it that it loops through an ArrayList called items but what does Box.this.add(item) do?
Can someone clarify this?
On top of what #ernest_k wrote in a comment there is an actual use-case where you actually need to qualify a method call with the class name like this: If you create an anonymous inner class in a method that accesses fields of its outer class, like the following arbitrary (and quite useless in reality) example:
import java.util.ArrayList;
public abstract class Box {
public abstract void add(String item);
public void add(ArrayList<String> items) {
for (String item : items) {
Runnable r = new Runnable() {
#Override
public void run() {
add(item); // works, implicitly accesses Box.this.add
this.add(item); // does not work as "add" is not a method of the anonymous runnable
Box.this.add(item); // works
}
};
r.run();
}
}
public abstract boolean isInBox(String item);
}
That class is declaring an interface with some code already in. Specifically, it is declaring a Box without a detailed implementation, in which you can later create the Box with the underlying code that suits your needs.
For example, you can declare the BoxOnSet class, that implements that declaration with a HashSet<>:
public abstract class BoxOnSet extends Box {
public BoxOnSet()
{
this.items = new HashSet<>();
}
public void add(Item item)
{
this.items.add( item );
}
public boolean isInBox(Item item)
{
return this.items.contains( item );
}
private HashSet<Item> items;
}
As for your specific question, the add(ArrayList<>) method is equivalent to the collections addAll() method. It just uses the abstract add(Item) in order to insert items in the Box. You can specify add( item ), this.add( item ) or even Box.this.add( item ), and in this example all point to the same method, they are just ways to specify further.
Related
The Problem
I'm trying to create an application where an object class can implement some
operations from the total pool of available operations. The end goal is to not have any code duplication and to abide by the laws of OOP as much as possible.
In more detail, I'm trying to make a search engine using Lucene. Lucene
uses many indices. I've already implemented a simple structure where different index-objects inherit the methods of a parent class. The problem is that, whatever method is implemented in that parent class, it automatically becomes available for all subclasses to use. I want to give the option to the user to determine if he wants to do a phrase search, a term search or whatever else there is available for that specific index. The catch is, some indices shouldn't have the option to conduct phrase search, for example.
First Thoughts
I've thought of implementing something close to the Composite pattern,
as described by the GoF. I would implement the search operations (e.g. term search, phrase search) as primitive operations implementing some Component class and add these primitive objects later on to a Composite object. The Composite object will be implementing the same Component class as the primitives.
public abstract class Index {
public Index(String indexPath) {
// Constructor using the information provided by the subclass
}
public void phraseSearch(...) {
// Do the operation
}
public void termSearch(...) {
// Do the operation
}
public void categorySearch(...) {
// Do the operation
}
}
public class ReviewIndex extends Index {
public ReviewIndex() {
super("./review_index/");
}
}
public class TipIndex extends Index {
public TipIndex() {
super("./tip_index/");
}
}
Expected Outcome
The class ReviewIndex shouldn't be able to perform a categorySearch but be
able to execute phraseSearch and termSearch. Respectively, the TipIndex class
should be able to execute some of the parent class methods.
Final Thoughts
I know that in my solution there is no code duplication but there
are useless methods being generated each time a new index object is created.
Thank you all in advance!
P.S. If you think the Composite pattern is the way to go, in which way would you actually add the primitive objects to the composite class and in which way would you invoke them when need to?
All methods defined in a superclass are available at deriving classes but with Java 8 you might be able to get something like this by using default-methods in interfaces. So instead of one abstract class containing all possible methods you might implement four interfaces
public interface Searchable {
public String getIndexPath();
}
public interface PhraseSearchable extends Searchable {
public default void phraseSearch() {
String indexPath = getIndexPath();
// do the search
}
}
public interface TermSearchable extends Searchable {
public default void termSearch() {
String indexPath = getIndexPath();
// do the search
}
}
public interface CategorySearchable extends Searchable {
public default void categorySearch() {
String indexPath = getIndexPath();
// do the search
}
}
To avoid duplicate code you can create an abstract class
public abstract class AbstractSearchable implements Searchable {
private String indexPath;
public AbstractSearchable(String indexPath) {
this.indexPath = indexPath;
}
// other methods that might be useful
}
Your actual classes can then implement the corresponding interfaces
public class ReviewIndex extends AbstractSearchable implements CategorySearchable {
public ReviewIndex() {
super("./review_index/");
}
}
public class TipIndex extends AbstractSearchable implements PhraseSearchable, TermSearchable {
public ReviewIndex() {
super("./review_index/");
}
}
If this is possible depends heavily on the actual implementation of the search methods. Interfaces can't contain any members, etc. so these methods must be able to run for themselves (like a static method without using any static members of the class). You might to overcome this problem by adding more methods to the Searchable interface that provide the data and do the implementation in the abstract class but that might expose internal stuff to the public because all the declared methods in an interface are public.
If you don't want to use categorySearch(...) for ReviewIndex class then create one more hierarchy where you keep the categorySearch(...) method.
Example:
public abstract class Index {
public Index(String indexPath) {
// Constructor using the information provided by the subclass
}
public void phraseSearch(...) {
// Do the operation
}
}
// Give a meaningful Name
public abstract class IndexChild1 extends Index {
public void categorySearch(...) {
// Do the operation
}
}
// Give a meaningful Name
public abstract class IndexChild2 extends Index {
public void termSearch(...) {
// Do the operation
}
}
public class ReviewIndex extends IndexChild1 {
public ReviewIndex() {
super("./review_index/");
}
}
public class TipIndex extends IndexChild2 {
public TipIndex() {
super("./review_index/");
}
}
You can use Composite pattern if you need to have the same objects and use them as you wish in your ReviewIndex and TipIndex classes. you can use a list which implies aggregation and you can use one instantiation of each object(PhraseSeach, TermSearch, CategorySearch) in any order you want.
here is the code:
import java.util.ArrayList;
import java.util.List;
public class Main{
public static void main(String[] args) {
Main m = new Main();
m.run();
}
public void run() {
ReviewIndex ri = new ReviewIndex();
}
public interface ISearch {
public void search();
}
public class SearchComposite implements ISearch{
private List<ISearch> l = new ArrayList<ISearch>();
public SearchComposite(String index) {
System.out.println(index);
}
public int addSearch(ISearch search) {
l.add(search);
return this.l.size() - 1;
}
public List<ISearch> getSearch(){
return this.l;
}
public void search() {
System.out.println("search");
}
}
public class CategorySearch implements ISearch{
#Override
public void search() {
System.out.println("category search");
}
}
public class PhraseSearch implements ISearch{
#Override
public void search() {
System.out.println("phrase search");
}
}
public class TermSearch implements ISearch{
#Override
public void search() {
System.out.println("term search");
}
}
CategorySearch cs = new CategorySearch();
TermSearch ts = new TermSearch();
PhraseSearch ps = new PhraseSearch();
public class ReviewIndex {
SearchComposite sc = new SearchComposite("./review_index/");
public ReviewIndex() {
int p = sc.addSearch(ps);
int t = sc.addSearch(ts);
sc.search();
List<ISearch> s = sc.getSearch();
s.get(p).search();
s.get(t).search();
}
}
public class TipIndex {
SearchComposite sc = new SearchComposite("./tip_index/");
public TipIndex() {
int p = sc.addSearch(ps);
int t = sc.addSearch(ts);
int c = sc.addSearch(cs);
sc.search();
List<ISearch> s = sc.getSearch();
s.get(p).search();
s.get(t).search();
s.get(c).search();
}
}
}
the output of the code above is:
./review_index/
search
phrase search
term search
and we have used the same CategorySearch, TermSearch and PhraseSearch for ReviewIndex and TipIndex classes.
I have two exact the same functions and one different function which take a TypeX as parameter. All TypeX has the same parent class Type. The dummy code is like:
public void Append(TypeA item) { //same code }
public void Append(TypeB item) { //same code }
public void Append(TypeC item) { //different code }
I wonder is there a good way to optimize such functions? My code needs to pick up the right function based on the class type, so I can't use the parent class or a generic type here because that will affect TypeC's engagement.
The best thing would be public void Append(TypeA item || TypeB item) but of course there's no such a thing available. Any idea?
Whereas the solutions offered by #erwin-bolwidt would work, I suggest you also consider
private void baseAppend (TypeParent item) { //same code }
public void Append(TypeA item) { baseAppend (item); }
public void Append(TypeB item) { baseAppend (item); }
public void Append(TypeC item) { //different code }
This method would allow a looser coupling and the potential for specialised logging and expansion in the future
Methods to be called are selected at compile time based on the declared type (not the actual type) of the object. It's safe to merge Append for TypeA and TypeB into one method that takes an argument of Type item - it doesn't make a difference from the current code.
But if you want to select on actual type, you need to use instanceof. Or you create a method on type that returns whatever you need in the append method.
public void append(Type item) {
if (item instanceof TypeC) {
// Do TypeC-specific stuff
} else {
// Do stuff for TypeA, TypeB, and any other subtype of Type
}
}
Or cleaner, if the only difference is in what you get from the item:
public class Type {
public X getWhateverYouWantToAppend() {
// Return stuff for TypeA, TypeB, and any other subtype of Type
}
}
public class TypeC extends Type {
public X getWhateverYouWantToAppend() {
// Return stuff for TypeC specifically
}
}
public class YourOtherClass {
public void append(Type item) {
X thingToAppend = item.getWhateverYouWantToAppend();
// Do the appending
}
}
You can create a parent class for TypeA and TypeB. Then use this type as an argument to the overloaded function.
This way you can avoid a duplication of code.
Another way is to let these classes to implement some interface then use this interface as an argument to the overloaded function.
Third, you can use generic type and delegate implementation to corresponding functions.
its simple in java, you can do it using method overloading
public class example{
public static void print(String s) {
System.out.println("string - "+s);
}
public static void print(int q) {
System.out.println("number - "+q);
}
public static void main(String[] args) {
print(12);
print("welcome");
}
}
output
number - 12
string - welcome
at work we do a peer review of code and I found something I don't like and I want to ask about best practice for this particular problem.
We have an interface:
public interface Item {
public String getType();
//some other methods
}
and an implementing class:
public class EmailItem implements Item {
public static final String TYPE = "email";
#Override
public String getType() {
return TYPE;
}
}
and some code that uses the classes:
for (Item item : items) {
if (EmailItem.TYPE.equals(item.getType())) {
isProcessed = Processor.process(item);
} else {
LOGGER.error("Unknown failover type received to process. Type: {}", item.getType());
}
}
At this point we have only one implementing class so checking the type is not necessary but we will add some other implementations and then it would make sense (though switch will be used).
The main issue is that EmailItem has variable TYPE set as public and this variable has also a getter.
Both class and instance of that class should have access to this variable, but having it public static final and accessing it with instance directly doesn't seem right/best practice (although it is technically possible) and when it would be private (as it should) then it won't be accessible from other classes (where for cycle is and static would not make sense at that point).
Through discussion we come up with solution with usage of instanceOf(...) or instance.getClass().getName() and EmailItem.class.getName() but none of them seem elegant to me :).
So finally, my question is what is the most elegant solution for described problem?
Heh, this is my first question here and I hope it makes sense to you ;).
Thinking about it from an OO point of view I'd consider the following approach:
public interface Item {
public boolean process();
//some other methods
}
public class EmailItem implements Item {
#Override
public boolean process() {
// email specific implementation
}
}
public class AnotherItem implements Item {
#Override
public boolean process() {
// another implementation
}
}
for (Item item : items) {
isProcessed = item.process();
}
The way you did it is fine, if you want to do it that way:
The static final variable TYPE lets you treat it as a type constant,
The implementation on the instance lets you check the constant against the return value on the interface.
However, when you find yourself dispatching on a type represented by String or some other value, you are usually going down a wrong path of switch statements in object-oriented code. If you have a choice of action at this point, consider an alternative technique of double dispatch, such as implementing the Visitor Pattern:
interface ItemVisitor {
void visitEmail(EmailItem item);
void visitSms(SmsItem item);
}
interface Item {
void accept(ItemVisitor v);
}
class EmailItem implements Item {
public void accept(ItemVisitor v) { v.visitEmail(this); }
}
class SmsItem implements Item {
public void accept(ItemVisitor v) { v.visitSms(this); }
}
Now you can do this:
class Example implements ItemVisitor {
public void visitEmail(EmailItem item) {
// Do something with an e-mail
}
public void visitSms(SmsItem item) {
// Do something with an SMS
}
public static void main(String[] args) {
Example e = new Example();
for (Item item : ItemSource.getManyItems()) {
item.accept(e);
}
}
}
If all "types" for your Item are known at compile time, you could use an enum like this:
public interface Item {
enum ItemType { MAIL, OTHER; }
public ItemType getType();
//some other methods
}
Suppose you have the following Interfaces
public interface Action {
public State execute(State state);
}
public interface State {
public Collection<Action> getPossibleActions();
}
And this method
public static Collection<State> getAllSuccessorStates(State state){
Collection<State> allSuccessors = new HashSet<>();
for (Action action: state.getPossibleActions()){
State successorState = action.execute(state);
allSuccessors.add(successorState);
allSuccessors.addAll(getAllSuccessorStates(successorState));
}
return allSuccessors;
}
A Concrete State could be for example a Chessboard and an Action the movement of a Piece on the board. Obviously the Chess-Actions need to know the concrete State class:
public class ChessAction implements Action {
#Override
public ChessState execute(ChessState state) {...}
}
Which is ofcourse not an allowed way of overriding execute. What would be the correct way of implementing this, so you can have concrete Actions, that operate on concrete States, which you can give as Arguments to getAllSuccessorStates?
I thought about Generics and also got answers pointing to Generics, but that brings about new Problems. If i write the Action class like this:
public interface Action<E extends State> {
public E execute(E state);
}
i will have the following Problem with ChessState class:
#Override
public Collection<Action<State>> getPossibleActions() {
Collection<Action<State>> actions = new ArrayList<>();
actions.add(new ChessAction());
return actions;
}
the line Actions.add causes the following error: The method add(Action) in the type Collection> is not applicable for the arguments (ChessAction)
Now i could declare Actions as
Collection<Action<ChessState>> actions = new ArrayList<>();
but that wont be a permitted return type.
You can use generics (needs java 1.5 or above):
public interface Action<T extends State> {
public T execute(T state);
}
public class ChessAction implements Action<ChessState> {
#Override
public ChessState execute(ChessState state) {...}
}
Hope that helps.
i found a satisfactory Solution now, which works correctly, doesnt need instanceof and yields no compile warnings:
public interface Action<E extends State<?>> {
public E execute(E state);
}
public interface State<E extends Action<?>> {
public Collection<E> getPossibleActions();
}
public static <A extends Action<S>, S extends State<A>> Collection<S> getAllSuccessorStates(S state){
Collection<S> allSuccessors = new HashSet<>();
for (A localAction: state.getPossibleActions()){
S successorState = localAction.execute(state);
allSuccessors.add(successorState);
allSuccessors.addAll(getAllSuccessorStates(successorState));
}
return allSuccessors;
}
Example of using getAllSuccessorStates (i forgo the implementation Details of the concrete classes here, but the Point should be apparent. You can use the method getAllSuccessorStates with any concrete State class, get Instances of this class in return collection and use them)
public class TestState implements State<TestAction> {...}
public class TestAction implements Action<TestState> {...}
public static void main(String[] args) {
TestState initialState = new TestState("1");
Collection<TestState> allSuccessorStates = getAllSuccessorStates(initialState);
for (TestState state: allSuccessorStates){
System.out.println(state.getStateStr());
}
}
This Question arose from the book "AI-A modern approache" by Stuart Russel and Peter Norvig, in case somebody who reads this book has the same Problem and searches for solutions. In the book the Action and State methods are inside a Problem Class, but i think in this way the OO-design is better.
Well, ChessState must have the same signature of execute as in the Action interface. If you require that ChessAction.execute accept only ChessState, you can write :
public class ChessAction implements Action {
#Override
public State execute(State state)
{
if (!(state instanceof ChessState))
throw new SomeException ();
ChessState cs = (ChessState) state;
...
}
}
You need to implement the same inherited method, and it will work since State is a super class for CheesState.
public class ChessAction implements Action {
#Override
public State execute(State state) {...}
}
Inside the execute method, you can use polymorph method (define in State and redefined ChessState), or you can cast to ChessState (ChessState s = (ChessState) state;), then use it as you need
Not sure how to title this...
So I've got three child classes of Event: WeightEvent, TimedEvent, RepEvent. Through whatever means, I get an object of one of the children. Now I want to send that child event to a method in another object so it can pull the data from it with the getSavedEvents() method. The method only exists in the children since pulling the data is specific to the type of event.
I started with
public void setEvent(Event e) {
but that cast my child object to an Event (parent) object.
Is there any way around this short of writing three different methods. One each for the children?
public void setEvent(WeightEvent e) {
public void setEvent(TimedEvent e) {
public void setEvent(RepEvent e) {
Thanks for any advice.
-John
Even though the reference is cast, it doesn't change the type of the actual object. When you pass the reference on, it will still be a reference to an instance of the child object. Normally this would be enough, with appropriate abstract methods in the parent type if necessary.
However, if the methods you want are specific to the types of the children and you can't come up with an appropriate abstraction which all of them can implement generically, then either you've got to use instanceof within your setEvent code or you do have to overload your method... because you're going to have to call different bits of code depending on the exact type of the event.
This is all a bit vague because we can't see any of your code except a couple of method signatures. If you could give us more details about what you're trying to do, particularly in terms of what setEvent needs to achieve and what the different methods in the child classes are, we may be able to help more.
Instead of switching on the type you should call a method on the event that's defined differently for each type of event type. This is called the Template method pattern. (It has nothing to do with C++ templates, BTW)
Using this pattern, your EventTable class becomes something like this:
public class EventTable {
public void setEvent(Event e) {
int x = 0;
columns = e.getFields();
Event[] savedEvents = e.getSavedEvents();
for(Event ev : savedEvents) {
tempdata[x] = ev.getTempData();
x++;
}
}
}
Note that the entire switch has been replaced with a single call to getTempData(). This method is then abstract in Event, just like getSavedEvents:
public abstract class Event {
public Date getDate() { return(_date); }
public abstract Event[] getSavedEvents();
public abstract int[] getTempData();
public int[] getFormattedDate() {
...
}
Then you define the getTempData() method in each subclass. For example:
public class WeightEvent extends Event {
public int getWeight() { return(_weight); }
public int getReps() { return(_reps); }
public int[] getTempData() {
return new int[]{
getFormattedDate()[0],
getWeight(),
getReps()
};
}
}
public class TimedEvent extends Event {
public String getTimeInHMS() { return(_timeString); }
public int[] getTempData() {
return new int[]{
getFormattedDate()[0],
getTimeInHMS()
};
}
}
public class RepEvent extends Event {
public int getReps() { return(_reps); }
public int[] getTempData() {
return new int[]{
getFormattedDate()[0],
getReps()
};
}
}
You could use generics to do this.
Define the Event class as follows:
public abstract class Event<T extends Event> {
public abstract void setEvent(T e);
}
This defines a class that expects to be created with any type that extends Event.
Then in your child classes you implement something like this using the child class as the generic type:
class WeightEvent extends Event<WeightEvent>
{
#Override
public void setEvent(WeightEvent e) {
...
}
}
I think your probem is calling getSavedEvents() when having an Event variable.
If so, add an abstract getSavedEvents() method to Event, which must also be declared abstract :
public abstract class Event {
public abstract Events getSavedEvents();
...
}
since Eventis abstract you can not create an instance of it; it must be subclassed to be used. If that is a problem, throw an Exception or do anything reasonable for your application (nothing at all, just return null) in Event.getSavedEvents():
public class Event {
public Events getSavedEvents() {
throw new UnsupportedOperationException("must be called in a child class");
// OR return null;
...
}
now you can call the getSavedEvents() method in your other object:
public class OtherObject {
private Event event;
public void setEvent(Event e) {
event = e;
...
Events events = event.getSavesEvents();
the method implemented by the real class of e will be used, e.g. if e is a TimedEvent, the method in that class will be called.
You could abstract the problem out behind an interface
interface IEvent
{
abstract public void doSomething();
}
Then have all your event classes implement it, e.g.
class WeightedEvent implements IEvent
{
public void doSomething()
{
// do something
}
}
Then you only need a single method and don't need to do any type checking
public void setEvent(IEvent e)
{
e.doSomething();
}
HTH
May be you can use a Visitor pattern.
Using abstract helped with the getSavedEvents() method, since all of the children implement that method.
Here's the code for setEvent():
public class EventTable {
public void setEvent(Event e) {
int x = 0;
int type = e.getEventType();
columns = e.getFields();
Event[] savedEvents = e.getSavedEvents();
for(Event ev : savedEvents) {
tempdata[x][0] = ev.getFormattedDate()[0];
switch(type) {
case EVENTTYPE.WEIGHT:
tempdata[x][1] = ev.getWeight();
tempdata[x][2] = ev.getReps();
break;
case EVENTTYPE.TIMED:
tempdata[x][1] = ev.getTimeInHMS();
break;
case EVENTTYPE.REP:
tempdata[x][1] = ev.getReps();
break;
}
x++;
}
}
}
This code works after I added "abstract" to the Event class and defined an abstract method called getSavedEvents().
The next problem is the getWeight(), getReps() and getTimeInHMS() methods. They are specific to the type of child event and again don't exist in the parent Event class. If I make them abstract in Event, now I have to define them in each child, even though getReps() has no context for a TimedEvent.
public class Event {
public Date getDate() { return(_date); }
}
public class WeightEvent extends Event {
public int getWeight() { return(_weight); }
public int getReps() { return(_reps); }
}
public class TimedEvent extends Event {
public String getTimeInHMS() { return(_timeString); }
}
public class RepEvent extends Event {
public int getReps() { return(_reps); }
}
Abbreviated code, obviously. WeightEvents have a date, weight and reps associated with them. TimedEvents have a date and length of time associated with them. RepEvents have a date and number of reps associated to them. The date methods are all in the parent since they are common across events.
If I don't make getWeight(), getReps() abstract and only declare them in the child where they are relevant, here's the error I get from EventTable in the above copied setEvent() method:
EventTable.java:124: cannot find symbol
symbol : method getWeight()
location: class Event
tempdata[x][1] = ev.getWeight();
-John
You could cast the Event e object to the child classes -- I think the instanceof operator in Java will help you.