4 ms·
Inheritance is overused in OOP. There are many ways to share object behaviors, inheritance only works well when you expect all objects of both classes to share
by vinceguidry 10y ago
Inheritance is overused in OOP. There are many ways to share object behaviors, inheritance only works well when you expect all objects of both classes to share all behavior except one or two things. Even then, you should investigate dependency injection before reaching for inheritance.
For the example given for the Triangle Problem, the author isn't clear about exactly what behavior is being shared among the classes. The top of the tree, PoweredDevice, gives an indication, but my guess is that there are more responsibilities than just power, these responsibilities aren't being reflected in the domain model as they should be.
Instances of a class share behavior with other instances, it is the state that differs, i.e. the data being stored in the instance variables. In the example hierarchy, the state being stored is left out of the analysis, but it's the first place I would look for a missing domain concept. My guess would be that the most concrete class is going to be models of consumer peripherals, of which instances are intended to represent actual devices.
In this case a copier, which contains both a scanner and a printer, but not an actual discernible model of scanner or printer, would simply inherit from PoweredDevice. That it has this functionality does not mean it need actually have those in its class hierarchy. It is a job better suited for mixins, or injected dependencies.
- RantyDave 10y agoSounds to me like PoweredDevice would be an interface.
- rahkiin 10y agoOr an IScannable and IPrintable interface (that is not the correct english word for 'something that can scan'..), and a Scanner implementing IScannable and deriving from PoweredDevice. And a copier deriving from PoweredDevice implementing both interfaces. Then an interface is a capability.
- jghn 10y agoFrom a purist view one could argue that inheritance doesn't belong in OO in the first place. Alan Kay's first descriptions of Smalltalk & OOP did not include inheritance concepts.
- Chattered 10y agoKay has also suggested that late binding or dynamic dispatch is a massive deal, and in most statically typed oop languages, dynamic dispatch is typed according to the inheritance hierarchy. The upshot is that to teach OOP in Java, say, you need to talk about significant parts of the inheritance machinery just to get dynamic dispatch, perhaps later cautioning against implementation inheritance and even interface inheritance. In Smalltalk, you can talk dynamic dispatch without messing around with inheritance at all. For a statically typed language where dynamic dispatch is free from inheritance graphs (sometimes described by saying that subtyping is not inheritance) see Ocaml's structural subtyping via row polymorphic records (bit of a mouthful --- but I need to differentiate from Ocaml's module system which is structurally subtyped and supports inheritance!)
- imtringued 10y agoclass A { public int field1; public void method1() { System.out.println("A"); } public void method2() { System.out.println("A"); } } class B extends A { public int field2; public void method1() { System.out.println("B"); } } is basically equivalent to interface C { public void method1() {} public void method2() {} } class A implements C { public int field1; public void method1() { System.out.println("A"); } public void method2() { System.out.println("A"); } } class B implements C { public A a; public int field2; public void method1() { System.out.println("B"); } public void method2() { a.method(); } } As you can see both are basically the same except one little detail. The benefit is that you don't have to write the redundant "method2" method in class B. So the only time inheritance is ever useful is when you don't want to override all methods. Now someone tells you to model everything in terms of class hierarchies even when they don't need it right now and you've negated the tiny little benefit it ever had which means not having it in the programming language actually has positive consequences.