I have the following two Java classes (Command and Player). I would like to be able to list from the Command class all the public methods from the Player class, without having to hard-code them. I tried several ways, including an interface, or the command pattern, but I am not fluent in Java and I did not manage to make them work.
It seems to me that using Java's reflection API would be easier. However, when I use it to print the public methods from the Player class, I get extraneous methods, which I assume were inherited from the Object class.
Is there a way to only include those methods I defined myself (i.e. those starting with "public method: public void Player.")?
Thank you,
LC
Here is the output I get:
public method: public void Player.search(Command)
public method: public Room Player.getCurrentRoom()
public method: public void Player.engage()
public method: public void Player.trade(Command)
public method: public void Player.goRoom(Command)
public method: public void Player.takeItem(Command)
public method: public void Player.dropItem(Command)
public method: public void Player.lock(Command)
public method: public void Player.unlock(Command)
public method: public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public method: public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public method: public final void java.lang.Object.wait() throws java.lang.InterruptedException
public method: public boolean java.lang.Object.equals(java.lang.Object)
public method: public java.lang.String java.lang.Object.toString()
public method: public native int java.lang.Object.hashCode()
public method: public final native java.lang.Class java.lang.Object.getClass()
public method: public final native void java.lang.Object.notify()
public method: public final native void java.lang.Object.notifyAll()
Here is the Command class:
import java.lang.reflect.Method;
public class Command
{
// a constant array that holds all valid command words
private static String[] validCommands;
private String commandWord;
private String secondWord;
public Command(String firstWord, String secondWord)
{
commandWord = firstWord;
this.secondWord = secondWord;
}
[...] //some code omitted
public boolean process(Player player)
{
Class pClass = player.getClass();
Method[] methods = pClass.getMethods();
for (int i = 0; i < methods.length; i++) {
System.out.println("public method: " + methods[i]);
}
boolean wantToQuit = false;
if(commandWord == null) {
System.out.println("I don't know what you mean...");
return false;
}
if (commandWord.equals("help")) {
printHelp();
}
else if (commandWord.equals("go")) {
player.goRoom(this);
}
else if (commandWord.equals("quit")) {
wantToQuit = quit();
}
else if (commandWord.equals("take")) {
player.takeItem(this);
}
else if (commandWord.equals("drop")) {
player.dropItem(this);
}
else if (commandWord.equals("search")) {
player.search(this);
}
else if (commandWord.equals("engage")) {
player.engage();
}
else if (commandWord.equals("trade")) {
player.trade(this);
}
else if (commandWord.equals("lock")) {
player.lock(this);
}
else if (commandWord.equals("unlock")) {
player.unlock(this);
}
else {
System.out.println("Invalid command. Type 'help' if you forgot the list of available commands.");
}
// else command not recognised.
return wantToQuit;
}
}
Here is the outline of the Player class:
public class Player
{
private String name;
private Room currentRoom;
private ArrayList<Item> items;
Player (String name, Room startingRoom)
{
this.name = name;
items = new ArrayList<Item>();
this.currentRoom = startingRoom;
printWelcome();
}
public void engage()
{
[...]
}
public void trade(Command command)
{
[...] }
public void goRoom(Command command)
{
[...] }
public void search(Command command)
{
[...] }
public void takeItem(Command command)
{
[...] }
public void dropItem(Command command)
{
[...] }
public void lock(Command command)
{
[...] }
public void unlock(Command command)
{
[...]
}
}
You want to use the getDeclaredMethods() class from the Java reflection API.
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getDeclaredMethods()
That gives you only the methods declared on the class in question, ignoring superclasses and interfaces.
Related
For example, if I wanted to do something like this to call a method:
myLights.addLight(new Fluorescent(lumens));
in order to create a new object in the Fluorescent class and pass down the lumens data. How would I then set up the method to receive this?
Assuming method is not returning anything.
void addlight(Fluorescent a){
// your logic
}
In your Lights class create a method that accepts a Fluorescent object as an argument.
public void addLight(Fluorescent fluorescent){
// do something
}
Here is a basic example:
public class HelloWorld
{
public static void main(String[] args)
{
Light light = new Light();
light.addLight(new Fluorescent("300 lm"));
System.out.print(light.getLumen());
}
}
public class Light {
private String lumen;
public Light() {
}
public void setLumens(String lumen){
this.lumen = lumen;
}
public String getLumen(){
return this.lumen;
}
public void addLight(Fluorescent fluorescent) {
if(fluorescent.getLumen() != null) {
this.lumen = fluorescent.getLumen();
}
}
}
public class Fluorescent {
private String lumen;
public Fluorescent(String lumen){
this.lumen = lumen;
}
public void setLumen(String lumen){
this.lumen = lumen;
}
public String getLumen(){
return this.lumen;
}
}
Seeing that a Fluorescent is a Light, you might want to look in to inheritance.
Look here for some explanation
Java 101: Inheritance in Java, Part 1
public class Fluorescent() {
public Fluorescent(String lumens) {
// do something
}
}
public class Lights() {
public void addLight(Fluorescent fluorescent) {
// do something
}
}
I have the following need and please help me to write good and abstract class.
Different types of operations is needed based on the type
I have a abstract class,
abstract public class FileHelper{
//Template method
//This method defines a generic structure for parsing data
public void parseDataAndGenerateFile(String fileDownloadType)
{
createHeader(fileDownloadType);
generateFile();
}
//We have to write output in a excel file so this step will be same for all subclasses
public void createHeader(String fileDownloadType)
{
System.out.println('Creating HEADER in EXCEL');
}
public void generateFile(String fileDownloadType)
{
System.out.println('Output generated,writing to XLX');
}
}
public class ExcelDataParser extends FileHelper {
String fileDownloadType="";
}
public class TemplateMethodMain {
public static void main(String[] args) {
String fileDownloadType="expired";
ExcelDataParser csvDataParser=new ExcelDataParser();
csvDataParser.parseDataAndGenerateFile(fileDownloadType);
}
}
Please help me and correct me to have a good way of doing this.
If you want to use an abstract base class, you better should declare an abstract method String getDownloadType() in your abstract base class. These method must be overridden by the derived classes and the type could be fix in the derived class.
For example:
abstract public class FileHelper {
abstract String getFileDownloadType();
public void parseDataAndGenerateFile() {
createHeader();
generateFile();
}
public void createHeader() {
if ("expired".equals(getFileDownloadType())) {
} else {
}
}
public void generateFile() {
if ("expired".equals(getFileDownloadType())) {
} else {
}
}
}
public class ExcelDataParser extends FileHelper {
#Override
String getFileDownloadType() {
return "expired";
}
}
public class TemplateMethodMain {
public static void main(String[] args) {
ExcelDataParser csvDataParser = new ExcelDataParser();
csvDataParser.parseDataAndGenerateFile();
}
}
But if you don't need a class for every type, you also could make the type a variable inside a single class and passing the type to the contructor
For example:
public class CsvFileHelper {
private final String fileDownloadType;
public CsvFileHelper(String type) {
fileDownloadType = type;
}
public void parseDataAndGenerateFile() {
createHeader();
generateFile();
}
public void createHeader() {
if ("expired".equals(fileDownloadType)) {
} else {
}
}
public void generateFile() {
if ("expired".equals(fileDownloadType)) {
} else {
}
}
}
public class TemplateMethodMain {
public static void main(String[] args) {
CsvFileHelper csvDataParser = new CsvFileHelper("expired");
csvDataParser.parseDataAndGenerateFile();
}
}
Is it possible to define following in Java:
public interface IGenericRepo<T> {
void add();
void delete();
void attach();
}
public interface IGenericRepo<Book> {
default String bookSpecificMethod(){
return "smthn";
}
}
public class NHGenericRepo<T> implements IGenericRepo<T>{
/* implementation */
}
public class NHUnitOfWork implements UnitOfWork{
#Autowired
public void setBookRepo(NHGenericRepo<Book> bookRepo) {
this.bookRepo= bookRepo;
}
public NHGenericRepo<Book> getBookRepo() {
return bookRepo;
}
private NHGenericRepo<Book> bookRepo;
}
And to be able somewhere in code to have:
{
#Autowired
public void setNhuw(NHUnitOfWork nhuw) {
this.nhuw = nhuw;
}
private NHUnitOfWork nhuw;
/**/
{
String st = this.nhuw.getBookRepo().bookSpecificMethod();
}
}
In .net this is possible by using Extension Method with "this IGenericRepo<Book>" as a first method parameter.
The closest you can come is:
public interface IBookGenericRepo extends IGenericRepo<Book> {
void BookSpecificMethod();
}
I was trying to understand Decorator Pattern. Below is the code am trying to understand how it works.
public static void main(String[] args)
{
Room myRoom = new CurtainDecorator(new ColorDecorator(new SimpleRoom()));
System.out.println(myRoom.showRoom());
}
Below is my Concrete Class
public class SimpleRoom implements Room{
#Override
public String showRoom()
{
return "show room";
}
}
Below is my abstract Decorator class
public abstract class RoomDecorator implements Room{
public Room roomReference;
#Override
public String showRoom()
{
return roomReference.showRoom();
}
}
Below is my Decorator implementation1
public class ColorDecorator extends RoomDecorator{
#Override
public String showRoom()
{
return addColors(); //How does showRoom() method gets invoked here?
}
public ColorDecorator(Room room)
{
this.roomReference = room;
}
public String addColors()
{
return "Blue";
}
}
Below is my Decorator implementation 2
public class CurtainDecorator extends RoomDecorator{
public CurtainDecorator(Room room)
{
this.roomReference = room;
}
#Override
public String showRoom()
{
return this.roomReference.showRoom() + addCurtains(); //What will showRoom method invoke?
}
public String addCurtains()
{
return "Curtain";
}
}
Output is - BlueCurtain
My question are placed in the comment..
In the end you have:
CurtainDecorator(ref=ColorDecorator(ref=SimpleRoom)))
When you call showRoom from main, it calls the method of CurtainDecorator, which in turn first goes to it's reference (ColorDecorator in this case) that outputs 'Blue', then CurtainDecorator adds it's bit 'Curtain'.
I have a requirement that is close to extending enums and since that is not possible, after doing some research online, I came up with this approach of using interfaces and making the enums extend them.
My problem is that I have a few basic types A,B and a flag for each type that says if that has to be checked. Similarly I have some extended types C... which do the same stuff after checking their flags.
Here is the code that does this
Type Interface:
public interface Type {
public String name();
}
Here is the class that uses the basic types
public class BasicChecker {
private static boolean checkA = false;
private static boolean checkB = false;
public enum BasicType implements Type {
A, B;
}
public static boolean isCheckA() {
return checkA;
}
public static void setCheckA(boolean checkA) {
BasicChecker.checkA = checkA;
}
public static boolean isCheckB() {
return checkB;
}
public static void setCheckB(boolean checkB) {
BasicChecker.checkB = checkB;
}
public static void doStuff(String message, Type type) {
if (type.name().equalsIgnoreCase(BasicType.A.name())) {
doStuff(message, isCheckA());
} else if (type.name().equalsIgnoreCase(BasicType.B.name())) {
doStuff(message, isCheckB());
}
}
protected static void doStuff(String message, boolean flag) {
if (someCheckMethod() && flag) {
doStuff(message, flag);
}
}
private static boolean someCheckMethod() {
return false;
}
}
And this is the class that uses extended types
public class ExtendedChecker extends BasicChecker {
private static boolean checkC = false;
public enum ExtendedType implements Type {
C;
}
public static boolean isCheckC() {
return checkC;
}
public static void setCheckC(boolean checkC) {
ExtendedChecker.checkC = checkC;
}
public static void doStuff(String message, Type type) {
BasicChecker.doStuff(message, type);
if (type.name().equalsIgnoreCase(ExtendedType.C.name())) {
doStuff(message, isCheckC());
}
}
}
What I am trying to solve now is to remove all the if else cases from log method. I am also trying to see if there is a better way to do this. Please ignore the statics. I do want them to be static fields and methods.
I'm having trouble understanding exactly what you're trying to do from your description, but you may find abstract methods in enums to be useful.
For example, you could add an abstract method "foo" to your enums:
public enum BasicType implements Type {
A {
public void foo(String message) {
// Do special A stuff
}
}, B {
public void foo(String message) {
// Do special B stuff
}
};
public abstract void foo(String message);
}
And you could then use that method like this:
public static void doStuff(String message, Type type) {
type.foo(message);
}
Naturally, you could put any such abstract methods in an interface you extend, if that's useful.
public class BasicChecker {
private static final Set<Type> _doCheck = Collections.newSetFromMap(new ConcurrentHashMap<Type,Boolean>());
public enum BasicType implements Type {
A, B;
}
public static boolean isCheck(Type type) {
return return _doCheck.contains(type);
}
public static void setCheck(Type type, boolean check) {
if(check) {
_doCheck.add(type);
} else {
_doCheck.remove(type);
}
}
public static void doStuff(String message, Type type) {
doStuff(message, isCheck(type));
}
}