Say I have the following code
public class A {
public void callme() {
System.out.println("Calling of class A function ");
}
}
public class B extends A {
public void callme() {
System.out.println(" Calling of class B fuction ");
}
public void Hello() {
System.out.println("hello guys");
}
}
and a main() that does the following
public class Main {
public static void main(String [] args){
A a = new B();
B b = new B();
b = (B)a;
a.callme();
b.callme();
a.Hello(); // show error : Hello is undefined for method A
}
}
The book says "you get the behavior associated with the object to which the variable refers at runtime". Ok, I get behavior of B class when a method callme is called, but when I access the method Hello, it shows an error that Hello is undefined for method A. why is that?
Polymorphism doesn't work this way. Since A is parent of B, B can inherit methods of A (like son can inherit properties of father), but its not vice versa because A doesn't know which classes are inheriting it (A does not know who are its children.)
For Example, suppose there is one more class C:
public class C extends A {
public void callme(){
System.out.println(" Calling of class C fuction ");
}
public void Hello(){
System.out.println("hello guys, I am C");
}
}
Now, if you use
a.Hello();
how will a know which child class it should call since it does not methods of its child. only its own abstract method, which it knows child will implement for sure.
a is of type A, even if it is referring to an instance of B.
A doesn't have the Hello method (even an abstract declaration). So your compiler emits the error. Adjusting your code slightly to
public abstract class A {
public abstract void Hello();
/*the rest as before*/
would be a fix. A is then assuming the characteristics of an interface.
public class B extends A {
public void callme(){
System.out.println(" Calling of class B fuction ");
}
public void Hello(){ // hello method is only the part of class B not A.
System.out.println("hello guys");
}
}
In above class hello() method is a part of B only. it not override by the method of A.
now in your main method call
public static void main(String [] args){
A a= new B(); // object of b referred by (a) Reference Variable of A
B b= new B(); // object of b referred by (b) Reference Variable of B
b= (B)a;
a.callme(); //override takes place and method of B's Callme() called
b.callme(); //again override takes place here and method of B's Callme() called
a.Hello();// buttttttt
b.Hello(); // this will compile and executes fine.
}
}
Here you used the reference variable of class A which don't have any method name Hello(). So, Method Resolution will not take place(won't be able to find any method like Hello()).
but if you try to call b.Hello() using the reference variable of B then it will work fine to you.
Now suppose there is another class C which is a sub class of A and contains a Method Name Hello().
public class C extends A {
public void Hello(){ // hello method is only the part of class B not A.
System.out.println("hello guys");
}
}
In main a Statement like this
A a = new C();
and if you try to call a.Hello() then which Hello() method will call. Compiler will get confused.
So, This concept work only when you try to override the method of super class in sub Class.
Is the parent class aware of classes derived from it ?
Casting does not change the actual object type. Only the reference type gets changed.
I highly recommend you my upcasting and downcasting writing from the link
Related
Lets deduct from a very simple example:
Class a:
public class a{
public a{}
Subclass b inherits a:
public class b inherits a{
public b{super}
public void customMethodB(){}
Subclass c inherits a:
public class c inherits a{
public c{super}
public void customMethodC(){}
Main:
public class Main{
public static void main(String[] args){
a newObject = null;
//User can now choose through input if he wants to create b or c. Lets say he creates b:
newObject = new b();
//His choice is stored in a string.
String userChoice = b;
//I now call the general object from another method for the user to interact with.
//(I have a feeling it is here my problem is).
}
userInteraction(a newObject, String userChoice){
if (userChoice.equals("b"){
newObject.customMethodB();
}
else if (userChoice.equals("c"){
newObject.customMethodC();
}
}
Here lies my problem: I can not call customMethodB nor customMethodC even though the object is created as b in main. Is this due to the parameter type being a in the userInteraction method? Would it be possible to do something like this without creating a method to pass the specific subclass type?
Your method customMethodB does not exist in your type a.
In order to call this method, you have to cast your object ( down cast is possible here )
if (userChoice.equals("b") && newObject instanceof b){
((b)newObject).customMethodB();
}
public class Temp {
public static void main(String args[]) {
A ref;
B objB = new B();
C objC = new C();
ref = objB;
ref.show();
ref = objC;
ref.show();
}
}
abstract class A {
abstract void show();
{
System.out.println("In Class A");
}
}
class B extends A {
void show() {
System.out.println("In class B");
}
}
class C extends B {
void show() {
System.out.println("In Class C");
}
}
In the above code abstract methods containing a definition of the method. But in books it is stated that an abstract method should contain only the declaration rather definition of that method. When i execute this program it results in the following output without any error. Please explain me how it shows the below output.
In Class A
In Class A
In class B
In Class C
Your abstract class does not contain a definition of the method. Your abstract class contains an abstract method, and an initializer block.
abstract class A {
// Abstract method
abstract void show();
// Initializer block, completely unrelated to show
{
System.out.println("In Class A");
}
}
Initializer blocks run when the object is constructed - similarly to constructors (but you can have more than one, and they can't have arguments). It's exactly the same as if you wrote:
abstract class A {
// Abstract method
abstract void show();
// Constructor
public A()
{
System.out.println("In Class A");
}
}
The output comes from:
A ref;
B objB = new B(); // calls B's constructor, then A's constructor which prints "In Class A"
C objC = new C(); // calls C's constructor, then A's constructor which prints "In Class A"
ref = objB;
ref.show(); // prints "In Class B"
ref = objC;
ref.show(); // prints "In Class C"
This abstact method has no implementation in class A:
abstract void show();
The semi-colon ends the method declaration without an implementation.
The following block is an instance initialization block (which gets executed when creating an isntance of the class, before the code of the constructor is executed), unrelated to the abstract method :
{
System.out.println("In Class A");
}
If you tried to give an implementation to an abstract method, it would look like this and fail to compile :
abstract void show()
{
System.out.println("In Class A");
}
As for the output you got :
In Class A // new B() causes the instance initialziation block of A to be executed before the (default) constructor of A
In Class A // new C() causes the instance initialziation block of A to be executed before the (default) constructor of A
In class B // first ref.show() executes B's show, since you assigned objB to ref
In Class C // second ref.show() executes C's show, since you assigned objC to ref
Say I have Class A and Class B. Class B extends Class A. Class A has one method.
public class notimportant
{
public void one()
{
}
}
public class A extends notimportant
{
public void one()
{
//assume there is a super class making this call legal which doesnt do anything
super.one();
System.out.println("blah");
}
}
public class B extends A
{
}
A var1 = new B();
if I call 'var1.one();' will the output end up being:
"blah"
"blah"
because it creates a local copy of 'one()' in Class B and then reads that which calls 'super()' which leads it up to method 'one()' in Class A OR does it just print
"blah"
because it knows to look directly at Class A
EDIT: Hope that is a lot more clear now.
It will follow the way you have it currently written:
-> New object of class B
-> Call method One on this object
-> First line calls supermethod, proceed to execute it
-> Second line prints out after that
Your code doesn't compile at all though, you might want to clear that up. What's keeping you from testing this yourself?
Here's the new situation as you described it. Everything still works as expected, you just add a layer.
public class C {
public void test() {
System.out.println("Inside C");
}
}
public class B extends C {
public void test() {
super.test();
System.out.println("Inside B");
}
}
public class A extends B {
public static void main(String[] args) {
A obj = new A();
obj.test();
}
}
Output:
Inside C
Inside B
super means your superclass – it's resolved at compile-time.
It does not mean the immediate parent class of whatever the runtime type of this is.
I know that we cannot override static methods in Java, but can someone explain the following code?
class A {
public static void a() {
System.out.println("A.a()");
}
}
class B extends A {
public static void a() {
System.out.println("B.a()");
}
}
How was I able to override method a() in class B?
You didn't override anything here. To see for yourself, Try putting #Override annotation before public static void a() in class B and Java will throw an error.
You just defined a function in class B called a(), which is distinct (no relation whatsoever) from the function a() in class A.
But Because B.a() has the same name as a function in the parent class, it hides A.a() [As pointed by Eng. Fouad]. At runtime, the compiler uses the actual class of the declared reference to determine which method to run. For example,
B b = new B();
b.a() //prints B.a()
A a = (A)b;
a.a() //print A.a(). Uses the declared reference's class to find the method.
You cannot override static methods in Java. Remember static methods and fields are associated with the class, not with the objects. (Although, in some languages like Smalltalk, this is possible).
I found some good answers here: Why doesn't Java allow overriding of static methods?
That's called hiding a method, as stated in the Java tutorial Overriding and Hiding Methods:
If a subclass defines a class method with the same signature as a
class method in the superclass, the method in the subclass hides the
one in the superclass.
static methods are not inherited so its B's separate copy of method
static are related to class not the state of Object
You didn't override the method a(), because static methods are not inherited. If you had put #Override, you would have seen an error.
A.java:10: error: method does not override or implement a method from a supertype
#Override
^
1 error
But that doesn't stop you from defining static methods with the same signature in both classes.
Also, the choice of method to call depends on the declared type of the variable.
B b = null;
b.a(); // (1) prints B.a()
A a = new B();
a.a(); // (2) prints a.a()
At (1), if the system cared about the identity of b, it would throw a NPE. and at (2), the value of a is ignored. Since a is declared as an A, A.a() is called.
Your method is not overridden method. you just try to put #Override annotation before your method in derived class. it will give you a compile time error. so java will not allow you to override static method.
While goblinjuice answer was accepted, I thought the example code could improved:
public class StaticTest {
public static void main(String[] args) {
A.print();
B.print();
System.out.println("-");
A a = new A();
B b = new B();
a.print();
b.print();
System.out.println("-");
A c = b;
c.print();
}
}
class A {
public static void print() {
System.out.println("A");
}
}
class B extends A {
public static void print() {
System.out.println("B");
}
}
Produces:
A
B
-
A
B
-
A
If B had overridden print() it would have write B on the final line.
Static methods will called by its Class name so we don't need to create class object we just cal it with class name so we can't override static
for example
class AClass{
public static void test(){
}
}
class BClass extends AClass{
public static void test(){}
}
class CClass extends BClass{
public static void main(String args[]){
AClass aclass=new AClass();
aclass.test(); // its wrong because static method is called
// by its class name it can't accept object
}
}
we just call it
AClass.test();
means static class can't be overridden
if it's overridden then how to cal it .
Static members belong to class not to any objects. Therefore static methods cannot be overriden. Also overiding happens at run time therefore compiler will not complain.
Howeve, you can add #Override annotation to method. This will flag compiler error.
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());
}
}