问题描述
假设我有这个:
public class A {
public String foo() { return "A"; }
}
public class B extends A {
public String foo() { return "B"; }
public String superFoo() { return super.foo(); }
}
public class C extends B {
public String foo() { return "C"; }
}
在这里,new C().superFoo()
返回"A"
.有没有一种方法可以使new C().superFoo()
多态化调用B.foo()
(并因此返回"B"
)而无需覆盖C
中的superFoo()
?我尝试了反射(像这样重新定义B.superFoo()
:return getClass().getSuperclass().getDeclaredMethod("foo").invoke(this)
),希望通过getDeclaredMethod
我可以引用超类中的确切方法实现,但是在这种情况下我得到了"C"
(因此,应用了多态性).
Here, new C().superFoo()
returns "A"
.Is there a way I can polymorphically make new C().superFoo()
invoke B.foo()
(and hence return "B"
) without the need to override superFoo()
in C
?I tried with reflection (redefining B.superFoo()
like this: return getClass().getSuperclass().getDeclaredMethod("foo").invoke(this)
), hoping that with getDeclaredMethod
I could reference the exact method implementation in superclass, but I get "C"
in that case (hence, polymorphism is applied).
我正在寻找一种解决方案,每当我向层次结构添加新的子类时,都不需要我重新声明superFoo()
.
I was searching for a solution that doesn't require me to redeclare superFoo()
whenever I add a new subclass to the hierarchy.
推荐答案
TL; DR
遍历问题和评论,似乎这里的要问是逐步建立在行为上.从不同的角度来看,在这种情况下,我更倾向于组成而不是继承.
Going through the question and comments, it seems like the ask here is to incrementally build up on a behavior. Taking a different perspective, I would prefer Composition over Inheritance in this scenario.
您可以使用Decorator模式并将实例组合在一起;这反过来又为您提供了对父代的foo()
实现的引用.另一个好处之一是,您可以在运行时扩展/更改行为,而使用静态继承设计则无法实现.
You can use Decorator pattern and compose the instances together; which in turn gives you a reference to the parent's foo()
implementation. One of the other benefits is that you can extend/change the behavior at runtime, which is not possible with a static inheritance design.
关于装饰图案
装饰器模式可用于以静态或动态方式将附加职责附加到对象上.
Decorator pattern can be used to attach additional responsibilities to an object either statically or dynamically.
-
Component
-可以动态添加职责的对象的接口. -
ConcreteComponent
-定义可以添加其他职责的对象. -
Decorator
-维护对Component对象的引用,并定义一个符合Component接口的接口. -
Concrete Decorators
-混凝土装饰器通过添加状态或行为来扩展组件的功能.
Component
- Interface for objects that can have responsibilities added to them dynamically.ConcreteComponent
- Defines an object to which additional responsibilities can be added.Decorator
- Maintains a reference to a Component object and defines an interface that conforms to Component's interface.Concrete Decorators
- Concrete Decorators extend the functionality of the component by adding state or adding behavior.
示例代码
让我们以比萨饼烘焙过程为例.
Let's take a Pizza baking process as an example.
Component
界面-定义必须烘焙比萨饼的合同.
Component
interface - Defines the contract that a Pizza must be baked.
public interface Pizza {
void bake();
}
ConcreteComponent
类-这是接口的实现,该接口可以独立运行.它不应该扩展Decorator
,并且当对象组合在一起时,它会出现在最里面的位置(请参阅最后的客户端代码)
ConcreteComponent
class - This is your implementation of the interface which can stand alone by itself. It should not extend the Decorator
and it appears at the innermost position when the objects are composed together (see client code at the end)
public class VeggiePizza implements Pizza {
@Override
public void bake() {
System.out.println("I'm a Veggie Pizza in the making :)");
}
}
Decorator
-指定用于扩展ConcreteComponent
功能的合同.
Decorator
- Specifies a contract for extending the functionality of the ConcreteComponent
.
public abstract class Topping implements Pizza {
private Pizza pizza;
public Topping(Pizza pizza) {
this.pizza = pizza;
}
@Override
public void bake() {
pizza.bake();
}
}
Concrete Decorator
-这些实现通过将其构造函数嵌套在一起而构成了ConcreteComponent
的功能(一种构成方式!).除了最里面的位置(请参见下面的客户代码)以外,混凝土装饰器可以在合成时出现在任何位置.
Concrete Decorator
- These implementations add to the functionality of the ConcreteComponent
by nesting their constructors together (one of the ways to compose!). The concrete decorator can appear anywhere while composing, except for the innermost position (see client code below).
在这里,我们定义了两个浇头-蘑菇和墨西哥胡椒.
Here we are defining two toppings - Mushroom and Jalapeno.
public class Mushroom extends Topping {
public Mushroom(Pizza pizza) {
super(pizza);
}
@Override
public void bake() {
addMushroom();
super.bake();
}
private void addMushroom() {
System.out.println("Adding mushrooms...");
}
}
public class Jalapeno extends Topping {
public Jalapeno(Pizza pizza) {
super(pizza);
}
@Override
public void bake() {
addJalapenos();
super.bake();
}
private void addJalapenos() {
System.out.println("Adding jalapenos...");
}
}
客户代码-您如何将ConcreteDecorator
和ConcreteComponent
组合在一起?
Client code - How do you compose the ConcreteDecorator
and ConcreteComponent
together?
public void bakePizza() {
Pizza pizza = new Mushroom(new Jalapeno(new VeggiePizza()));
pizza.bake();
}
请注意,我们以VeggiePizza
为基础,通过包裹对象以及Mushroom
和Jalapeno
的其他行为来包装对象.在这里,ConcreteComponent
是最里面的VeggiePizza
,而我们的ConcreteDecorator
是Jalapeno
和Mushroom
.
Notice that we build upon the VeggiePizza
by wrapping the objects around with additional behavior from Mushroom
and Jalapeno
. Here, the ConcreteComponent
is the innermost VeggiePizza
, while our ConcreteDecorator
s are Jalapeno
and Mushroom
.
注意:构造器组成只是组成方式之一.您可以通过设置器将对象组合在一起,也可以使用依赖注入框架.
Note: Constructor composition is only one of the ways to compose. You can compose object together via setters or use a Dependency Injection framework.
输出
Adding mushrooms...
Adding jalapenos...
I'm a Veggie Pizza in the making :)
这篇关于Java:多态调用超级实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!