Is overloading in inheritance class possible in Java? - java

Is overloading in inheritance class possible in Java? Parent class and Child class contain the same method name, but different parameters. Is this overloading?
class Parent {
public void add(int a) {
System.out.println("I am parent" + a);
}
}
class Child extends Parent {
public void add(long a) {
System.out.println("I am child.");
}
}

Yes. While extending any class, internally it means all accessible behaviour of the parent class will be present or inherited in child class. i.e, so in your case same name with different argument is overloading.

Yes of course, overloading in inheritance class is possible in Java. Java compiler detect that add method has multiple implementations. so according to the parameter java compiler will determines which method has to be executed.
class Parent {
public void add(int a) {
System.out.println("I am parent " + a);
}
}
class Child extends Parent {
public void add(long a) {
System.out.println("I am child.");
}
}
class Demo{
public static void main(String args[]){
Child child = new Child();
child.add(1); // prints "I am parent 1"
child.add(1L); // prints "I am child."
}
}

Yes, In java allow overloading concept which means you can declare different method with Same name and different parameter .In your case You are extending the parent class ,which means all the property of parent class available in child class(child).
Its a overloading:
Child c = new Child();
c.add(1);//it will call the parent method
c.add(1L);//It will call the child method

Related

Why bother using abstract method and overriding while we can always use a generic method in the superclass?

The following is a popular use case involving abstract method and overridding.
class Demo {
public static void main(String[] args) {
Parent a = new Child_A();
Parent b = new Child_B();
a.method();
b.method();
}
}
abstract class Parent {
abstract void method();
}
class Child_A extends Parent {
#override
void method() {
do the task for Child_A;
}
}
class Child_B extends Parent {
#override
void method() {
do the task for Child_B;
}
}
It seems that we can always achieve the same thing by defining a generic method in the superclass, which uses the instanceof keyword to determine the subclass and performs the corresponding task for the subclass.
class Demo {
public static void main(String[] args) {
Parent a = new Child_A();
Parent b = new Child_B();
a.method();
b.method();
}
}
class Parent {
void method() {
if (this instanceof Child_A) {
do the task for Child_A;
}
else if (this instanceof Child_B) {
do the task for Child_B;
}
}
}
class Child_A extends Parent {
}
class Child_B extends Parent {
}
Which code style is better and why?
Because:
you don't want to have to modify the parent class every time you add another subclass
in some circumstances like a library API you may not even know all the subclasses
code that deals with a subclass should be in that subclass, not in the parent.
If you do the latter, your subclasses becomes useless. They don't do anything. I'd like to think of it this way, the parent passed you the ability to do methodA in your own way. However in your case, the parent does everything, meaning you are dependent on your parent forever. Who would want that?
Well aside from that, when you create a new subtype, you'll have to edit also the parent(very absurd), think of what will happen 100 subtypes later. Give your subtypes the power to have their own individuality.

can invoke concrete class method using interface without casting

here's the code snippet.
public interface Parent{
public void invoke();
}
public class Child implements Parent{
public void invoke(){
System.out.println("invoking invoke()");
}
public void invoke1(){
System.out.println("invoking invoke1()");
}
}
public static void main(String[] args){
Parent parent = new Child();
parent.invoke1();
}
how would i invoke invoke1() using interface without casting it to child?
how would i invoke invoke1() using interface without casting it to child?
Not possible. And that's one leg of polymorphism.
It is not possible. invoke1() method is not belonging to the Parent interface. That method method is owned by the child class. so in order to invoke the method, you need to have a need to have a valid object reference for the Child class.

Understanding the use of Super to access Superclass members

I was referring to the java language specification to understand the use of super. While I understand the first use case i.e.
The form super.Identifier refers to the field named Identifier of the current object, but with the current object viewed as an instance of the superclass of the current class.
I can't seem to understand the following use case:
The form T.super.Identifier refers to the field named Identifier of the lexically enclosing instance corresponding to T, but with that instance viewed as an instance of the superclass of T.
Could someone please explain this with the help of code?
I suppose the following could be illustrative of the second case:
class S{
int x=0;
}
class T extends S{
int x=1;
class C{
int x=2;
void print(){
System.out.println(this.x);
System.out.println(T.this.x);
System.out.println(T.super.x);
}
}
public static void main(String args[]){
T t=new T();
C c=t.new C();
c.print();
}
}
output:
2
1
0
I believe it applies to this situation
public class Main {
static class Child extends Parent{
class DeeplyNested {
public void method() {
Child.super.overriden();
}
}
public void overriden() {
System.out.println("child");
}
}
static class Parent {
public void overriden() {
System.out.println("parent");
}
}
public static void main(String args[]) {
Child child = new Child();
DeeplyNested deep = child.new DeeplyNested();
deep.method();
}
}
In the JLS
The form T.super.Identifier refers to the field named Identifier of
the lexically enclosing instance corresponding to T, but with that
instance viewed as an instance of the superclass of T.
Identifier is overriden, the method.
Here, the lexically enclosing instance is of type Child and its superclass is Parent. So T.super refers to the instance of Child viewed as Parent.
The code above prints
parent

Variables binding VS method binding in polymorphism

I observer the behaviour that when we call a variable from a polymorphic object then it calls the parent's variable but when we call a method with the same polymorphic object then it calls child's method.Why this is the behaviour of polymorphism in Java? Why doesn't Java handle polymorphic variables and methods in same way?
class Parent{
int age =10;
public void showAge(){
System.out.println("Parent Age:"+age);
}
}
class ChildOne extends Parent{
int age = 20;
public void showAge(){
System.out.println("child one age:"+age);
}
}
class ChildTwo extends Parent{
int age = 30;
public void showAge(){
System.out.println("Child Two Age:"+age);
}
}
public class Test{
public static void main(String[] args) {
Parent parentChildOne = new ChildOne();
System.out.println("parentChildOne.age: "+parentChildOne.age);
parentChildOne.showAge();
Parent parentChildTwo = new ChildTwo();
System.out.println("parentChildTwo.age: "+parentChildTwo.age);
parentChildTwo.showAge();
}
}
Here is the output:
parentChildOne.age: 10
child one age:20
parentChildTwo.age: 10
Child Two Age:30
First of all keep in mind that Your variables are not polymorphic and the next climax thing is your this point
Parent parentChildOne = new ChildOne();
Parent parentChildTwo = new ChildTwo();
See when you are trying to call a method using Parent parentChildOne then it should call the child's method because it is overrided and according to polymorphism it should be called. Now see again Parent parentChildOne same object for variables , now here is nothing with polymorphism but jvm is dealing it now with the concept of shadowingSo thats why they both are showing their real behavioursPlease follow this tutorial of shadowing in java
Variables are not polymorphic in Java.
Instead, instance variables in child classes shadow instance variables with the same name in the parent class.
See also Can parent and child class in Java have same instance variable?
parentChildOne and parentChildTwo are of type Parent. So you are printing age of the Parent. Same happes with the showAge() method but the value of age is shadowed by the child classes.
Please see the comments into,
class Parent{
int age =10;
public void showAge(){
System.out.println("Parent Age:"+age);
}
}
class ChildOne extends Parent{
//when you extends Parent the inherited members are like
//and initialized into the default constructor
// int super.age =10;
int age = 20;
public void showAge(){
System.out.println("child one age:"+age);
}
}
class ChildTwo extends Parent{
//when you extends Parent the inherited members are like
//and initialized into the default constructor
// int super.age =10;
int age = 30;
public void showAge(){
System.out.println("Child Two Age:"+age);
}
}
public class Test{
public static void main(String[] args) {
Parent parentChildOne = new ChildOne();
// when we call like this, goes to the parent type of the variable instead of object.
System.out.println("parentChildOne.age: "+parentChildOne.age);
parentChildOne.showAge();
Parent parentChildTwo = new ChildTwo();
// when we call like this, goes to the parent type of the variable instead of object.
System.out.println("parentChildTwo.age: "+parentChildTwo.age);
parentChildTwo.showAge();
}
}

How to make some methods from superclass not avaliable in child class

Lets say I have a class
public class Base {}
and a child class
public class Derived extends Base {
public void Foo(Object i){
System.out.println("derived - object");
}
}
and main class
public class Main {
public static void main(String[] args) {
Derived d = new Derived();
int i = 5;
d.Foo(i);
}
}
In console we will see
derived - object
Some time later I want to modify my superclass like this :
public class Base {
public void Foo(int i) {
System.out.println("base - int");
}
}
Now if I run my programm I will see:
base - int
So can I make a method in superclass not avaliable in my child class?
In result I want to see derived - object.
I see some don't understand what I want so I'll try to explain:
I want to modify only superclass and I don't want to modify my child class.. for example if I will make jar with my superclass and jar with my childs. I don't want to change all jars.. I want to add method into superclass and make it avaliable for superclass..
And such code
public class Main {
public static void main(String[] args) {
Derived d = new Derived();
int i = 5;
d.Foo(i);
Base b = new Base();
b.Foo(i);
}
}
give me
derived - object
base - int
You should use following signature for Foo method in base class:
public void Foo(Object i) {
System.out.println("base - int");
}
This way you can override method Foo from base class. Now you do not override this method but overload it instead.
If you want to use public void Foo(int i) signature in your base class then you can define Foo method in base class as private.
PS: I hope that I've understood you.
private members are limited to the class scope.
default (no keyword for this one) are limited to other members of the same package.
protected are limited to hierarchy.
public are not limited.
So if you don't want your child class to access a member of the superclass (member means methods, enum, variables ...) you should declare your foo like this :
public class Base {
private void Foo(int i) {
System.out.println("base - int");
}
}
Edit from my comment :
if you dont want child class to access a parent's member at compile time I can't see any way to still allow external classes to access it.
You want to block access from close scope while allowing broader scope. This can only be done by overriding the method and throwing an exception for accessviolation or something which is not at compile time but at runtime. Although you could make it work with a custom annotations but I don't know how to do this.
You can make a method final, which means, that the child class cannot override it.
If you do not do that and the child class overrides the method, you cannot call the super classes method from your main.
A Convention note: Please use lowercase method names in java.
package com.abc;
public class TestParentChild {
public static void main(String[] asd) {
Base b = new ChildB();
b.foo(5);
}
}
class Base {
public void foo(int i) {
System.out.println("derived - int");
}
}
class ChildB extends Base {
public void foo(int i) {
System.out.println("derived - object");
}
}
This might help you

Categories