I Have something similar to this setup:
public class Base {
public String getApple() {return "base apple"};
}
public class Extended extends Base{
public String getApple() {return "extended apple"};
}
Somewhere else in the code I have this:
{
Base b = info.getForm();
if (b instanceof Extended){
b = (Extended) b;
}
System.out.println(b.getApple()); // returns "base apple" even when if clause is true why??
}
How do I accomplish that?
First:
if (b instanceof Extended){
b = (Extended) b;
}
does absolutely nothing. You are basically saying b = b, which says nothing. You are not even changing the reference.
Second, getApple() will always be dynamically bound, and the "extended apple" should always be called - given that the subclass is truly extending the base class, and the method is truly overridden.
Basically what you need to do, in order to accomplish correct getApple() behavior:
remove the if clause. it does nothing.
make sure your class is indeed extending the base class
make sure the getApple() method is overriding the base class method. (use the #override annotation if you are not sure)
As written, your code will not compile, which makes me think that your problem is elsewhere. Your return statements don't have semicolons at the end of them. Rather, they appear after the }. It's possible you had some other problem (maybe your subclass misspelled getApple()), but you're still using your old class files because your new stuff isn't compiling.
This code works:
class Base {
public String getApple() { return "base apple"; }
}
class Extended extends Base {
public String getApple() { return "extended apple"; }
}
public class Test {
public static void main(String[] args) {
Base b = new Extended();
System.out.println(b.getApple());
}
}
Console:
#javac Test.java
#java Test
extended apple
First of all, that if block should never be necessary. It's basically a no-op.
Second, this isn't your real code, because it doesn't even compile. You're missing semicolons after the return statements.
I suspect that your problem is that your real code has a typo that's making the signatures of the two getApple methods different. This means that Extended has two methods: the one inherited from Base and the one with a different signature in itself. Since you're calling with the signature of the Base.getApple method, you're always getting that behavior. This is only a guess though, as your posted code does not exhibit the problem you describe.
Yuval is right that your cast in the if block has no effect. You might try combining your last statement with the if:
if (b instanceof Extended)
{
// Prints "extended apple" if reached.
System.out.println(((Extended)b).getApple());
}
Add #Override to the method in your subclass and recompile. This will help you find out if you're not actually overriding the method you think you are.
i.e.
public class Base {
public String getApple() {return "base apple";}
}
public class Extended extends Base{
#Override
public String getApple() {return "extended apple";}
}
The only way to get that behavior is to return super.getApple() in your extended class, which is effectively the same as not overriding it in the first place. The only way this could help is if you pass in an argument to decide which to return. Not saying thats good design...
Forgot to mention that, as Yuval said, the cast does nothing to the object.
You should investigate what is constructing your instance that is returned from info.getForm(). You may want to make the Base abstract to prevent it from being instantiated and you'll quickly see where construction is happening.
Are you sure your code example provided in your question EXACTLY matches the code your are using? The reason I ask is that the behavior you are describing happens when you access a public FIELD instead of a public METHOD with an object pointer.
For example:
public class BaseClass {
public String baseField;
public BaseClass() {
baseField = "base";
}
public String getBaseField() {
return baseField;
}
}
public class SubClass extends BaseClass {
public String baseField;
public SubClass () {
baseField = "sub";
}
public String getBaseField() {
return baseField;
}
}
public class MainClass {
public static void main(String[] args) {
BaseClass baseObject = new BaseClass();
SubClass subObject = new SubClass();
System.out.println(baseObject.getBaseField());
System.out.println(subObject.getBaseField());
System.out.println(baseObject.baseField);
System.out.println(subObject.baseField);
System.out.println(((BaseClass)subObect).getBaseField());
System.out.println(((BaseClass)subObect).baseField);
}
}
Will print out:
base
sub
base
sub
sub
base
When you call a method, the JVM will start at the bottom of the inheritance hierarchy and call the appropriate method. When you reference a field instead, it uses the class of the pointer instead of walking up the class hierarchy to resolve the value. The behavior of the field reference matches what you're seeing, which is why I ask for clarification/verification.
Related
Java, in theory, doesn't support member overriding so I was thinking whether this code snippet can be used for overriding members of the class. However, I am not quite sure in what situations this code might fail. I mean, if this works perfectly then it wouldn't go unnoticed right?
It might be a stupid question, but I really want to know what this code might do in different situations which my mind can't think of.
So it will be really great if someone can explain it to me.
Thanks!
class ClassA{
int i = 10;
void eat() {
System.out.println("In Class A: Eating");
}
void bark() {
System.out.println("In Class A: Barking");
}
}
class ClassB extends ClassA{
//int i = 20;
ClassB(){
super.i = 20; //Changing the value of i in class A.
}
void eat() {
System.out.println("In Class B: Eating");
}
}
public class Main{
public static void main(String[] args) {
ClassB b = new ClassB();
System.out.println(b.i);
b.eat();
b.bark();
ClassA ua = new ClassB();
System.out.println(ua.i);
ua.eat();
ua.bark();
ClassA a = new ClassA();
System.out.println(a.i);
}
}
I am not quite sure in what situations this code might fail.
It (sort of) fails on the human reader/conceptual level.
The java language is what it is. This means that java programmers know what to expect, what to do, and what not to do.
And one of the basic rules for inheritance (in java, but also in general): you are extremely cautious regarding fields of your super class(es). Member fields should be considered an internal implementation detail of a class. You don't expose it to the outer world. You don't expose it to your child classes, unless there is a really good reason to do so. And if you really want to do that in java, then the correct way is: using the protected keyword for that field.
Your idea is basically that the child class "knows" about super class fields, and worse: changes that "internal state" at creation time.
Thus, in the real world, such code might quickly lead to all sorts of nasty surprises. Because people in the real world wouldn't expect that a subclass is doing something like, thus they might be really surprised to find "i should be 10, why is it 20" when debugging a problem in a large application.
Long story short: the fact that you can do something doesn't mean that you should do it. To the contrary: good programming is about doing things in "standard" ways that do not surprise your readers.
If you override a method then try to call it from the parent, the parent calls the derived method, even though it wasn't aware of it at definition time.
class A {
public void foo() {
System.out.println("A.foo");
}
public void callFoo() {
this.foo();
}
}
class B {
public void foo() {
System.out.println("B.foo");
}
}
B instance = new B();
instance.callFoo(); // Prints "B.foo"
Now if we try to do the same thing with instance fields, we get the original one.
class A {
public String foo = "A.foo";
public void printFoo() {
System.out.println(this.foo);
}
}
class B {
public String foo = "B.foo";
}
B instance = new B();
instance.printFoo(); // Prints "A.foo"
So we haven't actually overridden anything; we've simply made a new variable that happens to confusingly share the name of an existing one. If it was true overriding, then we would be able to augment the behavior of A methods which use that variable but aren't aware of the subclass.
Simple answer for your question is 'Yes', your eat method of class ClassA is overriding in class ClassB. The easy option to verify, is using #Override annotation.
In a subclass, you can override and overload an instance method. Override means, you are subclass replacing the inherited behavior. Overloading means, you are extending the inherited method.
If you modify your ClassB as follows , it will compile successfully.
class ClassB extends ClassA{
//int i = 20;
ClassB(){
super.i = 20; //Changing the value of i in class A.
}
#Override // **Added line is here**
void eat() {
System.out.println("In Class B: Eating");
}
This isn't exactly the definition of implicit type conversion, but I'm curious how many standards I'm breaking with this one...
I'm creating an abstract class in Java that basically casts its variables depending on a string passed into the constructor.
For example:
public abstract class MyClass {
Object that;
public MyClass(String input){
if("test1".equals(input){
that = new Test1();
}
else{
that = new Test();
}
}
public void doSomething(){
if(that instanceof Test1){
//specific test1 method or variable
} else if(that instanceof Test2)}
//specific test2 method or variable
} else {
//something horrible happened
}
}
}
You see what I'm getting at? Now the problem I run into is that my compiler wants me to explicitly cast that into Test1 or Test2 in the doSomething method - which I understand, as the compiler won't assume that it's a certain object type even though the if statements pretty much guarantee the type.
I guess what I'm getting at is, is this a valid solution?
I have other classes that all basically do the same thing but use two different libraries depending on a simple difference and figure this class can help me easily track and make changes to all of those other objects.
You are right. This is a horrible way to achieve polymorphism in design. Have you considered using a factory? A strategy object? It sounds like what you are trying to achieve can be implemented in a more loosely-coupled way using a combination of these patterns (and perhaps others).
For the polymorphism of doSomething, for example:
interface Thing {
public void doThing();
}
class Test1 implements Thing {
public void doThing() {
// specific Test1 behavior
}
}
class Test2 implements Thing {
public void doThing() {
// specific Test2 behavior
}
}
class MyClass {
Thing _thing;
public void doSomething() {
_thing.doThing(); // a proper polymorphism will take care of the dispatch,
// effectively eliminating usage of `instanceof`
}
}
Of course, you need to unify the behaviors of Test1 and Test2 (and other concrete Thing classes, present and planned) under a set of common interface(s).
PS: This design is commonly known as Strategy Pattern.
I would create a separate class file. So you would have something like this:
1. You abstract "MyClass"
->within "MyClass" define an abstract method call doSomething...this will force the specific implementation of the method to it's subclasses.
2. Test1 would be the implementation of MyClass which would contain the implementation of the doSomething method
3. Create a utility class that does the check "instanceOf" that check should not be in the constructor it belongs in another class.
So in the end you would have 3 class files an Abstract Class, Implementation of the Abstract and a Class that does the "instanceOf" check. I know this sounds like a lot but it's the proper way to design, for what I think you are attempting to do. You should pick up a design patterns book, I think it would help you a lot with questions like these.
The Open-Closed principle would be better satisfied by moving the object creation outside of this class.
Consider changing the constructor to accept an object that implements an interface.
public MyClass {
public MyClass( ITest tester ) { m_tester = tester; }
public void doSomething(){ m_tester.doTest(); }
}
This makes it possible to change the behavior of the class (open to extension) without modifying its code (closed to modification).
The better way to do this is to create an interface which will specify a set of methods that can be guaranteed to be called on the object.
Here's an example:
public interface TestInterface
{
void doTest();
}
Now you can write your classes to implement this interface. This means that you need to provide a full definition for all methods in the interface, in this case doTest().
public class Test implements TestInterface
{
public void doTest()
{
// do Test-specific stuff
}
}
public class Test1 implements TestInterface
{
public void doTest()
{
// do Test1-specific stuff
}
}
Looks really boring and pointless, right? Lots of extra work, I hear you say.
The true value comes in the calling code...
public abstract class MyObject
{
Test that;
// [...]
public void doSomething()
{
that.doTest();
}
}
No if statements, no instanceof, no ugly blocks, nothing. That's all moved to the class definitions, in the common interface method(s) (again, here that is doTest()).
Is it possible to return in a static method a class? I will explain...
I have:
public class A { public static void blah(){} }
public class B { }
I want to create a static method in B witch returns A. So you can do:
A.blah();
And
B.getA().blah();
This, without creating an instance of A. Just use it static methods.
Is this possible?
This is a rebuttal of #irreputable's answer:
public class B {
public static A getA(){ return null; }
}
B.getA().blah(); //works!
It "works", but probably not in the sense that you expect, and certainly not in a useful way. Let's break this down into two parts:
A a = B.getA();
a.blah();
The first statement is returning a (null in this case) instance of A, and the second statement is ignoring that instance and calling A.blah(). So, these statements are actually equivalent to
B.getA();
A.blah();
or (given that getA() is side-effect free), just plain
A.blah();
And here's an example which illustrates this more clearly:
public class A {
public static void blah() { System.err.println("I'm an A"); }
}
public class SubA extends A {
public static void blah() { System.err.println("I'm a SubA"); }
}
public class B {
public static A getA(){ return new SubA(); }
}
B.getA().blah(); //prints "I'm an A".
... and this (I hope) illustrates why this approach doesn't solve the OP's problem.
I'm going to guess that the reason you ask this is that you want B to return many different classes with different behaviours - not just A.
You probably want to use an interface for what you're doing instead.
interface IA {
void blah();
}
public class B {
IA getA1() {
return new IA {
void blah() {
...code...
}
}
}
IA getA2() {
...
}
IA getA3() {
...
}
}
myCallingMethod {
B.getA1().blah();
B.getA2().blah();
B.getA3().blah();
}
No this is not possible. You have two options:
B.getA() returns an instance of
A, and blah() will be a non-static
method.
Directly call A.blah().
People are saying it's impossible, and that's kind of true, but if you use the reflection API you can do something close to that.
Here's how you could do it.
You have a class that does this.
public class B {
Class a
public static Class getA(){
return a;
}
}
then to call blah you do:
try{
Method m = B.getA().getDeclaredMethod("blah");
m.invoke(null);//for a static method, you can invoke on null
}
Catch(Exception e){
// see documentation for list of exceptions
}
So, why would you want to do this? Well, if you do it this way you can change the class A at So getA() could return A, B, C or D, all with different blah() functions. I'm not really sure what purpose that would serve, but if you want to do it, you can.
see:
Class.getDeclaredMethod() and Method.invoke() for more info.
I haven't tried this, so you might need to do some tweaking.
No, this is not possible. You can only return a reference to an instance of a class. The closest you can get to this is to return a reference to a variable of type Class. The question is: why do you want this? What problem are you trying to solve? There may be a better solution.
Even if it would be possible, it won't be of much use. The call A.blah() doesn't create an instance of A. It's a static method with no need for an instance.
And you can't use interfaces to implement static methods. So what should it be good for?
If you don't want to have an instance of A, then let B call blah() directly. I.e.
class B {
void blah() {
A.blah();
}
}
public class B {
public static A getA(){ return null; }
}
B.getA().blah(); //works!
EDIT
It is true that it is equivalent to
B.getA();
A.blah();
Except they look quite different. Imagine you have a chain of these.
I checked out org.apache.commons.cli.OptionBuilder and personly I wouldn't do it that way, but the author has his case. The API is used only in the beginning of a program, in a single thread.
API designers sometimes have to make some magic moves, don't be too judgemental.
You can return a Method using reflection which you can invoke() later.
However, it sounds like you are trying to do something which should be done another way.
Why are you trying to do this?
Why can't Java classes have abstract fields like they can with abstract methods?
For example: I have two classes that extend the same abstract base class. These two classes each have a method that is identical except for a String constant, which happens to be an error message, within them. If fields could be abstract, I could make this constant abstract and pull the method up into the base class. Instead, I have to create an abstract method, called getErrMsg() in this case, that returns the String, override this method in the two derived classes, and then I can pull up the method (which now calls the abstract method).
Why couldn't I just make the field abstract to begin with? Could Java have been designed to allow this?
You can do what you described by having a final field in your abstract class that is initialised in its constructor (untested code):
abstract class Base {
final String errMsg;
Base(String msg) {
errMsg = msg;
}
abstract String doSomething();
}
class Sub extends Base {
Sub() {
super("Sub message");
}
String doSomething() {
return errMsg + " from something";
}
}
If your child class "forgets" to initialise the final through the super constructor the compiler will give a warning an error, just like when an abstract method is not implemented.
I see no point in that. You can move the function to the abstract class and just override some protected field. I don't know if this works with constants but the effect is the same:
public abstract class Abstract {
protected String errorMsg = "";
public String getErrMsg() {
return this.errorMsg;
}
}
public class Foo extends Abstract {
public Foo() {
this.errorMsg = "Foo";
}
}
public class Bar extends Abstract {
public Bar() {
this.errorMsg = "Bar";
}
}
So your point is that you want to enforce the implementation/overriding/whatever of errorMsg in the subclasses? I thought you just wanted to have the method in the base class and didn't know how to deal with the field then.
Obviously it could have been designed to allow this, but under the covers it'd still have to do dynamic dispatch, and hence a method call. Java's design (at least in the early days) was, to some extent, an attempt to be minimalist. That is, the designers tried to avoid adding new features if they could be easily simulated by other features already in the language.
Reading your title, I thought you were referring to abstract instance members; and I couldn't see much use for them. But abstract static members is another matter entirely.
I have often wished that I could declare a method like the following in Java:
public abstract class MyClass {
public static abstract MyClass createInstance();
// more stuff...
}
Basically, I would like to insist that concrete implementations of my parent class provide a static factory method with a specific signature. This would allow me to get a reference to a concrete class with Class.forName() and be certain that I could construct one in a convention of my choosing.
Another option is to define the field as a public (final, if you like) in the base class, and then initialize that field in the constructor of the base class, depending upon which subclass is currently being used. It's a bit shady, in that it introduces a circular dependency. But, at least it's not a dependency that can ever change -- i.e., the subclass will either exist or not exist, but the subclass's methods or fields can not influence the value of field.
public abstract class Base {
public final int field;
public Base() {
if (this instanceof SubClassOne) {
field = 1;
} else if (this instanceof SubClassTwo) {
field = 2;
} else {
// assertion, thrown exception, set to -1, whatever you want to do
// to trigger an error
field = -1;
}
}
}
class One {
public One foo() { return this; }
}
class Two extends One {
public One foo() { return this; }
}
class Three extends Two {
public Object foo() { return this; }
}
public Object foo() { return this; } throws a compilation error. Why is that? Can someone explain why "Object" type is not possible? Is Object the base class of Class One, Two? If So why does it throws an error?
Please change the title of the question as I couldnt find a suitable title.
Three.foo is trying to override Two.foo(), but it doesn't do it properly. Suppose I were to write:
One f = new Three();
One other = f.foo();
Ignoring the fact that actually Three.foo() does return a One, the signature of Three.foo() doesn't guarantee it. Therefore it's not an appropriate override for a method which does have to return a One.
Note that you can change the return type and still override, but it has to be more specific rather than less. In other words, this would be okay:
class Three extends Two {
public Three foo() { return this; }
}
because Three is more specific than One.
You are changing the signature of the foo method in a way not supported. Polymorphism only works for different argument list, not for identical methods only different by the return type.
And if you think about it, it is quite natural... If it worked and someone who only knows about one of the two super classes would call Three.foo() he would expect it to return a One (because that is how it works in One and Two) but in Three you could actually return a HashMap and still behave correctly.
Jon (in the comment below) is correct, you can narrow the scope but then you would still follow the protocol that you will return a "One" (should you return a Three from Three.foo()) because subclasses will all implement the superclass interface.
However, return type is still not part of the polymorphism, hence you cannot have three different methods that only differs by return type.
It would enable:
class Four extends Three {
public Object foo() { return "This String is not an instance of One"; }
}
Overriding a method and trying to return a less specific type is a violation of the Liskov substitution principle, which says that subclasses must fulfill all contracts of their superclass. Your class Three violates the superclass contract "foo() returns an instance of One".