I am trying to wrap my mind around something in java. When I pass an object to another class' method, can I not just call any methods inherent to that object class?
What is the reason code such as the example below does not compile?
Thank you,
class a {
public static void myMethod(Object myObj) {
myObj.testing();
}
}
class b {
public void testing() {
System.out.println ("TESTING!!!");
}
}
class c {
public static void main (String[] args) {
b myB = new b();
a.myMethod(myB);
}
}
Edit: The reason I have left the parameter in myMethod as type Object, is because I would like to be able to pass in a variety of object types, each having a testing() method.
If you would like to pass in a variety of objects with testing() methods, have each object implement a Testable interface:
public interface Testable
{
public void testing()
}
Then have myMethod() take a Testable.
public static void myMethod(Testable testable)
{
testable.testing();
}
Edit: To clarify, implementing an interface means that the class is guaranteed to have the method, but the method can do whatever it wants. So I could have two classes whose testing() methods do different things.
public class AClass implements Testable
{
public void testing()
{
System.out.println("Hello world");
}
}
public class BClass implements Testable
{
public void testing()
{
System.out.println("Hello underworld");
}
}
The problem is that myMethod can't know it's getting a b object until it actually runs. You could pass a String in, for all it knows.
Change it to
public static void myMethod(b myObj) {
myObj.testing();
}
and it should work.
Update of the question:
Edit: The reason I have left the parameter in myMethod as type Object, is because I would like to be able to pass in a variety of object types, each having a testing() method.
As Amanda S and several others have said, this is a perfect case for an interface. The way to do this is to create an interface which defines the testing() method and change myMethod to take objects implementing that interface.
An alternative solution (without interfaces) would be to reflectively discover if the object has a testing() method and call it, but this is not recommended and not needed for a such a simple case.
What you are talking about is duck typing. Java doesn't have duck typing.
Therefore you need to define an interface that all the classes with a testing() method implement.
e.g:
public interface Testable
{
public void testing()
}
class B implements Testable
{
public void testing() {
System.out.println ("TESTING!!!");
}
}
class A {
public static void myMethod(Testable myObj) {
myObj.testing();
}
}
Your issue is a classic argument in favor of an interface. You want as generic as possible, yet you want every object you pass to have a testing() method. I suggest something along the lines of the following:
public interface Testable
{
public void testing();
}
public class A
{
public static void myMethod(Testable myObj)
{
myObj.testing();
}
}
public class B implements Testable
{
public void testing()
{
System.out.println("This is class B");
}
}
public class C implements Testable
{
public void testing()
{
System.out.println("This is class C");
}
}
public class Test
{
public static void main (String[] args)
{
B myB = new B();
C myC = new C();
A.myMethod(myB); // "This is class B"
A.myMethod(myC); // "This is class C"
}
}
Because you're passing in an Object (b inherit from Object). Object doesn't have testing, b does.
You can either pass in b or cast the object to b before calling the method.
EDIT
To pass in a generic class that implements that method: you'll want to make an interface that has the method signature and pass in the interface type instead of Object. All objects that you pass in must implement the interface.
You can only access the members that are visible for the type of reference you have to the object.
In the case of myMethod(Object myObj) that means only the members defined in Object, so in class a the members of class b will not be visible.
If you changed the definition of a.myMethod to be public static void myMethod(b myObj) you would then be able to see the testing method on the instance of b while in myMethod.
update based on clarification:
In that case defining an interface for all of them to implement is likely what you want.
public interface Testable {
public void testing();
}
public class a {
public static void myMethod(Testable myObj) {
myObj.testing();
}
}
public class b implements Testable {
public void testing () {
System.out.println("TESTING!!!");
}
}
Why can’t java find my method?
Because of the way Java was designed.
Java is "statically typed" that means objects types are checked during compilation.
In Java you can invoke a method only if that method belongs to that type.
Since this verification is made during compilation and the Object type does not have the "testing()" method, the compilation fails ( even though if at runtime the objects do have that method". This is primarily for safety.
The workaround as described by others will require you to create a new type, where you can tell the compiler
"Hey, the instances of this type will respond the the testing method"
If you want to pass a variety of objects and keep it very generic, one way is having those objects to implement and interface.
public interface Testable {
public void testing();
}
class A implements Testable { // here this class commits to respond to "testing" message
public void testing() {
}
}
class B implements Testable { // B "is" testable
public void testing() {
System.out.println("Testing from b");
}
}
class C implements Testable { // C is... etc.
public void testing() {
//....
}
}
Later somewhere else
public void doTest( Testable object ) {
object.testing();
}
doTest( new A() );
doTest( new B() );
doTest( new C() );
The "OTHER" way to do this, in java is invoking the methods reflectively, but I'm not sure if that's what you need, for the code is much more abstract when you do it that way, but that's how automated testing frameworks (and a lot of other frameworks such as Hibernate) do actually work.
I hope this help you to clarify the reason.
If you REALLY, REALLY want to keep the parameter as abstract as possible, you should consider reflection API. That way, you can pass whatever object you want and dynamically execute the method you want. You can take a look at some examples.
It's not the only way, but it might be a valid alternative depending on your problem.
Keep in mind that reflection is way slower than calling your methods directly. You might consider using an interface as well, such as the one on Amanda's post.
Related
I have interface:
public interface Doable {
void doSomething();
}
and the class that implements it:
public class DoJump() implements Doable {
#Override
private void doSomething() {
fireJumpHandler();
}
}
This is stupid example, but I would like to present the problem.
This code doesn't compile, I am getting an error in Eclipse IDE:
Cannot reduce the visibility of the inherited method from
Doable
I have common interface that declares a method. This method is overriden in concrete class. I would like to avoid another class that can extend this class (DoJump), so I would like to hide this method from sub classes. I would like to use private modifier, but Java does not allow me to do it.
Why it is impossible, and how to workaround it?
I'd like to answer your last question "How to workaround it?" as this is not described in the related question. Create a second interface NotDoable which simply does not have doSomething() declared. Then let your DoJump implement both interfaces. Give everyone that shouldn't override doSomething a reference to the interface NotDoable instead of the true type DoJump. Then they won't know that the object truly can doSomething, they won't know per class design. Of course, one can workaround this but one actually can workaround everything. The class design is more correct this way. Here's some code:
public interface Doable {
public void doSomething();
}
public interface NotDoable {
}
public class DoJump implements Doable, NotDoable {
#Override
public void doSomething() {
System.out.println("hi");
}
public NotDoable meAsNotDoable() {
return this;
}
public static void main(String[] args) {
DoJump object = new DoJump();
// This call is possible, no errors
object.doSomething();
NotDoable hidden = object.meAsNotDoable();
// Not possible, compile error, the true type is hidden!
hidden.doSomething();
}
}
But as said, one can workaround this by using if (hidden instanceof DoJump) { DoJump trueObject = (DoJump) hidden; }. But well, one can also access private values via reflection.
Other classes now implement NotDoable instead of extending DoJump. If you declare everything others should know about DoJump in this interface, then they only can do what they should do. You may call this interface IDoJump and the implementing class DoJump, a common pattern.
Now the same a bit more concrete.
public interface IDog {
public void bark();
}
public interface ICanFly {
public void fly();
}
public class FlyingDog implements IDog, ICanFly {
#Override
public void bark() {
System.out.println("wuff");
}
#Override
public void fly() {
System.out.println("Whuiiii");
}
public static void main(String[] args) {
FlyingDog flyingDog = new FlyingDog();
// Both works
flyingDog.fly();
flyingDog.bark();
IDog dog = (IDog) flyingDog;
// Same object but does not work, compile error
dog.fly();
ICanFly canFly = (ICanFly) flyingDog;
// Same object but does not work, compile error
canFly.bark();
}
}
And now an extending class.
public class LoudDog implements IDog {
#Override
public void bark() {
System.out.println("WUUUUFF");
}
// Does not work, compile error as IDog does not declare this method
#Override
public void fly() {
System.out.println("I wanna fly :(");
}
}
In the end, be aware that if others know that their IDog actually is a FlyingDog (and they cast it), then they must be able to call fly() as a FlyingDog must can fly. Furthermore, they must be able to override the behavior as long as they follow the specification of fly() given by its method-signature. Imagine a subclass called PoorFlyingDog, he needs to override the default behavior, else he can perfectly fly, but he is a poor flyer.
Summarized: Hide to others that you're actually a DoJump, also hide that you are a Doable, pretend to only be a NotDoable. Or with the animals, pretend to only be an IDog instead of a FlyingDog or ICanFly. If the others don't cheat (casting), they won't be able to use fly() on you, though you actually can fly.
Add final to DoJump declaration to prevent this class to be overriden (and therefore doSomething() to be overriden too).
public final class DoJump implements Doable {
#Override
public void doSomething() {
fireJumpHandler();
}
}
If you still need to be able to inherit DoJump but you don't want doSomething() to be overriden, put the final modifier in the method signature
public class DoJump implements Doable {
#Override
public final void doSomething() {
fireJumpHandler();
}
}
I would like to prevent a class from calling its own method. The method shall only be callable by its super class.
Right now, I cannot think of any way to achieve this (cleanly). But maybe someone knows a solution?
In code:
public abstract class A {
protected abstract void foo();
private void barA() {
//do smth
foo();
}
}
public class B extends A {
#Override
protected void foo() {
//do smth
}
private void barB() {
//must not be able to call foo() here
}
}
Edit: the explanation why I would like to do this:
A is lets say a vehicle. B can be a car or an airplane. The method foo() would be startEngines(). -> I want to make sure that the engines can only be started by calling the method barA().... does that make any sense?
There is a way to do it, but you need to use Google Error Prone. This is an extension of the Java compiler that aims to provide more and more helpful warnings and errors (similar to FindBugs and PMD, but with less false alarms). I can only recommend it, it has already helped us to find some bugs.
Specifically, it contains an annotation #ForOverride and an according compile-time check. This annotation is meant to be used for protected methods that the sub-class and any other class should not call, but only the defining class.
So using
public abstract class A {
#ForOverride
protected abstract void foo();
private void barA() {
//do smth
foo();
}
}
would exactly achieve what you want.
You can integrate Error Prone into most build systems like Maven and Ant. Of course, it won't help if somebody compiles your source without Error Prone (for example in Eclipse), but using it in a continous-integration system would still allow you to find such issues. The source code still stays compatible with regular Java compilers (provided you have error_prone_annotations.jar on the class path), other compilers will simply not do the additional checks.
this answer has a good hint.
add below method in your class (class B):
public static String getMethodName(final int depth)
{
final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
return ste[ste.length - 1 - depth].getMethodName();
}
and change the foo method in class B to this:
#Override
protected void foo() {
//....
if (getMethodName(0)=="barB"){
// tell you are not able to call barB
}
}
Considering your vehicle and engine scenario, I think you need to reconsider your design a bit.
Your vehicle could be a car, aeroplane, etc but car, aeroplane, ... each have separate engines and therefore different startEngine method. So declare your class vehicle as abstract like you did and class startEngine as abstract method . Next , subclass Vehicle and implement startEngine in them , now you can invoke startEngine on the subclass instances
abstract class Vehicle{
abstract void startEngine();
}
public class Car extends Vehicle{
public void startEngine(){
//implementation
}
public static void main(String[] arg){
Vehicle v=new Car();
v.startEngine();
}
}
Add Anonymouse inner class to barA method via Interface, so you will need to implement a method for foo() (functional interface). It won't be part of Class B.
you could put an interface as a member in the super class given to it via the constructor. the child class implements the method but can't call it except by making it static.
interface Foo {
void stopEngines();
void startEngines();
}
abstract class Base {
final private Foo foo;
public Base(final Foo foo) {
this.foo = foo;
}
private void barA() {
// do smth
foo.startEngines();
}
}
class Child extends Base {
public Child() {
super(new Foo() {
boolean engineRunning;
#Override
public void stopEngines() {
this.engineRunning = false;
}
#Override
public void startEngines() {
this.engineRunning = true;
}
});
}
private void barB() {
// can't call startEngines() or stopEngines() here
}
}
class Child2 extends Base {
public Child2() {
super(new Foo() {
#Override
public void stopEngines() {
stopEngines();
}
#Override
public void startEngines() {
startEngines();
}
});
}
static void stopEngines() {
// influence some static state?
}
static void startEngines() {
// influence some static state?
}
private void barB() {
// can call stopEngines() and startEngines(), but at least they have to be static
}
}
Of course, this is not really what you asked for, but about as much as you can do about it in Java, I guess.
Seeing the startEngines explanation, this solution might even suffice.
I guess you wouldn't care about the class calling its static methods, since they can only influence a static state, which is used seldom. The methods within the anonymous interface implementation can mutually call each other, but I guess that would be OK, since you only seem to be trying to prevent others to start the engines in some different way.
I guess this is similar to the problem AWT/Swing has with overriding the paint(Graphics g) method on a component (or onCreate(..) in Android Activities). Here you are overriding the paint method but you should never call it.
I think the best thing you can do is add documentation to the method to clarify that it should never be explicitly called by the subclasses OR re-evaluate your design.
I've some class with these methods:
public class TestClass
{
public void method1()
{
// this method will be used for consuming MyClass1
}
public void method2()
{
// this method will be used for consuming MyClass2
}
}
and classes:
public class MyClass1
{
}
public class MyClass2
{
}
and I want HashMap<Class<?>, "question"> where I would store (key: class, value: method) pairs like this ( class "type" is associated with method )
hashmp.add(Myclass1.class, "question");
and I want to know how to add method references to HashMap (replace "question").
p.s. I've come from C# where I simply write Dictionary<Type, Action> :)
Now that Java 8 is out I thought I'd update this question with how to do this in Java 8.
package com.sandbox;
import java.util.HashMap;
import java.util.Map;
public class Sandbox {
public static void main(String[] args) {
Map<Class, Runnable> dict = new HashMap<>();
MyClass1 myClass1 = new MyClass1();
dict.put(MyClass1.class, myClass1::sideEffects);
MyClass2 myClass2 = new MyClass2();
dict.put(MyClass2.class, myClass2::sideEffects);
for (Map.Entry<Class, Runnable> classRunnableEntry : dict.entrySet()) {
System.out.println("Running a method from " + classRunnableEntry.getKey().getName());
classRunnableEntry.getValue().run();
}
}
public static class MyClass1 {
public void sideEffects() {
System.out.println("MyClass1");
}
}
public static class MyClass2 {
public void sideEffects() {
System.out.println("MyClass2");
}
}
}
This is feature which is likely to be Java 8. For now the simplest way to do this is to use reflection.
public class TestClass {
public void method(MyClass1 o) {
// this method will be used for consuming MyClass1
}
public void method(MyClass2 o) {
// this method will be used for consuming MyClass2
}
}
and call it using
Method m = TestClass.class.getMethod("method", type);
Method method = TestClass.class.getMethod("method name", type)
Use interfaces instead of function pointers. So define an interface which defines the function you want to call and then call the interface as in example above. To implement the interface you can use anonymous inner class.
void DoSomething(IQuestion param) {
// ...
param.question();
}
You mention in the code comment that each method consumes an object of a certain type. Since this is a common operation, Java already provides you with a functional interface called Consumer that acts as a way to take an object of a certain type as input and do some action on it (two words so far that you already mentioned in the question: "consume" and "action").
The map can therefore hold entries where the key is a class such as MyClass1 and MyClass2, and the value is a consumer of objects of that class:
Map<Class<T>, Consumer<T>> consumersMap = new HashMap<>();
Since a Consumer is a functional interface, i.e. an interface with only one abstract method, it can be defined using a lambda expression:
Consumer<T> consumer = t -> testClass.methodForTypeT(t);
where testClass is an instance of TestClass.
Since this lambda does nothing but call an existing method methodForTypeT, you can use a method reference directly:
Consumer<T> consumer = testClass::methodForTypeT;
Then, if you change the signatures of the methods of TestClass to be method1(MyClass1 obj) and method2(MyClass2 obj), you would be able to add these method references to the map:
consumersMap.put(MyClass1.class, testClass::method1);
consumersMap.put(MyClass2.class, testClass::method2);
While you can store java.lang.reflect.Method objects in your map, I would advise against this: you still need to pass the object that is used as the this reference upon invocation, and using raw strings for method names may pose problems in refactoring.
The cannonical way of doing this is to extract an interface (or use an existing one) and use anonymous classes for storing:
map.add(MyClass1.class, new Runnable() {
public void run() {
MyClass1.staticMethod();
}
});
I must admit that this is much more verbose than the C#-variant, but it is Java's common practice - e.g. when doing event handling with Listeners. However, other languages that build upon the JVM usually have shorthand notations for such handlers. By using the interface-approach, your code is compatible with Groovy, Jython, or JRuby and it is still typesafe.
To answer your direct question regarding using a Map, your proposed classes would be:
interface Question {} // marker interface, not needed but illustrative
public class MyClass1 implements Question {}
public class MyClass2 implements Question {}
public class TestClass {
public void method1(MyClass1 obj) {
System.out.println("You called the method for MyClass1!");
}
public void method2(MyClass2 obj) {
System.out.println("You called the method for MyClass2!");
}
}
Then your Map would be:
Map<Class<? extends Question>, Consumer<Question>> map = new HashMap<>();
and populated like this:
TestClass tester = new TestClass();
map.put(MyClass1.class, o -> tester.method1((MyClass1)o)); // cast needed - see below
map.put(MyClass2.class, o -> tester.method2((MyClass2)o));
and used like this:
Question question = new MyClass1();
map.get(question.getClass()).accept(question); // calls method1
The above works OK, but the problem is that there's no way to connect the type of the key of the map with the type of its value, ie you can't use generics to properly type the value of the consumer and so use a method reference:
map.put(MyClass1.class, tester::method1); // compile error
that's why you need to cast the object in the lambda to bind to the correct method.
There's also another problem. If someone creates a new Question class, you don't know until runtime that there isn't an entry in the Map for that class, and you have to write code like if (!map.containsKey(question.getClass())) { // explode } to handle that eventuality.
But there is an alternative...
There is another pattern that does give you compile time safety, and means you don't need to write any code to handle "missing entries". The pattern is called Double Dispatch (which is part of the Visitor pattern).
It looks like this:
interface Tester {
void consume(MyClass1 obj);
void consume(MyClass2 obj);
}
interface Question {
void accept(Tester tester);
}
public class TestClass implements Tester {
public void consume(MyClass1 obj) {
System.out.println("You called the method for MyClass1!");
}
public void consume(MyClass2 obj) {
System.out.println("You called the method for MyClass2!");
}
}
public class MyClass1 implements Question {
// other fields and methods
public void accept(Tester tester) {
tester.consume(this);
}
}
public class MyClass2 implements Question {
// other fields and methods
public void accept(Tester tester) {
tester.consume(this);
}
}
And to use it:
Tester tester = new TestClass();
Question question = new MyClass1();
question.accept(tester);
or for many questions:
List<Question> questions = Arrays.asList(new MyClass1(), new MyClass2());
questions.forEach(q -> q.accept(tester));
This pattern works by putting a callback into the target class, which can bind to the correct method for handling that class for the this object.
The benefit of this pattern is if another Question class is created, it is required to implement the accept(Tester) method, so the Question implementer will not forget to implement the callback to the Tester, and automatically checks that Testers can handle the new implementation, eg
public class MyClass3 implements Question {
public void accept(Tester tester) { // Questions must implement this method
tester.consume(this); // compile error if Tester can't handle MyClass3 objects
}
}
Also note how the two classes don't reference each other - they only reference the interface, so there's total decoupling between Tester and Question implementations (which makes unit testing/mocking easier too).
Have you tried Method object? refer:
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/reflect/Method.html
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getMethod%28java.lang.String,%20java.lang.Class...%29
Your question
Given your classes with some methods:
public class MyClass1 {
public void boo() {
System.err.println("Boo!");
}
}
and
public class MyClass2 {
public void yay(final String param) {
System.err.println("Yay, "+param);
}
}
Then you can get the methods via reflection:
Method method=MyClass1.class.getMethod("boo")
When calling a method, you need to pass a class instance:
final MyClass1 instance1=new MyClass1();
method.invoke(instance1);
To put it together:
public class Main {
public static void main(final String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
final Map<Class<?>,Method> methods=new HashMap<Class<?>,Method>();
methods.put(MyClass1.class,MyClass1.class.getMethod("boo"));
methods.put(MyClass2.class,MyClass2.class.getMethod("yay",String.class));
final MyClass1 instance1=new MyClass1();
methods.get(MyClass1.class).invoke(instance1);
final MyClass2 instance2=new MyClass2();
methods.get(MyClass2.class).invoke(instance2,"example param");
}
}
Gives:
Boo!
Yay, example param
Watch out for the following gotchas:
hardcoded method name as a string - this is very hard to avoid
it is reflection, so accessing to the metadata of the class in runtime. Prone to a lot of exceptions (not handled in the example)
you need to tell not only the method name, but the parameter types as well to access to one method. This is because method overloading is standard, and this is the only way to pick the right overloaded method.
watch out when calling a method with parameters: there is no compile time parameter type check.
An alternative answer
I guess what you're looking for is a simple listener: i.e. a way to call a method from another class indirectly.
public class MyClass1 implements ActionListener {
#Override
public void actionPerformed(final ActionEvent e) {
System.err.println("Boo!");
}
}
and
public class MyClass2 implements ActionListener {
#Override
public void actionPerformed(final ActionEvent e) {
System.err.println("Yay");
}
}
using as:
public class Main {
public static void main(final String[] args) {
final MyClass1 instance1=new MyClass1();
final MyClass2 instance2=new MyClass2();
final Map<Class<?>,ActionListener> methods=new HashMap<Class<?>,ActionListener>();
methods.put(MyClass1.class,instance1);
methods.put(MyClass2.class,instance2);
methods.get(MyClass1.class).actionPerformed(null);
methods.get(MyClass2.class).actionPerformed(null);
}
}
This is called the listener pattern. I dared to reuse the ActionListener from Java Swing, but in fact you can very easily make your own listeners by declaring an interface with a method. MyClass1, MyClass2 will implement the method, and then you can call it just like a... method.
No reflection, no hardcoded strings, no mess. (The ActionListener allows passing one parameter, which is tuned for GUI apps. In my example I just pass null.)
public class Testing extends JDialog {
public MyClass myClass;
public Testing() {
}
}
given the above code, is it possible to override a method in myClass in Testing class?
say myClass has a method named computeCode(), will it be possible for me to override it's implementations in Testing? sorry it's been a long time since I've coded.
if you want to override a method from MyClass then your testing class must extend that. for overriding a method one must complete IS-A relationship whereas your code comes under HAS-A relationship.
Yes, it is generally possible (note that as others have correctly mentioned - you'd need to extend it to override the method). Refer to this sample:
public class Animal {
public void testInstanceMethod() {
System.out.println("The instance method in Animal.");
}
}
public class Cat extends Animal {
public void testInstanceMethod() {
System.out.println("The instance method in Cat.");
}
public static void main(String[] args) {
Cat myCat = new Cat();
Animal myAnimal = myCat;
myAnimal.testInstanceMethod();
}
}
Not only is it possible, but it is a key feature in polymorphism an code reusability.
Note, however, that MyClass.computeCode might be final - in this case, it cannot be overridden.
You override methods of classes that you extend. Therefore, in your example your Testing class could override the various existing methods of JDialog. If you wanted to override computeCode() from MyClass (assuming it's not final), you should make Testing extend MyClass.
public class Testing extends MyClass
{
#Override
public int computeCode()
{
return 1;
}
}
You can override a class's method only in a subclass (a class that extends the class whose method you want to override). However, given your skeletal code, you can (within Testing) have a nested class that extends MyClass and force an instance of that nested class into the myClass instance variable... so, the answer must be "yes".
Whether that's the best choice (as opposed to using interfaces, rather than subclassing concrete classes, and relying on Dependency Injection to get the implementations most suited for your testing), that's a different question (and my answer would be, unless you're testing legacy code that you can't seriously refactor until it's well test-covered... then, probably not;-).
See, if you want to override method from MyClass then you need to extend it.
As per your code, it seems you want to make a wrapper wround MyClass.
Wrapper means, calling implemented class method will call method of MyClass.
I am just clearing how wrapping works as below.
public class Testing extends JDialog {
public MyClass myClass;
public Testing() {
}
public void someMethod() {
//Add some more logic you want...
...
..
myClass.computeCode();
}
}
thanks.
The wording of the question is confused and lost.
Here are some key points:
You can't #Override something that you didn't inherit to begin with
You can't #Override something that is final
Here's a small example:
import java.util.*;
public class OverrideExample {
public static void main(String[] args) {
List<String> list = new ArrayList<String>(
Arrays.asList("a", "b", "c")
) {
#Override public String toString() {
return "I'm a list and here are my things : " + super.toString();
}
};
System.out.println(list);
// prints "I'm a list and here are my things : [a, b, c]"
}
}
Here, we have an anonymous class that #Override the toString() method inherited from java.util.ArrayList.
Note that here, it's not class OverrideExample that overrides the ArrayList.toString(); it's the anonymous class that (implicitly) extends ArrayList that does.
All the above answers are valid. But, if you want to extend JDialog but still if you want to override a method of another class it is possible through interfaces. Interfaces won't have method definitions but will have method declarations. More about interfaces, you can read at http://java.sun.com/docs/books/tutorial/java/concepts/interface.html
In your case, you can make use of interface like this
public interface MyInterface{
public void myMethod();
}
public class Testing extends javax.swing.JDialog implements MyIterface{
public void myMethod(){
// code for your method
}
}
Since Testing class has already inherited JDialog, there is no way let it inherit MyClass again unless to implement an interface. What you can do is to use some design pattern. However this is not overriding, since there is no inheritance. The Adapter is the one you need. Again you are losing the flexibility of polymorphism.
public class Testing extends JDialog {
MyClass myClass = new MyClass();
public Testing() {
}
public void methodA(){
myClass.methodA();
}
}
class MyClass {
public void methodA(){}
}
public interface Foo {
}
public class SpecificFoo implements Foo {
}
public interface SomeInterface {
void thisMethod(Foo someKindOfFoo);
}
public class SomeClass implements SomeInterface {
public void thisMethod(Foo someKindOfFoo) {
// calling code goes into this function
System.out.println("Dont go here please");
}
public void thisMethod(SpecificFoo specificFoo) {
// not into this function
System.out.println("Go here please");
}
}
public class SomeOlderClass {
public SomeOlderClass( SomeInterface inInterface ) {
SpecificFoo myFoo = new SpecificFoo();
inInterface.thisMethod(myFoo);
}
}
calling code:
SomeClass myClass = new SomeClass();
SomeOlderClass olderClass = new SomeOlderClass(myClass);
I have an interface (SomeInterface) that several classes call into (such as SomeOlderClass). I have a class that implements the interface, but I want to do type safe operations on the specific implementations that are passed into the generic interface.
As shown in the above code, I really want to able to make another method that matches the specific type passed in to the interface. This doesn't work. I assume it is because the calling code only knows about the interface, and not the implementation with the more specific methods (even though SpecificFoo implements Foo)
So how can I do this in the most elegant way? I can get the code working by adding an if statement in the class implementing the interface (SomeClass):
public void thisMethod(Foo someKindOfFoo) {
// calling code goes into this function
if ( someKindOfFoo.getClass().equals(SpecificFoo.class) )
thisMethod(SpecificFoo.class.cast(someKindOfFoo));
else
System.out.println("Dont go here please");
}
However, this is not elegant, as I have to add if statements everytime I add a new kind of Foo. And I might forget to do so.
The other option is to add SpecificFoo to the SomeInterface, and let the compiler sort out reminding me that I need implementations in SomeClass. The problem with this is that I end up adding quite a bit of boiler plate code. (If someone else implements the interface, they have to implement the new method, as well as any tests)
It seems that there should be another option I am missing, given that Foo and SpecificFoo are related. Ideas?
MORE INFO:
Well I actually worked for a while to try and simplify the question. As I add more details the complexity goes up by quite a bit. But whatever... I think I can explain it.
Basically, I am write a GWT web apps RPC servlet using the command pattern as explained by Ray Ryan in his talk
There are several implementations of it on google code, but many of them suffer this inherit problem. I thought it was a bug in the GWT-RPC code bugreport HOWEVER, as I was implementing further I noticed a similar problem happening purely on the client side, and while in hosted mode. (ie all java, no gwt javascript madness).
So I abstracted the basic ideas to a raw java command line case, and saw the same issue, as described above.
If you follow along with what Ray Ryan discusses, Foo is an Action, SpecificFoo is a specific action I want to call. SomeInterface is the client side RPC service and SomeClass is the server side RPC class. SomeOlderClass is a kind of rpc service that would know about cacheing and whatnot.
Obvious, right? Well as I said, I think all the GWT RPC nonsense just muddies up the waters on the base issue, which is why I tried to simplify it as best I could.
If you need to find out the actual type of an object at runtime, then the design is most probably wrong. That violates at least the Open Closed Principle and Dependency Inversion Principle.
(Because Java does not have multiple dispatch, the thisMethod(Foo)will be called instead of thisMethod(SpecificFoo). Double dispatch could be used to get around the language's limitations, but there might still be some design problem lurking there...)
Please give more information on what you are trying to accomplish. Right now the question does not provide enough information to come up with a right design.
A generic solution is that since the action depends on the runtime type of Foo, that method should be part of Foo so that its implementation can vary depending on Foo's type. So your example would be changed to something like below (possibly adding SomeInterface or other parameters to thisMethod()).
public interface Foo {
void thisMethod();
}
public class SpecificFoo implements Foo {
public void thisMethod() {
System.out.println("Go here please");
}
}
Try using double dispatch: Add a method to the Foo interface that is called by SomeClass#thisMethod. Then place the code in the implementation of this method.
public interface Foo {
public void thatMethod(SomeClass a);
public void thatMethod(SomeOlderClass a);
}
public class SomeClass implements SomeInterface {
public void thisMethod(Foo someKindOfFoo) {
someKindOfFoo.thatMethod(this);
}
}
Sorry, I find the problem description far too abstract to be able to make a recommendation. You clearly have a design issue because you generally should not need to check the type of interface. I will give it a go though... First, I need to make your problem more concrete for my small brain to understand. Instead of Foos, how about Birds?
public interface Bird {
}
public class Ostrich implements Bird {
}
public interface BirdManager {
void fly(Bird bird);
}
public class AdvancedBirdManager implements BirdManager {
public void fly(Bird bird) {
System.out.println("I am in the air. Yay!");
}
public void fly(Ostrich ostrich) {
System.out.println("Sigh... I can't fly.");
}
}
public class ZooSimulation {
public ZooSimulation(BirdManager birdManager) {
Ostrich ostrich = new Ostrich();
birdManager.fly(ostrich);
}
}
public static void main(String[] args) {
AdvancedBirdManager advancedBirdManager = new AdvancedBirdManager();
ZooSimulation zooSimulation = new ZooSimulation(advancedBirdManager);
}
Here, the Ostrich will declare "I am in the air. Yay!" which is not what we want.
OK, so, ignoring the fact that I am failing basic OO here, the problem is that the BirdManager will look for the least-specific method that matches the type that is passed in. So no matter what kind of bird I give it, it will always match fly(Bird). We can put some if checks in there, but as you add more types of birds, your design will degrade further. Here's the tough part - I have no idea if this makes sense within the context of your problem, but consider this refactoring where I move the logic from the manager into bird:
public interface Bird {
void fly();
}
public class BasicBird implements Bird {
public void fly() {
System.out.println("I am in the air. Yay!");
}
}
public class Ostrich implements Bird {
public void fly() {
System.out.println("Sigh... I can't fly.");
}
}
public interface BirdManager {
void fly(Bird bird);
}
public class AdvancedBirdManager implements BirdManager {
public void fly(Bird bird) {
bird.fly();
}
}
public class ZooSimulation {
public ZooSimulation(BirdManager birdManager) {
Ostrich ostrich = new Ostrich();
birdManager.fly(ostrich);
}
}
public static void main(String[] args) {
AdvancedBirdManager advancedBirdManager = new AdvancedBirdManager();
ZooSimulation zooSimulation = new ZooSimulation(advancedBirdManager);
}
Our Ostrich now says the correct thing and the bird manager still treats it as just a bird. Again, bad OO (Ostriches should not have fly() methods) but it illustrates my thoughts.
As long as there are not too many implementations of Foo, I would declare an abstract method in SomeInterface for each subclass of Foo, and have an abstract class forward calls to a default method that is defined for the most general type:
public interface Foo {
}
public class SpecificFoo implements Foo {
}
public interface SomeInterface {
void thisMethod(Foo someKindOfFoo);
void thisMethod(SpecificFoo specificFoo);
void thisMethod(OtherSpecificFoo otherSpecificFoo);
}
public abstract class AbstractSomeInterface {
public void thisMethod(Foo wrongFoo) {
throw new IllegalArgumentException("Wrong kind of Foo!");
}
public void thisMethod(SpecificFoo specificFoo) {
this.thisMethod((Foo) specificFoo);
}
public void thisMethod(OtherSpecificFoo otherSpecificFoo) {
this.thisMethod((Foo) specificFoo);
}
}
public class SomeClass extends AbstractSomeInterface {
public void thisMethod(SpecificFoo specificFoo) {
// calling code goes into this function
System.out.println("Go here please");
}
}
public class SomeOlderClass {
public SomeOlderClass( SomeInterface inInterface ) {
SpecificFoo myFoo = new SpecificFoo();
inInterface.thisMethod(myFoo);
}
}