So I have two classes. One is abstract:
public abstract class AbstractClient {
protected boolean running = true;
protected void run() {
Scanner scanner = new Scanner(System.in);
displayOptions();
while (running) {
String input = null;
while (scanner.hasNext()) {
input = scanner.next();
}
processInputCommand(input);
}
}
abstract void displayOptions();
abstract void processInputCommand(String input);
}
One is the concrete subclass:
public class BasicClient extends AbstractClient {
private IBasicServer basicServer;
public static void main(String[] args) {
new BasicClient();
}
public BasicClient() {
try {
System.setSecurityManager(new RMISecurityManager());
Registry registry = LocateRegistry.getRegistry();
basicServer = (IBasicServer) registry.lookup(IBasicServer.LOOKUPNAME);
run();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
void displayOptions() {
BasicClientOptions.displayOptions();
}
#Override
void processInputCommand(String input) {
// TODO Auto-generated method stub
}
}
Now in the subclass I call the run() method of the abstract class because this should be common to all clients. Inside the run() method is a call to the abstract method displayOptions().
I have overridden displayOptions() in the subclass so I assumed that it would invoke the subclassed method but it seems it has not. Is there a way to do this or have I made an obvious mistake or have I misunderstood how abstract classes should work?
P.S I tried putting a print statement inside the subclassed displayOptions() to ensure I hadn't done something daft with method I call.
Many thanks,
Adam
Maybe something is wrong with your BasicClientOptions.displayOptions() call. I'm wondering how you know that BasicClient.displayOptions() isn't being called.
Here's a simplified version of what you have. Try running it. It behaves in the way you expect.
public abstract class BaseClass {
public void run() { foo(); }
public abstract void foo();
}
public class Subclass extends BaseClass {
public static void main(String[] args) { new Subclass().run(); }
#Override
public void foo() {
System.out.println("I'm from the subclass");
}
}
Is it the case that the classes are in different packages? If so you need to declare the method to override as protected.
Edit: (guess an explanation might help :-)
If you declare a method public/protected then it can be overridden by children outside of the package. If you make it (package)/private then it cannot. private methods cannot be overridden at all which (package) ones can only be overridden by classes in the same package.
I use (package) because there is no keyword for it, so in the absence of public/protected/private you get (package) access.
Edit:
The above is likely not true given your description (assuming that the class really is abstract, and you have used the #Override annotation).
Are you 100% sure that the run method is getting called? Put a System.out.println in run and make sure it is called.
Are you 100% sure that you are not catching any other exceptions and failing to print out the stack trace (or something else that will ensure that you see that the exception was caught)?
Not sure what the problem is, could you print some output (with your print statements).
I copy / pasted your code and aside from commenting out a line or two where I did'nt have the proper source for the object. It called the subclasses methods for me.
Logically, reading your code nothing seemed out of place but I prefer to see stuff with my own eyes to make sure there wasn't another issues and so I tried running your code first. :)
Here's what I modified and my output.
import java.util.Scanner;
public abstract class AbstractClient {
protected boolean running = true;
protected void run() {
Scanner scanner = new Scanner( "foo\\r\\nbar\\r\\n" );
displayOptions();
while ( running ) {
String input = null;
while ( scanner.hasNext() ) {
input = scanner.next();
}
processInputCommand( input );
running = false;
}
}
abstract void displayOptions();
abstract void processInputCommand( String input );
}
import java.rmi.RMISecurityManager;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class BasicClient extends AbstractClient {
//private IBasicServer basicServer;
public static void main( String[] args ) {
new BasicClient();
}
public BasicClient() {
try {
System.setSecurityManager( new RMISecurityManager() );
Registry registry = LocateRegistry.getRegistry();
//basicServer = (IBasicServer) registry.lookup(IBasicServer.LOOKUPNAME);
run();
} catch ( Exception e ) {
e.printStackTrace();
}
}
#Override
void displayOptions() {
//BasicClientOptions.displayOptions();
System.out.println( "We're in subclasses displayOptions()." );
}
#Override
void processInputCommand( String input ) {
System.out.println( "We're in subclasses processInputCommand()." );
}
}
My Output
We're in subclasses displayOptions().
We're in subclasses processInputCommand().
So in effect it seems your class was working just maybe the logging wasn't up to par.
Hope this helps.
This thread has been quiet for a while, so I doubt this will help you, but I thought I'd post it in case somebody else comes looking for answers.
Up until a few minutes ago, I was having a similar problem with an interface, abstract class, and concrete subclass. Basically the interface defines 10 methods, the abstract class implements 2 of those and leaves the other 8 for the concrete class. The implementation for one of the methods in the abstract class calls a method that was meant to be implemented by the concrete class.
Everything compiled fine and NetBeans didn't complain about anything but at runtime the VM bombed out, stating that the method (the one implemented in the concrete class) did not exist. It's been years since the last time I used Java, but I'm pretty sure this isn't the expected behavior in this situation (somebody please correct me if I'm wrong).
After several hours of kicking my laptop, I discovered that adding an abstract stub of the method I was calling to the abstract class allowed the call to be forwarded to the concrete class without any complaints from the VM. Is this normal or did I just get lucky?
Anyway, hope somebody finds this useful.
Related
Today I was thinking about a nice way to write less code for a common functionality that is required for different objects.
Inheritance can do the job but then the classes won't be able to inherit from anyone else, so I chose Interfaces.
So I have my interface with the functionality I will need for some objects:
public interface Test {
String message = "Hello from Interface!";
default void printMessage() {
System.out.println(message);
}
}
And then I can use it in any object without having to override/write any code more than just simply calling the method when needed:
public class TestingTest implements Test {
public String message = "Hello from Class!";
public TestingTest() {
printMessage();
}
public static void main(String[] args) {
new TestingTest();
}
}
It works like a charm! But... Then I thought, what if I want some of those objects to specify a different message without being required (optional), well first thing I thought was to shadow the interface variable, but it doesn't work, the default method keeps using the variable from the interface instead of the class variable (which shadowed it).
A solution of course would be to overload the printMessage method in the interface so it recieves the message as a parameter for when the user requires to specify the message, but is there any more elegant way? Something like simply just declaring a new message in the class?
The String message in the interface is static (AFAIK). So that scheme does not work.
You might do something (ugly) as:
default void printMessage(String... messages) {
if (messages.length == 0) {
messages = new String[] { "arrgg" };
}
System.out.println(messages[0]);
}
Fields have no inheritance, so the value can only stem from an overridable method like
public String message() { return "..."; }
What you want is a functionality in n classes that should also be modifiable, if needed.
To be honest, your example is a little bit abstract and thus my answer will be abstract, too.
public interface Test {
void printMessage();
default void printMessage(String message) {
System.out.println(message);
}
}
public class TestingTest {
private final test;
public TestingTest(Test test) {
this.test = test;
}
public void someMethod() {
test.printMessage("Hello from class");
}
}
Additionally, you would have a class that implements the interface and offers the message. This way you could group your objects, change the message, make more complex logging and you would actually see the dependency from outside.
In my opinion, you are misusing the interface. An interface offers public methods to call it from outside, but you want to use them inside like they were private functionalities for the class.
Just use objects instead.
I have a question. I have multiple classes in a package: Let's say package is
com.myPackage.first
And this package has the following classes:
firstGood
secondGood
thirdBad
fourthGood
Each of these classes have a method with the same name but different implementation. So say each have a one particular function called:
public void runMe(){
}
For now I want to come up with a way to given a class name, it'll go inside the class and run that particular method.
So conceptually, my method will look like those:
ArrayList<Class> classList ; // where classList is a list of classes I want to run
public void execute(){
for(Class c : classList){
// Go inside that class, (maybe create an intance of that class) and run the method called run me
}
}
or
public void execute(Class c, String methodToRun){
for(Class c : classList){
// Go inside that class, (maybe create an intance of that class) and run the method called run me
}
}
For now. what I have been able to do is get the name of the classes I want to run the
runMe()
method. So I have been able to come with a way to get the arraylist of classes I want to run. So what I need help with is coming up with a method such that it takes a class name and run the method I want it to. Any help is appreciated. Thanks
I suggest having a look at Class.forName ( ... ) to get the class object, Class.newInstance(); if your classes have a default constructor (or Class.getDeclaredConstructor(...) otherwise) to create a new instance and then Class.getDeclaredMethod( ... ) to find the method and invoke it.
All of this without any regard if your idea is really a good one, since I really didn't quite understand WHY you want to do what you want to do...
interface Me {
void runMe();
}
Then let all classes implement Me.
And have a list of Mes
List<Class<Me>> ...
Then
void test(Class<Me> cl) {
Me me = cl.newInstance();
me.runMe();
}
My adage is always use reflection to solve a problem - now you have two problems. In view of that have you considered a simple pattern like this:
interface Runner {
public void runMe();
}
static abstract class BaseRunner implements Runner {
public BaseRunner() {
// Automagically register all runners in the RunThem class.
RunThem.runners.add(this);
}
}
class FirstGood extends BaseRunner implements Runner {
#Override
public void runMe() {
System.out.println(this.getClass().getSimpleName() + ":runMe");
}
}
class SecondGood extends BaseRunner implements Runner {
#Override
public void runMe() {
System.out.println(this.getClass().getSimpleName() + ":runMe");
}
}
static class RunThem {
static final Set<Runner> runners = new HashSet<>();
static void runThem() {
for (Runner r : runners) {
r.runMe();
}
}
}
public void test() {
Runner f = new FirstGood();
Runner s = new SecondGood();
RunThem.runThem();
}
Here all of your runMe objects extend a base class whose constructor installs the object in a Set held by the class that calls their runMe methods.
inline
void execute() throws Exception{
for (Class<?> c : classesList)
{
//If you don't already have an instance then you need one
//note if the method is static no need for any existing instance.
Object obj = Class.forName(c.getName());
// name of the method and list of arguments to pass
Method m = c.getDeclaredMethod(methodName,null);
//method accessibility check
if(!m.isAccessible())
m.setAccessible(true);
//invoke method if method with arguements then pass them as new Object[]{arg0...} instead of null
//if method is static then m.innvoke(null,null)
m.invoke(obj, null);
}
}
I would recommend using an Interface that defines the runMe() method and then have all your classes implement that interface. Then you would have a list of this Interface:
List<MyInterface> classes = new ArrayList<MyInterface>();
Then you could easily iterate over it and invoke "runMe()" on all of them or if you only want to invoke it for instances of a certain class you could do it like this:
public void execute(Class classForWhichToExecute) {
for (MyInterface myInterface : classes) {
if (classForWhichToExecute.isAssignableForm(myInterface)) {
myInterface.runMe();
}
}
}
Of course this wouldn't work if your method is a static method - so adding more information from your side would help.
I would suggest to use an interface with a common method to override in each class. So that any class can be casted to interface and use its method to execute the method.
interface GoodAndBad{
public void runMe();
}
Implemented class
class FirstGood implements GoodAndBad{
#override
public void runMe(){
// Code to be executed
}
}
You can use execute() method as follows
public void execute(List<GoodAndBad> classList){
for(GoodAndBad c : classList){
c.runMe();
// Go inside that class, (maybe create an intance of that class) and
// run the method called run me
}
}
Change the Class to GoodAndBad interface to change the other method too.
This is loosely coupling objects to support favor over composition in Java Object Oriented Design Patterns.
Never use Strings of method names to execute a method at anytime. There are plenty of other cool solutions for that using design patterns.
Today while coding I began a deep dive into the world of reflection. I have messed with it in small bits and pieces before but never to this extent and no matter where I look I can find no answer to my question and so here I am! Currently what I am trying to do is use reflection with a class whose constructor requests a parameter but for ease of use I wish to use the super class of the parameter.
Here is the code causing problems with some explanations:
this.listener = (MyListener) listenerClass.getConstructor(MyAppState.class).newInstance(this);
The thing is that MyAppState is the class that all of my appstates extend from and each listener takes in its own specific AppState that extends MyAppState but has extra features different from each other. What I need to know is what I can put in my .getConstructor() to specify that the class I am passing in is the super of the parameter it wants.
Here is a theoretical example of the code:
this.listener = (MyListener) listenerClass.getConstructor(Class extends MyAppState.class).newInstance(this);
So is this possible or should I just work with my code to have a second constructor that accepts the MyAppState class, or something else along those lines.
Also, sorry if this is off topic but to prevent problems in the future, I am being told this question is subjective. Is there any way to word future questions to not be as subjective or is the method to figure out whether the question is subjective just a bit flawed?
[EDIT] As requested, a few more examples related to the question:
public MyAppState(Node screen, Class listenerClass)
{
this.screen = screen;
try
{
this.listener = (MyListener) listenerClass.getConstructor(MyAppState.class).newInstance(this);
}
catch (Exception e)
{
Logger.getLogger(MyAppState.class.getName()).log(Level.SEVERE, "The listener for the {0} appstate could not be created using reflection.", new Object[]{this.getClass().getName()});
System.exit(-1);
}
}
Above is the full parent class's constructor, the said class extends one more class but it contains no constructor and so I am not sure if it is needed. If it is please feel free to ask for it.
public class OptionsMenuState extends MyAppState
{
public OptionsMenuState()
{
super(new Node("Options Screen"), OptionsMenuStateListener.class);
}
That is one class and its constructor with pieces cut off to keep it short.
public class MainMenuState extends MyAppState
{
public MainMenuState()
{
super(new Node("Start Screen"), MainMenuStateListener.class);
}
Here is another class and its constructor.
[EDIT] As suggested, I created a program that roughly mimics what I am attempting to do.
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
//This is what I want to do but I don't know how to have java allow me to pass in Greeting.
createObject(SimpleSentence.class);
createObject(DifferentSentence.class);
}
public static void createObject(Class theClass)
{
theClass.getConstructor(Greeting.class).newInstance(new Hello());
}
class SimpleSentence
{
Hello firstWord;
public SimpleSentence(Hello word)
{
firstWord = word;
}
}
class DifferentSentence
{
Howdy firstWord;
public DifferentSentence(Howdy word)
{
firstWord = word;
}
}
class Greeting
{
}
class Hello extends Greeting
{
}
class Howdy extends Greeting
{
}
}
Short answer is you can't. getConstructor(Class<?>...parametertypes) is very explicit because it needs to match exactly zero or one constructor only.
You will need to go through all the constructors to find one, that has a parameter that is assignable from MyAppState
e.g. outline:
final Constructor<?>[] ctrs = listenerClass.getConstructors();
for (Constructor<?> constructor : ctrs) {
if (constructor.getParameterTypes()[0].isAssignableFrom(MyAppState.class)) {
// use this one?
}
}
I have an interface (p) and an implementation (imp). If I do the following in the code, then the check works:
if (!(imp instanceof p)) {
logger.error(imp.getClass().getName()+
" doesn't satisfy the interface "
+p.getClass().getName());
}
I tried to make it into a callable method as follows:
private boolean checkInterfaceImplementation(Object implemen, Object inter){
return (implemen instanceof inter);
}
which failed.
Then I found that inter needs to be a specific type and I cannot use a generic object. Then I found out about
"B.class.isAssignableFrom(A.getClass())"
Then I did:
System.out.println("B.class.isAssignableFrom(A
.getClass())");
The output was
true
I read up more from this question. My question is "Is this (the second implementation with ".isAssignableFrom") the preferred or standard way to implement said method? Is there any way that this present implementation can create problems?
It's hard to understand your question. I will edit when more details are received, if necessary, but as a general rule of thumb instanceof is an indicator of a lack of polymorphism and a design issue. Not always the case, but if you are a beginner I would try to use it as little as possible.
Instead, consider why that check is even there. If "imp" implements "p", then you are guaranteeing that any "imp" will have all the methods in "p". If it doesn't, you will receive a compiler error before you can even build. This is very abstract right now so I will do quick example.
public interface Runs {
public void run();
}
public class Cat implements Runs {
int numLegs;
public Cat() {
this.numLegs = 4;
}
public void run() {
System.out.println("does whatever running cats do");
}
}
public class Human implements Runs {
int numLegs;
public Human() {
this.numLegs = 2;
}
public void run() {
System.out.println("does whatever running humans do");
}
}
public class Main {
public static void main(String[] args) {
Cat cat = new Cat();
Human human = new Human();
ArrayList<Runs> listOfRunners = new ArrayList<Runs>();
listOfRunners.add(cat);
listOfRunners.add(human);
Runs runner = listOfRunners.get(0);
/* no compiler error because by implementing Runs we guarantee it has run() method */
runner.run();
runner = listOfRunners.get(1);
/* It doesn't matter what the object is. We don't care if it is cat or human */
runner.run();
}
}
Not sure exactly what you are trying to do, but something like this should work:
inter.getClass().isInstance(implemen)
Most likely what you are trying to do can be done in a much better way than resorting to this, though.
If I have the method public void send() { /* some code */ } in a class and have a child of this class also have a method public void send() { /* some code*/ }, how do I ensure that the child must call super.send() somewhere in the send() method that it's trying to override?
I was wondering about this because I've written in APIs where if you don't call the super of that method when overriding it, it'll throw an exception telling me that I haven't called the super method. Is this hard coded or can this be done with some keywords in Java?
You can't really, but you can...
class MySuperClass {
public final void send() {
preSend();
// do the work...
postSend();
}
protected void preSend() {
// to be overridden in by sub classes
}
protected void postSend() {
// to be overridden in by sub classes
}
}
You can do this by adding an abstract method (don't see another way) :
abstract class MyClass
{
public final void send() // forbid changing this.
{
// do something
doSend():
}
protected abstract doSend(); // no external calls
}
http://en.wikipedia.org/wiki/Call_super
What you're trying to do is an anti-pattern; you can do it (many Java core classes do), but you shouldn't - unless you have a really good reason for it.
Except for this bit, all answers provided here are correct.
Conceptually, this is like 'delegating to a child'. To achieve this, the parent class should implement final method which invoke an abstract method, which the child is supposed to implement.
abstract class Parent {
public final void invoke() {
// pre invoke code
doInvoke():
// post invoke code
}
protected abstract doInvoke(); // child should implement this
}
You can't really force a subclass to call the base one. One thing you can do is to change your send method into a base (final) "send" and a "sendcore" (virtual) which would be overriden by the subclasses. The base "send" would set some flag stating that "sendcore" hasn't been called, and then call "sendcore". When it returns it can check whether the child "sendcore" has called the base class.
There is no keyword that enforces this. In my opinion, you either
Provide the subclass with all the information (via protected methods or what not) it needs to completely override and change the send call itself, or...
Document the API so that it is known that they must eventually call send themselves via super. I would imagine most people who are overriding a superclass method would do this if enough of the class is abstracted anyway.
There's nothing built into Java to enforce calling a superclass method. One approach to this is to use private flags in the superclass together with a delegation method. Something like this:
public class Super {
private boolean inSend;
private boolean superCalled;
public final void send() {
inSend = true;
superCalled = false;
doSend();
inSend = false;
if (!superCalled) {
throw new IllegalStateException("Failed to call super.doSend()");
}
}
protected void doSend() {
if (!inSend) {
throw new IllegalStateException("Cannot call doSend() directly");
}
superCalled = true;
// base class functionality
}
}