can invoke concrete class method using interface without casting - java

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.

Related

Is overloading in inheritance class possible in 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

Java - calling a method by passing child instance to a function with parameter of parent class type [duplicate]

public class Parent {
....
}
public class Child1 extends Parent {
....
public void foo() {
....
}
}
public class Child2 extends Parent {
....
public void foo() {
....
}
}
Here method foo() only exists in the Child classes and CAN NOT be added to the Parent class (not even abstract method). In this situation when I want to call the foo() method on obj which is Parent class's reference then I need to use intanceof with multiple if..else which I want to avoid.
Parent obj = ...// Object of one of the child classes
obj.foo();
EDIT: I Need to use type of obj as Parent only. Else I will not be able to call methods on obj which exists in Parent class.
My Solution: The approach that I am thinking is to define an interface say FooInterface with foo() method and let all the child classes implement it, then I could just type cast the obj to that interface and call foo() method like this:
if(obj instanceof FooInterface){
((FooInterface)obj).foo();
}
Is there a better approach ? Or any improvement to this one?
You can't do it with parent object reference until an unless method is declared in parent class/interface itself.
You have to downcast it to child class because parent class/interface doesn't have any knowledge about the child class other than the contract defined between them.
Here contract means abstract methods.
you can try in this way where there is no need to put a check it.
FooInterface sc =new Child1();
sc.foo();
...
interface FooInterface{
void foo();
}
public class Parent {
}
public class Child1 extends Parent implements FooInterface{
public void foo() {
}
}
public class Child2 extends Parent implements FooInterface{
public void foo() {
}
}
The approach that I am finally taking is to define an interface say FooInterface with foo() method and let all the child classes implement it, then I could just type cast the obj to that interface and call foo() method like this:
Parent obj = ...// Object of one of the child classes
.....
if(obj instanceof FooInterface){
((FooInterface)obj).foo();
}
The polymorphism is applied on object reference, not a type. When you call
FooInterface obj = ...// Object of one of the child classes
obj.foo();
the child class method foo() is called.
If you want to typecast only then there is no need of adding interface. You can typecast it to your desired class and call the method. Example
public class HelloWorld {
public static void main(String args[]) throws FileNotFoundException {
SuperClass sc =new Child1();
if(sc instanceof Child1)//Do same for Child2
((Child1)sc).foo();
}
}
class SuperClass {
}
class Child1 extends SuperClass{
public void foo(){
System.out.println("From child1");
}
}
class Child2 extends SuperClass{
public void foo(){
System.out.println("From child2");
}
}
Output :
From child1
You could implement an AbstractChild inheriting from Parent and then extend this class instead of Parent:
public class Parent {
....
}
public abstract class AbstractChild extends Parent{
public abstract void foo();
}
public class Child1 extends AbstractChild {
....
public void foo() {
....
}
}
public class Child2 extends AbstractChild {
....
public void foo() {
....
}
}
So you need to only check if your instance is instanceof AbstractChild.

How to ensure a certain methods gets called in abstract super-class from method in sub-class (Java)

I have an abstract super class A with a method doSomething(). A sub-class of A must implement doSomething(), but there is also some common code that should be called every time a subclass calls doSomething(). I know this could be achieved thus:
public class A {
public void doSomething() {
// Things that every sub-class should do
}
}
public class B extends A {
public void doSomething() {
super.doSomething();
// Doing class-B-specific stuff here
...
}
}
There seem to be three issues with this, though:
The method signatures have to match, but I might want to return something in the sub-class methods only, but not in the super-class
If I make A.doSomething() abstract, I can't provide a (common) implementation in A. If I don't make it abstract, I can't force sub-class to implement it.
If I use a different method to provide the common functionality, I can't enforce that B.doSomething() calls that common method.
Any ideas how the methods should be implemented?
What about the following?
public abstract class A {
protected abstract void __doSomething();
public void doSomething() {
// Things that every sub-class should do
__doSomething();
}
}
public class B extends A {
protected void __doSomething() {
// Doing class-B-specific stuff here
...
}
}
The first bullet point however is not so clear. The signature can't match if you want to return something different.
add call back to doSomething()
public class A {
public void doSomething() {
// Things that every sub-class should do
doSomethingMore()
}
}
protected abstract void doSomethingMore()
so all subclusses will have to ipmelment doSomethingMore() with additional actions but external classes will call public doSomething()
For first point alone - you can consider the below answer and for enforcing subclass implementation it can be abstract but calling common code functionality can happen if the base class has some implementation.
Return type can be Object in Base Class and returning null. In SubClass the specific return type can be put as given below.
public class InheritanceTutorial {
static class Base{
public Object doSomething(){
System.out.println("parent dosomething");
return null;
}
}
static class SubClass extends Base{
public Integer doSomething(){
super.doSomething();
System.out.println("child dosomething");
return 0;
}
}
/**
* #param args
*/
public static void main(String[] args) {
SubClass subClass = new SubClass();
subClass.doSomething();
}
}

extend an override method from abstract class in java

Here is my scenario:
public interface Father{ public void sayHi(); }
public abstract class FatherImpl implements Father{
#Override
public void sayHi() { System.out.print("Hi"); } }
then is the child
public interface Child{}
public class ChildImpl extends FatherImpl implements Child{}
and test function is
Child c = new ChildImpl();
c.sayHi();
This will throw compiling error.
Only when i change child interface to
public interface Child{} extends Father
Then the program runs properly.
Anyone can help me explain the reason.
Child c = new ChildImpl();
The Child interface doesn't have a sayHi() method, that's in ChildImpl. You're referencing c as a Child object, so you can't access the method.
You could either reference the object as a ChildImpl or add another class.
ChildImpl c = new ChildImpl();
Or
public abstract class TalkingChild {
#Override
public void sayHi() {
System.out.print("Hi");
}
}
Or
public interface TalkingChild {
public void sayHi();
}
The best solution completely depends on your specific scenario.
The problem is that the compiler cares only the declared type - the type that is assigned is irrelevant.
Applying this to your case, the type Child has no methods. It doesn't consider that you assigned a ChildImpl, which does have a sayHi() method, to the Child variable.

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