Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding subclass methods with subclassed arguments?

How can I force base methods to take in the same specific subclass instance when overriden by a subclass?

i.e.:

abstract class Animal {
  def mateWith(that: Animal)
}

class Cow extends Animal {
  override def mateWith...?
}

Logically, a Cow should only be able to mateWith another Cow. However, if I do override def mateWith(that: Cow), this doesn't actually override the base class method (which I want it to, since I want to enforce its existence in the subclass).

I could check to make sure the other instance is of type Cow, and throw an exception if it isn't - is this my best option? What if I have more animals? I would have to repeat the exception-throwing code.

like image 637
Kevin Li Avatar asked Apr 17 '12 21:04

Kevin Li


People also ask

Can override method have different arguments?

No, while overriding a method of the super class we need to make sure that both methods have same name, same parameters and, same return type else they both will be treated as different methods.

What methods must be overriding in the subclass?

Methods a Subclass Must Override Subclass must override methods that are declared abstract in the superclass, or the subclass itself must be abstract. Writing Abstract Classes and Methods discusses abstract classes and methods in detail.

When should you override a method in a subclass?

When a method in a subclass has the same name, same parameters or signature, and same return type(or sub-type) as a method in its super-class, then the method in the subclass is said to override the method in the super-class.

Which methods are not allowed to override in subclass?

3) An instance method cannot override a static method, and a static method cannot hide an instance method.


1 Answers

abstract class Animal[T <: Animal[T]] {
  def mateWith(that: T)
}

class Cow extends Animal[Cow] {
  override def mateWith(that: Cow) { println("cow") }
}

class Dog extends Animal[Dog] {
  override def mateWith(that: Dog) { println("dog") }
}

And use it like this:

scala> (new Cow).mateWith(new Cow)
cow

scala> (new Cow).mateWith(new Dog)
<console>:17: error: type mismatch;
 found   : Dog
 required: Cow
              (new Cow).mateWith(new Dog)
                                 ^

No exception-throwing code needed; the type system handles it for you at compile-time!

like image 118
dhg Avatar answered Nov 14 '22 23:11

dhg