Java Get the List of an Object from another Class - java

I'm having two classes : WorldOfRobots and Robot (abstract). Both are public. World of robots is basically an arraylist of Robot.
Then I have a class telebot which is an extension of Robot.
I'm trying to build a method in the class Telebot which will identify and get the list of robots where the current object Telebot is.
For example:
I create 2 World of Robots (wor1 and wor2) and then 1 telebot (r1).
I add r1 in wor1.
I'd like to get a way to get the list of robots of wor1 in a method of the class telebot.
Here is a bit of code.
abstract class Robot {
// content
}
public class Telebot extends Robot
{
// instance variables - replace the example below with your own
private WorldOfRobots wor;
public Telebot(String newName, String newDirection)
{
super(newName, newDirection);
}
public void something {
// here I'm trying to get the list
wor = new WorldOfRobots();
ArrayList<Robot> robots = wor.getList();
// Unfortunately this solution doesn't work cause I'm creating a new WOR. What I want is to get the WOR where the Telebot belong.
}
}
public class WorldOfRobots {
// List of robots
private ArrayList<Robot> robots;
public WorldOfRobots() {
robots = new ArrayList<Robot>();
}
public ArrayList<Robot> getList() {
return robots;
}
}
Thanks for your help.

You can refactor your class to something like this ...
public class Telebot extends Robot {
//your code and constructer here
public void something(WorldofRobots container){
//this is the list containing your instance of telerobot, use it as you like
}
}
Now from outside classes you can invoke robotInstance.something(listOfRobot);
I am not sure how your classes are exactly interacting so I cannot expand on using this method more.

abstract class Robot {
private WorldOfRobots world;
public void setWorld(WorldOfRobots world)
{
this.world=world;
}
// content
}
public class Telebot extends Robot
{
public Telebot(String newName, String newDirection)
{
super(newName, newDirection);
}
public void doSomething()
{
world.doSomethingElse();
}
}
public class WorldOfRobots {
// List of robots
private ArrayList<Robot> robots;
public WorldOfRobots() {
robots = new ArrayList<Robot>();
}
public void addRobot(Robot robot)
{
robots.add(robot);
robot.setWorld(this);
}
}
Storing a reference for the WorldOfRobots in the Robot class is reasonable in this case. If you want a robot to belong to multiple WorldOfRobots then change the world varible to List.

Related

Is there a specific way to give a certain subclass some functions of the superclass?

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.

Copy an object that contains a super class of another object

I would like to create a copy of an object that contains a super class of another object. In this example I want to make a copy of the Box that contains a Toy. But all kind of toys can be in the box. What would be the best way to create the copy constructor in Toy?
class Box {
Toy toy;
public Box(Toy toy) {
this.toy = toy;
}
public Box(Box box) {
this.toy = new Toy(box.getToy());
}
}
abstract class Toy {
public Toy(String name) {
// ...
}
}
class Car extends Toy {
public Car(String name) {
super(name);
// ...
}
}
class Puppet extends Toy {
public Puppet(String name) {
super(name);
// ...
}
}
I don't really have an idea how to approach this problem.
Make Toy have an abstract method copy() with return type Toy. Then you will be forced to override this in Car and Puppet. In the copy constructor for Box you can use box.getToy().copy().
You can override the clone method of each Toy's subclass and then :
public Box(Box box) {
this.toy = (Toy) box.getToy().clone();
}
Alternatively, if you have a constant number of types of toy, you can use an enumeration instead of a class.
i think this structure can help you to have an idea,in this case we pass an Object toy using Box Constructor to SuperClass(Toy) and in Toy Class we have a Constructor to Accept an Object from Toy Class then it's call getInstance Method for Initialize toy object(just for example).
class Box extends Toy
{
public Box(Toy toy)
{
super(toy);
}
}
Class Toy
{
private static Toy toys = new Toy();
Toy(){}
Toy(Toy toy)
{
toy = Toy.getInstance();
}
public static Toy getInstance()
{
return toys;
}
}
and either,if you don't want other Classes(sub class) to don't see a specified methods and attributes just make them private,and if you want sub classes haven't access to set and get methods too,make them private only!

How to move a method from a class to another class when two classes are not at all related

I am trying to re factor some code by breaking a class into several other classes.
to do so i want to move some methods already existing in my old class to new class.
But these methods are being referred in a lot of places and manually updating the references seems tiresome. So is there any way to move methods as well as update their references in eclipse?
I would do it this way:
Ensure that your tests work and the code to be re-factored is covered. If you don't have tests write tests. They are your safety rope.
Use the re-factoring pattern extract superclass to create the new class that you want to move some methods to.
Use the re-factoring pattern pull up methods to move the methods along with the variables that they need to the superclass. Now you will see if the methods you want to move and the instance variables have dependencies to the other methods that you don't want to move. If so you must first break this dependencies.
Find all client code that should use the new extracted class instead of the "old" class and rewrite it to the new extracted class.
Remove the "extends" relationship between the two classes. Now the client code should work or you missed something.
Also a good book for learning how to apply re-factoring patterns is Working Effectively with Legacy Code
if you using eclipse IDE then refactor will help you.
I will show you the process I follow.
Consider such code:
public class GodClass {
public someInstanceMethodToMove() {
// some code 1
}
public static someStaticMethodToMove() {
// some code 2
}
public static void main(String[] args) {
GodClass c = ...;
c.someInstanceMethodToMove();
GodClass.someStaticMethodToMove();
}
}
Create the new class:
public class SingleResponsibilityClass {
}
The static method can be directly moved to the SingleResponsibilityClass by using Eclipse's Refactor > Move... refactoring as described by Prabhakaran:
public class GodClass {
public someInstanceMethodToMove() {
// some code 1
}
public static void main(String[] args) {
GodClass c = ...;
c.someInstanceMethodToMove();
SingleResponsibilityClass.someStaticMethodToMove();
}
}
public class SingleResponsibilityClass {
public static someStaticMethodToMove() {
// some code 2
}
}
For the instance method, the process is a little more complex. Read below.
Extract a method out of someInstanceMethodToMove() and let's name it someInstanceMethodToMove2():
public class GodClass {
public someInstanceMethodToMove() {
someInstanceMethodToMove2();
}
private someInstanceMethodToMove2() {
// some code 1
}
// ...
}
Use the SingleResponsibilityClass in the original method:
public class GodClass {
public someInstanceMethodToMove() {
someInstanceMethodToMove2(new SingleResponsibilityClass());
}
private someInstanceMethodToMove2(SingleResponsibilityClass obj) {
// some code 1
}
// ...
}
Note: it is important that SingleResponsibilityClass is a parameter of the instance method to move, otherwise Eclipse will not move it to this type.
From there, right click on someInstanceMethodToMove2(), and select Refactor > Move..., select SingleResponsibilityClass type in the wizard, then apply:
public class GodClass {
public someInstanceMethodToMove() {
new SingleResponsibilityClass().someInstanceMethodToMove2();
}
// ...
}
public class SingleResponsibilityClass {
private someInstanceMethodToMove2() {
// some code 1
}
public static someStaticMethodToMove() {
// some code 2
}
}
Then right click on SingleResponsibilityClass' someInstanceMethodToMove2() method and Refactor > Rename it to someInstanceMethodToMove():
public class GodClass {
public someInstanceMethodToMove() {
new SingleResponsibilityClass().someInstanceMethodToMove();
}
// ...
}
public class SingleResponsibilityClass {
private someInstanceMethodToMove() {
// some code 1
}
public static someStaticMethodToMove() {
// some code 2
}
}
Then right click on GodClass' someInstanceMethodToMove() method and Refactor > Inline:
public class GodClass {
public static void main(String[] args) {
GodClass c = ...;
new SingleResponsibilityClass().someInstanceMethodToMove();
SingleResponsibilityClass.someStaticMethodToMove();
}
}
public class SingleResponsibilityClass {
private someInstanceMethodToMove() {
// some code 1
}
public static someStaticMethodToMove() {
// some code 2
}
}
does it have any of your satisfaction
package com.hussi.stackOverFlow;
class ClassOne {
public void methodInClassOne(String stringParam)
{
ClassTwo classTwoObj = new ClassTwo();
classTwoObj.methodInClassTwo(stringParam);
}
}
class ClassTwo {
public void methodInClassTwo(String stringParam)
{
System.out.println(stringParam);
}
}
public class ClassThree {
public static void main(String[] args)
{
ClassOne objClassOne = new ClassOne();
// calling method of class two in class one
objClassOne.methodInClassOne("pass this String value");
}
}
Copy the method into the new class.
Replace the method body in the old class with a call into the new class.
Inline the old method.
That's all you need. It may not be quite that simple, because in steps 1 and 2 you may need to add arguments and/or make the method static, but that is the essence of how to do it.
If you use any of the standard IDEs (e.g., Eclipse or IntelliJ IDEA), they all have a simple menu option to do that (depending on how the code is organized).
If you go to each method and right-click on its name, the menu has a "Refactor" option, which leads to a "Move" option. Select that and follow the instructions.
The above is especially easy for static methods. For the non-static ones, you may need to do subclassing, or pass references to the appropriate objects around. Even so, the "Refactor -> Move" option is a good start.

An alternative to static classes

So I'm currently using a static class called GameFile and it holds the game instance, the current map, the player posiition, the player name, player money, etc. Basically all the global info. I was wondering if there is an alternative to this?
This is how I currently set in the static class the game instance (as an example):
GameFile.gameInstance = new ChromeGame();
and then when I need to use the information I call
GameFile.gameInstance.addScreen(SplashScreen).
This is how I would do it for a mobile game. You can have OOP concepts all through out and have all setters/getters, but in low type mobile devices, this "OOP" is costly.
public class GameData {
public static Model activePlayerModel;
public static GameMap currentMap;
public static void load () {
// read necessary data from external sources. e.g. a file
}
public static void updateMap () {
// update currentMap
}
public static Model getActiveModel() {
// get current model/set default/or read from file and return
}
public static GameMap getCurrentMap() {
// e.g. Create a map or read map from a file, etc
// return the map
}
}
Now I can access GameData's members directly.
public class GameScreen extends Screen {
Model playerModel;
public GameScreen (Game game) {
GameData.load();
playerModel = Settings.activePlayerModel;
}
}

Innerclass sharing attribute information

I have a class called ContentStream... the problem is that the inner class AddRectancle suppose to get the info of the getter of the class GraphicBeginn...I thought the class ContentStream can reach the getter at least as the getter is public ... plse tell me how to
public class ContentStreamExt extends ContentStreamProcessor
{
private Matrix graphicalMatrix;
public ContentStreamProcessorExt(ExtListener extListener)
{
super(extListener);
}
private void enhanceAdditional()
{
GraphicBeginn beginnGraphic = new GraphicBeginn();
super.register("a", beginnGraphic);
super.register("b", new AddRectangle(beginnGraphic));
}
private static class AddRectangle(GrapicBeginn beginn)
{
// should get the info of uUx and uUy
}
private static class GraphicBeginn implements ContentOperator
{
private float uUx;
private float uUy;
public float getuUx()
{
return this.uUx;
}
public float getuUy()
{
return this.uUy;
}
..... // the input for uUx and uuy will be created in a method
}
The code you gave has a number of problems, it doesn't compile correctly as another poster has noted. It also appears you are providing a method signature while also declaring a class called "AddRectange". Is this a class or a method? You need to decide which, it can't be both. Here is an example that I think illustrates what you're trying to do in a general sense:
public class SampleClass {
public SampleClass() {
}
private void sampleClassMethod() {
A a = new A();
a.acceptB(new B());
}
private class A {
public void acceptB(B bObject) {
System.out.println(bObject.memberVar1);
}
}
private class B {
private int memberVar1 = 5;
}
}
If i understand your question correctly, The add rectangle class should be passed an instance of graphic begin on which it can invoke the public getters. This wiring can be done by the content stream class.
By the way the following is syntactically invalid
private static class AddRectangle(GrapicBeginn beginn)

Categories