Rich Oliver
Rich Oliver

Reputation: 6119

Scala and OO: Specifying heirachy levels in super class

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

Answers (3)

Rich Oliver
Rich Oliver

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

paradigmatic
paradigmatic

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

oxbow_lakes
oxbow_lakes

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

Related Questions