As VonC wrote, but I would like to point out something.
The problem of a fragile base class is often blamed on virtual methods (dynamic method dispatch - this means that if methods can be overridden, the actual implementation that should be called in the case of such an overridden method can only be determined at run time).
? , - , MethodA() MethodB(), , MethodB(), , - , MethodB().
Go , polymorphism. , set , "" . , , wrapper , , , "" , .
- , Go.
Java
. Java, Java "" . Counter MyCounter:
class Counter {
int value;
void inc() {
value++;
}
void incBy(int n) {
value += n;
}
}
class MyCounter extends Counter {
void inc() {
incBy(1);
}
}
MyCounter:
MyCounter m = new MyCounter();
m.inc();
System.out.println(m.value);
m.incBy(2);
System.out.println(m.value);
, :
1
3
. , , Counter.incBy() :
void incBy(int n) {
for (; n > 0; n--) {
inc();
}
}
Counter - . MyCounter : MyCounter.inc() Counter.incBy(), inc(), - MyCounter.inc()... ... . .
Go
, Go:
type Counter struct {
value int
}
func (c *Counter) Inc() {
c.value++
}
func (c *Counter) IncBy(n int) {
c.value += n
}
type MyCounter struct {
Counter
}
func (m *MyCounter) Inc() {
m.IncBy(1)
}
:
m := &MyCounter{}
m.Inc()
fmt.Println(m.value)
m.IncBy(2)
fmt.Println(m.value)
( Go Playground):
1
3
Counter.Inc() , Java:
func (c *Counter) IncBy(n int) {
for ; n > 0; n-- {
c.Inc()
}
}
, . Go Playground.
, , MyCounter.inc() Counter.incBy(), inc(), inc() Counter.Inc(), . Counter MyCounter, MyCounter.