How to call default interface method from another subclass? - java

Consider the following:
//Fooable.java
public interface Fooable {
public default void foo() {
System.out.println("Fooable::foo");
}
//Lots of other non-default methods...
}
//MyFooable.java
public class MyFooable implements Fooable {
#Override
public void foo() {
System.out.println("MyFooable::foo");
}
//implements other methods in Fooable...
}
//MyAdvancedFooable.java
public class MyAdvancedFooable extends MyFooable {
#Override
public void foo() {
Fooable.super.foo();
System.out.println("MyAdvancedFooable::foo");
}
public static void main(String[] args) {
new MyAdvancedFooable().foo();
}
}
As you can see, I want to call foo() in Fooable from MyAdvancedFooable (a subclass of MyFooable). However, when I try to compile, I get the following error:
MyAdvancedFooable.java:4: error: not an enclosing class: Fooable
Fooable.super.foo();
if I try MyAdvancedFooable extends MyFooable implements Fooable I get the following:
MyAdvancedFooable.java:4: error: bad type qualifier Fooable in default super call
Fooable.super.foo();
method foo() is overridden in MyFooable
How can I resolve this problem without having to create a new anonymous implementation of Fooable?

You can only call a method one level up so you would need
Fooable.super.foo();
in MyFooable, while just calling super.foo() in MyAdvancedFooable

You need to use just super.foo() or this.super.foo() as it is the parent of the object and not of the class as implied by Fooable.super.foo().

Related

extending an abstract class with generic enum type

Is there a way to extend an abstract class with generic enum types? When I extend it and implement myMethod below, only the method from the abstract class gets called.
first i define abstract class with method myMethod where i would like to make decisions based on the enum value.
public abstract class MyAbstractClass <T extends enum<T>> {
public void myMethod(T cmd) {
//i want to override this
}
public void update(T cmd) {
myMethod(cmd);
}
}
define an enum and extend the class, but the child class myMethod never gets called(only the myMethod of abstract class gets called).
enum CMD {
CMD_1, CMD_2
}
public class Child extends MyAbstractClass<CMD> {
...
public void myMethod(CMD cmd) {
if (cmd == CMD_1) { //do something }
}
...
}
instantiate and call
Child child = new Child();
child.update(CMD.CMD_1);
Yes. Use T extends Enum<T>:
public abstract class MyAbstractClass <T extends Enum<T>> {
public void myMethod(T cmd) {}
}
See live demo of your code, with this change, compiling OK.
If you want to select the behaviour according to the enum value, then one way to do it is to put the behaviour into each enum value, e.g.:
enum Command {
CMD1 {
#Override
void execute() {
System.out.println("Command.CMD1");
}
},
CMD2 {
#Override
void execute() {
System.out.println("Command.CMD2");
}
};
abstract void execute();
}
public static void main(String[] args) {
final Command cmd = Command.CMD1;
cmd.execute();
}

calling non abstract method in abstract class java

I have 3 classes. It seems basic question. But I can'nt find answer by googling.
public abstract class Test {
void t1()
{
System.out.println("super");
}
}
public class concret extends Test{
void t1()
{
System.out.println("child");
}
void t2()
{
System.out.println("child2");
}
}
public class run {
public static void main(String[] args) {
Test t=new concret();
t.t1();
}
}
How do I call abstract class t1 method? Since I cant create object from abstract class how do I call t1 in abstract class?
Thank you.
Either you create a concrete class which doesn't override the method, or within a concrete class which does override the method, you can call super.t1(). For example:
void t1()
{
super.t1(); // First call the superclass implementation
System.out.println("child");
}
If you've only got an instance of an object which overrides a method, you cannot call the original method from "outside" the class, because that would break encapsulation... the purpose of overriding is to replace the behaviour of the original method.
you should be able to do it using
Test test = new Test(){};
test.t1();
Abstract class means the class has the abstract modifier before the class keyword. This means you can declare abstract methods, which are only implemented in the concrete classes.
For example :
public abstract class Test {
public abstract void foo();
}
public class Concrete extends Test {
public void foo() {
System.out.println("hey");
}
}
See following tests:
public abstract class BaseClass {
public void doStuff() {
System.out.println("Called BaseClass Do Stuff");
}
public abstract void doAbstractStuff();
}
public class ConcreteClassOne extends BaseClass{
#Override
public void doAbstractStuff() {
System.out.println("Called ConcreteClassOne Do Stuff");
}
}
public class ConcreteClassTwo extends BaseClass{
#Override
public void doStuff() {
System.out.println("Overriding BaseClass Do Stuff");
}
#Override
public void doAbstractStuff() {
System.out.println("Called ConcreteClassTwo Do Stuff");
}
}
public class ConcreteClassThree extends BaseClass{
#Override
public void doStuff() {
super.doStuff();
System.out.println("-Overriding BaseClass Do Stuff");
}
#Override
public void doAbstractStuff() {
System.out.println("Called ConcreteClassThree Do Stuff");
}
}
public class Test {
public static void main(String[] args) {
BaseClass a = new ConcreteClassOne();
a.doStuff(); //Called BaseClass Do Stuff
a.doAbstractStuff(); //Called ConcreteClassOne Do Stuff
BaseClass b = new ConcreteClassTwo();
b.doStuff(); //Overriding BaseClass Do Stuff
b.doAbstractStuff(); //Called ConcreteClassTwo Do Stuff
BaseClass c = new ConcreteClassThree();
c.doStuff(); //Called BaseClass Do Stuff
//-Overriding BaseClass Do Stuff
c.doAbstractStuff(); //Called ConcreteClassThree Do Stuff
}
}
use keyword 'super' to do that
void t1()
{ super.t1();
System.out.println("child");
}
Make sure you use that in the overriden method though.
Your code seems to call t1(). However this is calling the concrete t1() because the abstract t1() has been overridden by the concrete class.
If you wish to call the abstract t1 method from main code, do not override the t1() in concrete.
Or you can create a method in the concrete class for example:
public void invokeSuperT1(){
super.t1();
}
Create an anonymous Inner class,
Abstract class:
abstract class Test{
abstract void t();
public void t1(){
System.out.println("Test");
}
}
Here is how to create anonymous inner class:
Test test = new Test() {
#Override
void t() {
//you can throw exception here, if you want
}
};
Call the class via the object created for abstract class,
test.t1();
An abstract class is used when we want that every class that inherited from our abstract class should implement that abstract method, so it is must to implement method otherwise it gives the compile-time error.
void t1()
{
super.t1; // means the parent methods
System.out.println("child");
}
For example: Bird class has method sing() and there other classes that inherited from it like the sparrow, Pigeon, Duck, so these all have sing method so we make Bird class Abstract and make the sing() method abstract in it so every child of bird that implements Bird class should have a method of sing() with its on implementation.
First Create abstarct class like as shown in link: Creating Abstract Class
Create Sub-Classs like as shown in link: Sub-class extending
Creating main method for executing this as show in link: Instanciate the subclass to access
Result as shown here: Result

Explicitly calling a default method in Java

Java 8 introduces default methods to provide the ability to extend interfaces without the need to modify existing implementations.
I wonder if it's possible to explicitly invoke the default implementation of a method when that method has been overridden or is not available because of conflicting default implementations in different interfaces.
interface A {
default void foo() {
System.out.println("A.foo");
}
}
class B implements A {
#Override
public void foo() {
System.out.println("B.foo");
}
public void afoo() {
// how to invoke A.foo() here?
}
}
Considering the code above, how would you call A.foo() from a method of class B?
As per this article you access default method in interface A using
A.super.foo();
This could be used as follows (assuming interfaces A and C both have default methods foo())
public class ChildClass implements A, C {
#Override
public void foo() {
//you could completely override the default implementations
doSomethingElse();
//or manage conflicts between the same method foo() in both A and C
A.super.foo();
}
public void bah() {
A.super.foo(); //original foo() from A accessed
C.super.foo(); //original foo() from C accessed
}
}
A and C can both have .foo() methods and the specific default implementation can be chosen or you can use one (or both) as part of your new foo() method. You can also use the same syntax to access the default versions in other methods in your implementing class.
Formal description of the method invocation syntax can be found in the chapter 15 of the JLS.
This answer is written mainly for users who are coming from question 45047550 which is closed.
Java 8 interfaces introduce some aspects of multiple inheritance. Default methods have an implemented function body. To call a method from the super class you can use the keyword super, but if you want to make this with a super interface it's required to name it explicitly.
class ParentClass {
public void hello() {
System.out.println("Hello ParentClass!");
}
}
interface InterfaceFoo {
public default void hello() {
System.out.println("Hello InterfaceFoo!");
}
}
interface InterfaceBar {
public default void hello() {
System.out.println("Hello InterfaceBar!");
}
}
public class Example extends ParentClass implements InterfaceFoo, InterfaceBar {
public void hello() {
super.hello(); // (note: ParentClass.super could not be used)
InterfaceFoo.super.hello();
InterfaceBar.super.hello();
}
public static void main(String[] args) {
new Example().hello();
}
}
Output:
Hello ParentClass!
Hello InterfaceFoo!
Hello InterfaceBar!
The code below should work.
public class B implements A {
#Override
public void foo() {
System.out.println("B.foo");
}
void aFoo() {
A.super.foo();
}
public static void main(String[] args) {
B b = new B();
b.foo();
b.aFoo();
}
}
interface A {
default void foo() {
System.out.println("A.foo");
}
}
Output:
B.foo
A.foo
You don't need to override the default method of an interface. Just call it like the following:
public class B implements A {
#Override
public void foo() {
System.out.println("B.foo");
}
public void afoo() {
A.super.foo();
}
public static void main(String[] args) {
B b=new B();
b.afoo();
}
}
Output:
A.foo
It depends on your choice whether you want to override the default method of an interface or not. Because default are similar to instance method of a class which can be directly called upon the implementing class object. (In short default method of an interface is inherited by implementing class)
Consider the following example:
interface I{
default void print(){
System.out.println("Interface");
}
}
abstract class Abs{
public void print(){
System.out.println("Abstract");
}
}
public class Test extends Abs implements I{
public static void main(String[] args) throws ExecutionException, InterruptedException
{
Test t = new Test();
t.print();// calls Abstract's print method and How to call interface's defaut method?
}
}

Inheritance and Private Methods

Given the following block of code:
public class Trial {
public static void main (String[] args){
B obj = new B();
obj.doMethod(); #prints "From A".
}
}
class A {
private void method(){System.out.print("from A");}
public void doMethod(){method();}
}
class B extends A {
public void method(){System.out.print("from B");}
public void doMethod(){super.doMethod();}
}
It turns out that the method() from class A is invoked. Why is this?
You explicitly implement it that way. super calls method from base class which is A
public void doMethod(){super.doMethod();}
So the method chaining is like this:
B.doMethod() -> A.doMethod() -> A.method() -> "from A"
I think your question is if in class A private void method(){System.out.print("from A");} is private then why is printing "from A" in class B.
Answer is very simple you can't call method() of A class form any other class .But you can call it with object of its own.
when you calls super.doMethod(); then its function of super and method() is its own method so it can call it.
Because, see below:
class B extends A {
public void method(){System.out.print("from B");}
public void doMethod(){super.doMethod();}
}
Here in Class B's doMethod() you're invoiking Class A's doMethod() using super.doMethod(). So obviously it's printing Class A's doMethod().
You call the doMethod with super keyword. It's means it will call parent implementation
More on super keyword
Your code gives simple object creation (B obj = new B();) and a call using super. Super is used like other people mentioned for parent class. Things could have been different if you try something like (A obj = new B();), which is more interesting.
method() in class A is private and private methods can't be overriden. And when overriding it's better to use #Override annotion.
class B extends A {
#Override
public void method(){System.out.print("from B");} // Compile error
}
A similar thing happens, if you change the method to a static method.
class A {
public static void method(){System.out.print("from A");}
}
class B extends A {
public static void method(){System.out.print("from B");}
}

Java - Confused about a particular inheritance scenario

Say I have a class called A, and in A there's a method called myMethod(). Now say I make a subclass of A, called SubA, and in SubA I override myMethod() to make it do what I want it to. Now say I have another method in A called myOtherMethod() which calls myMethod() (from within the same class). I do not override myOtherMethod() in SubA. If I now call myOtherMethod() from inside SubA, it will clearly run A's myOtherMethod(). But does this now call the myMethod() as defined in A, or as defined (and overridden) in SubA?
To further confuse things, does it matter at all whether myMethod() were an interface method for some interface that class A implemented?
It is easy to try - the fact that A implements an interface or not does not make a difference:
public class A {
public void myMethod() {
System.out.println("A.myMethod()");
}
public void myOtherMethod() {
System.out.println("A.myOtherMethod()");
myMethod();
}
public static class SubA extends A {
#Override
public void myMethod() {
System.out.println("SubA.myMethod()");
}
}
public static void main(String[] args) {
A a = new A();
SubA subA = new SubA();
a.myMethod(); //A.myMethod()
subA.myMethod(); //SubA.myMethod()
a.myOtherMethod(); //A.myOtherMethod() + A.myMethod()
subA.myOtherMethod(); //A.myOtherMethod() + SubA.myMethod()
}
}
If you create instance of SubA then calling method myOtherMethod() (which is in A) calls method myMethod() defined in SubA because it overrides method defined in A.

Categories

Resources