The following is impossible in Java, since interfaces don't have implementations:
class A {
protected void foo() { /* A impl */ }
protected void baz() { /* impl */ }
}
interface B {
/* here's what's impossible to have in Java. */
protected void foo() { /* B impl incl. call to baz() */ }
}
class C extends A {
/* stuff that's not in B... */
}
class D extends C implements B {
void bar() { foo(); /* uses the B impl */ }
}
class E extends A {
void bar() { foo(); /* uses the A impl */ }
}
class F extends C implements B {
void bar() { foo(); /* uses the B impl */ }
}
What I want is for D to inherit C, but not to have to override foo()
itself; rather, I want it to merely indicate "I use the known modification from B". What's the right idiom in this scenario?
Notes:
Unless you are using Java 1.8, you cannot have any implementation in the interface, so your question is based on the wrong assumption: You only ever have the implementation of A.foo
in C
and D
.
With Java 1.8, you can have so called virtual extension methods in interfaces. There it should be possible using the following syntax :
class ExtenderOfB {
public static void foo(B b) {
//...
}
}
interface B {
public void foo() default ExtenderOfB.foo;
}
class D extends C implements B {
public void bar() {
B.super.foo();
}
}
However, since the magic essentially boils down to calling a static method, you can do that for yourself already:
Create a helper class that provides the default implementation of B.foo
using a static void foo(B b)
and call it from D.bar
via HelperClass.foo(this)
.
You can solve this problem using multilevel inheritance
class A
{
//implementation of A
}
class B extends A
{
public void foo()
{
//you can give your implementation of foo() here
}
//includes A's methods also.
}
class C extends B
{
//will have methods from both A and B
}
Is this what you're looking for? (This should be in the comments, since I'm not sure what you're looking for, but it doesn't exactly show up nicely there.)
interface A {
void foo();
void baz();
}
class B extends A{
void foo(){/* B's impl. (must be impl.)*/};
void baz(){/* B's impl. (must be impl.)*/};
}
class C extends A {
void foo(){/* C's impl. (must be impl.)*/};
void baz(){/* C's impl. (must be impl.)*/};
}
class D extends C {
void foo(){/* D's impl */};
void baz(){/* D's impl, if not included C's impl will be used */};
}
class E extends B {
void foo(){/* E's impl, if not included B's impl will be used.*/};
void baz(){/* E's impl, if not included B's impl will be used.*/};
}
Alternatively, if you want B and C to both share methods from A, you would do this...
class A {
void foo(){ /*(must be impl.)*/ };
void baz(){ /*(must be impl.)*/ };
}
class B extends A {
void foo(){/* B's impl, if not included A's impl will be used*/};
void baz(){/* B's impl, if not included A's impl will be used*/};
}
class C extends A {
void foo(){/* C's impl, if not included A's impl will be used*/};
void baz(){/* C's impl, if not included A's impl will be used*/};
}
class D extends C {
void foo(){/* D's impl, if not included C's impl will be used */};
void baz(){/* D's impl, if not included C's impl will be used */};
}
class E extends B {
void foo(){/* E's impl, if not included B's impl will be used.*/};
void baz(){/* E's impl, if not included B's impl will be used.*/};
}
If you want A to implement foo(), but not baz(), you would make it abstract, like this...
abstract class A {
void foo(){ /*(must be impl.)*/ };
abstract void baz();
}
class B extends A{
void foo(){/* B's impl, if not included A's impl will be used*/};
void baz(){ /*(must be impl.)*/ };
}
class C extends A {
void foo(){/* C's impl, if not included A's impl will be used*/};
void baz(){ /*(must be impl.)*/ };
}
class D extends C {
void foo(){/* D's impl, if not included C's impl will be used */};
void baz(){/* D's impl, if not included C's impl will be used */};
}
class E extends B {
void foo(){/* E's impl, if not included B's impl will be used.*/};
void baz(){/* E's impl, if not included B's impl will be used.*/};
}
A little crash course about interfaces and abstract classes here...
Java indeed does not have multiple inheritance in the sense that you can only extend one class -- however, you can implement more than one interface.
And there are abstract classes. Say you have:
interface B {
void foo();
}
// A is abstract, and it does not implement foo(): this will be left to
// its inheritors
abstract class A implements B {
// Method with implementation
protected void bar() {}
// Method which must be implemented in inheriting classes
abstract void baz();
}
// Concrete implementation of A: note that there is no need to specify
// "implements B" since A already does
class C extends A {
// C must implement baz() since it is declared abstract in A,
// but must also implement foo() since A implements B, and A
// has no implementation of it
}
Also, an abstract class can extend another abstract class:
// D also implements B since A does.
abstract class D extends A {
// But this time, D implements foo() from B
@Override
void foo() {}
}
class E extends D {
// E must still implement the abstract baz() method declared in A
}
Do not hesitate to ask for more details, I will edit as appropriate.
You probably need a redesign here, but...
class D extends C implements B {
void bar() {
foo(); /* used the B impl */
}
is valid only if interface B
declares foo
as a method signature ( protected void foo();
) and if D
implements foo
(since it would then implement the valid B
interface). Thus bar()
would then call the foo()
method that D
implements, since it would be most local to D
.
In the scenario one class A should implement the the interface B as well as both have method foo()
.
Then class C extends A it doesn't have to implement B as it has the default implementation by the superclass.
Then class D extends C and wrapped the method foo()
by the method bar()
without overriding it. This is idiom.
The code
interface B {
void foo();
}
class A implements B {
public void foo() {
/* B impl */
}
}
class C extends A {
/* stuff that's not in B... */
}
class D extends C {
void bar() {
foo(); /* used the B impl */
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.