Reputation: 6119
Lets say I'm creating a super class Animalia. It's going to potentially have an enormous amount of sub classes: eg Homo Sapien, Chimpanzee Chordata, Mammal Insecta etc. Now it would be really useful to be able to specify sub class levels in the super class: Phylum, Family, Genus, Species etc. This would then allow us to use something like self.Family.Type
or self.Species.Type
. So the self.Genus.Type of humans would be Homo and the self.Family.Type would be Hominadae. This is something I frequently find myself wanting in my own code. I want to use the self type but I can't because I have no way of specifying the level within the intended inheritance hierarchy.
This potentially would also allow us to do other things like specifying that a class couldn't be instantiated above species level or that certain members had to be made final at certain levels. So we might have val bool differentiated tissues, must be finalized at Phylum level. We could also specify that a species can not inherit directly from Animalia but from a Genus, which must inherit from a Family etc .
I've just used the Animalia as an example because its an easily understood complex hierarchy. So I'm not interested in the biology, but in response to comment, Animalia might have:
class Animalia {
Type fundamentalCellType = Eucharyotic // All sub species inherit from this.
val HasDifferentiatedTissues: Boolean
}
Is there any ways of doing any of this this with Scala currently? If not are there any articles papers etc that discuss this within Scala, other languages or generally in OO theory? I haven't been able to find anything but I'm sure I can't be the first person who have desired such a feature.
Upvotes: 0
Views: 128
Reputation: 6119
A first step to an answer to might look like this
class Animalia {
Type FundamentalCellType = Eucharyotic // All sub species inherit from this.
val HasDifferentiatedTissues: Boolean
type PhylumT <: Animalia
val phylum : PhylumT
type KlassT <: phylum.type //Not sure if this would work.
val klass: KlassT
type GenusT <: klass.type //intermediate classification left out for simplicity
val genus: GenusT
}
Upvotes: 0
Reputation: 40461
OO inheritance modeling is simpler than it seems. The extends
keywords is a synonym for "is-a" relationship. So a "Chimp is a primate and all primates are mammals" is meaningful so you can model this relationship as:
trait Primate extends Mammal
class Chimp extends Primate
But the relationship "a primate is an order" does not holds. So you cannot model it by inheritance. However, the "Primate order is an Order" is meaningful and you can model this relationship as:
object Primates extends Order
object Mammals extends Klass
You can then say that "Chimp belongs to the PrimateOrder", but that's a different relationship, that you can model as:
trait Animal {
def order: Order
def klass: Klass
}
trait Mammal extends Animal {
val klass = Mammals
}
trait Primate extends Mammal {
val order = Primates
}
class Chimp extends Primate
chimp.order //=> Primates
chimp.klass //=> Mammals
Upvotes: 2
Reputation: 134340
You are confusing an inheritance hierarchy with the hierarchical biological classification of things! For example; why would Chimpanzee
be an Animalia
? Why would a species be a phylum? These are distinct concepts.
What you are really looking for is aggregation (apologies for my lack of biological correctness)
trait Animalia { def phyla: List[Phylum] }
Then we might have:
trait Family { def phylum: Phylum }
trait Genus { def family: Family }
trait Species { def genus: Genus }
And an instance of this:
object Primates extends Family { val phylum = Mammals }
object Apes extends Genus { val family = Primates }
object HomoSapiens extends Species { val genus = Apes }
Upvotes: 1