I am extending a class but I am not able to figure out why the JVM decides only at runtime which method to call. I mean when I do A obj=new B();, isn't it obvious that the method in B will be called ?
Maybe it is not obvious for compiler but I want to know the details.
Code is as follows :
class A
{
String getName(String name) {
return "super";
}
}
class B extends A
{
#Override
String getName(String name) {
return "sub";
}
}
public class Overload
{
public static void main(String args[]) {
A obj=new B();
System.out.println(obj.getName(null));
}
}
A compiler can only able to check their types and it's functionality is limited. Hence it cannot actually run and see the program output. That is why it belong to run time.
Compiler check it's type, and runtime bind it's functionality.
You know it holds a reference of B, because the complexity of code here is simple.
What if you had class 'C' also extending from class 'A' and if the responsibility of initializing obj is with some other class or may be some config.
Unlike as in compile-type polymorphism where we as well as the compiler can see the single statement and decide which method can be called.
Lets see this scenario:
public abstract class A {
public abstract void sayHello();
}
public class B extends A{
public void sayHello(){
System.out.println("B says Hello!");
}
}
public class C extends A{
public void sayHello(){
System.out.println("C says Hello!");
}
}
public class FactoryA{
public static A getInstance(String type){
if("B".equals(type)){
return new B();
}
else if("C".equals(type)){
return new C();
}
}
}
Lets say that now you ask the factory to get instance based on the String parameter, like this:
A a = FactoryA.getInstance("B"); // the string can come user-input
a.sayHello();
In this output will be "B says Hello!", because the instance you get from Factory's method is an instance of B, which depends on the String parameter passed to it.
In this case it may not be known at the run time which method will be called (B's sayHello() or C's sayHello()). That's why it is called runtime polymorphism.
Because the decision was taken at runtime.
Related
I came across the following Java code that uses generics and inheritance. I truly do not understand what the following snippet does:
class A<B extends A<B>> {
...
}
What does this code do?
(I got this from DBMaker in MapDB)
It is almost clear and the question actually conists in two parts:
1) why B extends A?
2) why A inside B extends A<B> has generic type B?
Answers for these parts will be:
1) In particular example this class (A) is builder class (called DBMaker), so most of its methods return some type, which extends this builder's class type. This explains, why B should extend A class.
2) But, actualy, if we will hide for the second part ...extends A<B>, we will receive just class A<B>. So A has type variable of type B. That is why in ...extends A<B> A is marked as type A having type variable B.
This tells that A needs derived definitions to be able to do some work:
public abstract class A<T extends A<T>> {
protected T instance;
T getOne() {
return instance;
}
}
public class B extends A<B> {
public B() {
instance = this;
}
}
public static void test() {
B b = new B();
b.getOne();
}
This is most commonly used in interface definitions, where one wants to explicitly use instances of classes implementing an interface in return types or in arguments and not the interface itself:
public interface TimeSeries<T extends TimeSeries<T>> {
T join(T ts);
}
public class DoubleTimeSeries implements TimeSeries<DoubleTimeSeries> {
#Override
public DoubleTimeSeries join(DoubleTimeSeries ts) {
return null;
}
}
So I did some tests to figure this one out, and here is my test cases to see how one could use such a generic case:
public class A<B extends A<B>> {
int x = 10;
B test;
void printX() {
System.out.println(x);
}
void setB(B b) {
test = b;
}
void printB() {
System.out.println(test);
}
}
public class B extends A<B> {
}
public class Run {
public static void main(String[] args) {
A<B> test = new A<B>();
B myB = new B();
test.printX();
test.setB(myB);
test.printB();
myB.printB();
}
}
I hope the code might be self explanatory. If not leave a comment and I will try and explain what is going on. Look at the last line, myB.printB(), here we will get a null, because B has not yet been set for myB, but only for test. This demonstrates that we can have an infinite recursion into classes of B inside A (and inside B for that matter).
we can say:
myB.test.printB();
This will get an error (null pointer), but shows that we now have access to test in the A class from B, and we can go as deep as we want recursively with as many cases as we like. So the A class kind of functions as a wrapper of infinitely many B classes. Does this make sense?
This makes it easier when defining method return types such as this:
class A<B extends A<B>> {
public B getMe(){
return (B) this;
}
}
This tells Java compiler that you are in getMe() method returning a subclass of class A.
class C extends A<C> {
}
C c = new C();
c.getMe(); //returns C
Is it possible in Java to invoke an overridable method in such a way that it always executes the "locally defined" version rather than an overridden version from a subclass? I.e. is there an analog to super that refers to this class, rather than the super class?
Let me give a code example to hopefully make it clear what I'm trying to do:
class A {
void foo() {
System.out.println("Foo from A");
}
void bar() {
foo(); // <-- This is the important line!
}
}
class B extends A {
#Override
void foo() {
System.out.println("Foo from B");
}
}
If I do new B().bar(), it will call the bar() method defined in A, which calls foo() as overridden in B to print "Foo from B".
Is there a way that I can force the bar() method to call the foo() method as defined in A rather than B? Just like I can use super.foo() in B to call the foo() method as defined in A? Unfortunately using this.foo() still calls the version of the subclass. Even something like ((A) this).foo() or A.this.foo() doesn't work.
Clearly, I could simply define a private or final version of foo() in A and call that instead. But I am hoping for a solution, where all I do is change the "important line" in the code sample above to a different way of invoking foo() to have it print "Foo from A", preferably without some trick like reflection.
Your object is a B. It isn't an A! Here's an example:
public class Apple {
public void printColor() {
System.out.println("I am red");
}
public void bar() {
printColor();
}
}
Then the subclass:
public class GrannySmithApple extends Apple {
public void printColor() {
System.out.println("I am green");
}
}
GrannySmithApples are green, always (unless they are rotten, but that's a whole other can of bananas)! Once you have a GrannySmithApple, it's not an Apple anymore, except in the sense that you can do all the same things with it that you could a regular Apple (printColor, eat, etc.) Make sense? And anything that hasn't changed between the conversion from regular Apple to GrannySmithApple is obviously still the same.
You can have an "internal" foo() in A that is called.
class A {
private void fooInternal() {
System.out.println("Foo from A");
}
void foo() {
fooInternal();
}
void bar() {
fooInternal();
}
}
class B extends A {
#Override
void foo() {
System.out.println("Foo from B");
}
}
new B().bar() will now print "Foo from A" while new B().foo() will print "Foo from B".
Either make your methods static (baadddddd), either change your design.
Indeed, it makes no sense to provide the default behavior for a subclass that it is defined to adapt itself to the concerned method.
As your foo() method seems to vary, you may implement a Strategy Pattern like this:
interface BarProcess{
void foo();
}
public class DefaultBarProcess implements BarProcess{
void foo() {
System.out.println("Foo from A");
}
}
public class AnotherBarProcess implements BarProcess{
void foo() {
System.out.println("Foo from B");
}
}
class A {
private BarProcess barProcess;
public A(Bar barProcess){
this.barProcess = barProcess;
}
void bar() {
barProcess.foo();
}
}
class B extends A { //deprecated! No need to exist
}
As far as I know, a B object will always call its own foo() method. With that said, B.foo() can be defined to call the superclass' foo() method. For example, you could define B as follows:
class B extends A {
#Override public void foo() {
super.foo();
}
}
And doing so will have B call foo from A. But doing so will have it always do so.
There is this Rule of Thumb:
In Inheritance the most specific version of the method for that class is called.
- So it will be always the foo() method of Class B that will be called, if its called on an instance of B.
- Still if you want the foo() method of Class A to be called using your above mentioned code then you will need the super keyword.
Eg:
class B extends A {
#Override
void foo() {
super.foo();
}
}
foo() always invokes instance method of the class used in new ... statement.
In short I think that the answer to your question is NO, it can't be done. It would prevent you from overriding parts of behaviour completely.
class A {
method1() {
...
method2();
...
}
class B extends A {
// You can override method2 here to change the behaviour of method1
// because it will call **your** version of method2
// You **don't** have to override method1 to achieve that
method2() {
...
}
}
this references "this object", not "this class".
That means if you have an object B that extends A, when it executes a method in the superclass A that mentions this, it will actually point to the instance of B, so will execute the method on B.
You can think of the method in A as a default method. If the method is overridden in your actual object B, then it will always be called instead.
I suggest you change your design and use composition instead of inheritance: that would ensure a clear separation of concern, and make your code a lot easier to understand and test.
As others have stated there is no direct way to do it but you might consider a variant of this construct:
void bar() {
ClassA self = new ClassA();
self.foo(); // <-- This is the important line!
}
Can private methods be overridden in Java?
If no, then how does the following code work?
class Base{
private void func(){
System.out.println("In Base Class func method !!");
};
}
class Derived extends Base{
public void func(){ // Is this a Method Overriding..????
System.out.println("In Derived Class func method");
}
}
class InheritDemo{
public static void main(String [] args){
Derived d = new Derived();
d.func();
}
}
No, you are not overriding it. You can check by trying to mark it with #Override, or by trying to make a call to super.func();. Both won't work; they throw compiler errors.
Furthermore, check this out:
class Base {
private void func(){
System.out.println("In base func method");
};
public void func2() {
System.out.println("func2");
func();
}
}
class Derived extends Base {
public void func(){ // Is this an overriding method?
System.out.println("In Derived Class func method");
}
}
class InheritDemo {
public static void main(String [] args) {
Derived D = new Derived();
D.func2();
}
}
It will print:
func2
In base func method
When you change func() in Base to public, then it will be an override, and the output will change to:
func2
In Derived Class func method
No, a private method cannot be overridden because the subclass doesn't inherit its parent's private members. You have declared a new method for your subclass that has no relation to the superclass method. One way to look at it is to ask yourself whether it would be legal to write super.func() in the Derived class. There is no way an overriding method would be banned from accessing the method it is overriding, but this would precisely be the case here.
No, it is not. You can mark an override just to make sure like this:
#Override
public void func(){
System.out.println("In Derived Class func method");
}
And in this case it would be a compiler error.
You are not overriding. You cannot override private members, you are merely defining a new method in Derived. Derived has no knowledge Base's implementation of func() since its declared as private. You won't get a compiler error when you define func() in Derived but that is because Derived does not know Base has an implementation of func(). To be clear: it would be incorrect to say you are overriding Base's implementation of func().
In addition to the already correct answer, consider this:
public class Private {
static class A {
public void doStuff() {
System.out.println(getStuff());
}
private String getStuff() {
return "A";
}
}
static class B extends A {
public String getStuff() {
return "B";
}
}
public static void main(String[] args) {
A a = new A();
a.doStuff();
a = new B();
a.doStuff();
B b = new B();
b.doStuff();
}
}
This will print
A
A
A
although B "overrides" getStuff(). As implementation of doStuff() is fixed to calling A#getStuff(), no polymorphism will be triggered.
Nope because if you do something like Base b = new Derived(); you still won't be able to call b.func(). What you're doing is called "hiding".
Since the method is private it is not visible to the other classes.Hence the derived class does not inherit this method.
So this is not the case of overriding
Method hiding will be happening here instead of overriding. like what happens in case of static.
Actually,you are not overriding.Before Java5
an overridden method's return type must match with parent class's method.
But Java 5 introduced a new facility called covariant return type.You can override a method with the same signature but returns a subclass of the object returned. In another words, a method in a subclass can return an object whose type is a subclass of the type returned by the method with the same signature in the superclass.
you can follow this thread :Can overridden methods differ in return type?
The private member of the base class cannot be access by anyone outside of the class and cannot be overridden. The function in the derive class is an independent function that can be access by anywhere.
The code would run the function in the derived class
A private method can never be over ridden. It is always hidden.
In your example - Derived class has one parent class private method and has its own function func. Both are different, and the func is not over ridden. Its a separate independent function.
If you create a new function in parent class calling parent class function, the parent func will be called, if parent class reference is used as opposed in the case of method over ridding
Note : An object defines the members which it has, and a reference defines which it can access
// Method Over ridding case
class Base{
public void func(){
System.out.println("Parent class");
};
public void func1(){
func();
}
}
class Derived extends Base{
public void func(){
System.out.println("Derived class");
}
}
class InheritDemo{
public static void main(String [] args){
Derived d = new Derived();
d.func1(); // Prints Derived class
Base b = new Derived();
b.func1(); // Prints Derived class - no matter parent reference is calling,as there as method is overridden - Check func1() is in parent class, but id doesn't call parent class func() as the compiler finds a func() method over ridden in derived class
}
}
// Method Hidding case - Private and static methods case
class Base{
private void func(){
System.out.println("Parent class");
};
public void func1(){
func()
}
}
class Derived extends Base{
public void func(){ // Is this a Method Overriding..????
System.out.println("Derived class");
}
}
class InheritDemo{
public static void main(String [] args){
Derived d = new Derived();
d.func1(); // Prints Derived class
Base b = new Derived();
b.func1();
// Prints Parent class - the reason is we are using the parent class reference, so compiler is looking for func() and it founds that there is one private class method which is available and is not over ridden, so it will call it. Caution - this won't happen if called using derived class reference.
b.func();
// this prints the Derived class - the compiler is looking func(), as Derived class has only one func() that it is implementing, so it will call that function.
}
}
Read comments in the below code snippet to find the answer.
Sources:
Definition reference:
Credits for the source code example(reference) from the book - "OCA Oracle Certified Associate Java SE 8 Programmer Study Guide Exam 1Z0-808 Book" from 'Jeanne Boyarsky' and 'Scott Selikoff'.
public class Deer {
public Deer() { System.out.print("Deer"); }
public Deer(int age) { System.out.print("DeerAge"); }
private boolean hasHorns() { return false; }
public static void main(String[] args) {
Deer deer = new Reindeer(5);
System.out.println(","+deer.hasHorns());// false is printed.
}
}
class Reindeer extends Deer {
public Reindeer(int age) { System.out.print("Reindeer"); }
private boolean hasHorns() { return true; } // Overriding possible, but is of no use in the below context.
// Below code is added by me for illustration purpose
public static void main(String[] args) {
Deer deer = new Reindeer(5);
//Below line gives compilation error.
//System.out.println(","+deer.hasHorns());
}
}
I need a object B, but i get a object A when i execute 'B.GetByID()'
public class A
{
public A()
{
}
public static A GetSelf()
{
return new A();
}
public static A GetByID()
{
return GetSelf();
}
}
public class B extends A
{
public B()
{
super();
}
public static B GetSelf()
{
return new B();
}
}
B.GetByID(); //returns A, i need B
You can only do that by also creating a B GetByID() method in B. That's somewhat ugly though...
Basically your B.GetByID() call will be resolved to A.GetByID(); nothing in the compiled code will indicate that it was originally B.GetByID(), and the call to GetSelf() within GetByID() will be resolved to A.GetSelf() anyway.
Basically, static methods don't allow for polymorphism in the way you want. I suggest you create an AFactory and a BFactory subclass, and use method overriding in the normal way, with instance methods.
You could add a GetByID method to B, like so:
public class B ... {
public static B GetByID()
{
return GetSelf();
}
}
Your factory method (no matter in which class it's declared) needs to be aware of both, A and B and then make a decision on which class to instantiate. If the caller knows it needs a B, it just can do a new B() anyway, so the factory method has no value there anyway.
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.