Scala: передача экземпляра дочернего класса в функцию родительского класса - PullRequest
3 голосов
/ 22 сентября 2011

Почему Scala Repl говорит:

<console>:10: error: type mismatch;  
 found   : Car#Door  
 required: _1.Door where val _1: Car  

Когда я запускаю это утверждение:

var c = New Car  
c.is_door_open(c.door)  

Это относится к этому классу:

class Car {  
    var door = new Door(true)  

    class Door (var state: Boolean = true) {  }    

    def is_door_open(d: Door) {  
         println(d.state)  
    }  
}

1 Ответ

6 голосов
/ 22 сентября 2011

Если у вас есть внутренний класс как Door, то каждый экземпляр класса Car определяет свой тип Door.В is_door_open (d: Door), Дверь означает Дверь вмещающего экземпляра Автомобиля.Тип Car # Door в сообщении об ошибке означает дверь любого автомобиля, это общий тип для всех дверей.

Когда вы звоните c.is_door_open(c.door), Car из c.door должен совпадать с c из c.is_door_open, поскольку это то, что требуется для объявления is_door_open (оно должно иметьбыл d: Car#Door в противном случае).И более того, они должны быть одинаковыми для удовлетворения компилятора, который имеет некоторые точные правила для этого.Здесь кажется очевидным, что cars одинаковы.Не так, потому что c является var, поэтому не является стабильным идентификатором.

Представьте себе код c.is_door_open({c = new Car; c.door}).Придумано, конечно, но это показывает, что вы не можете полагаться на то, что c будет одним и тем же автомобилем.

Итак, среди ваших решений, в зависимости от того, каким может быть ваш реальный код:

  1. Сделайте c a val вместо var
  2. декларированияis_door_open параметр как d: Car # Door
  3. Прекратите делать Door зависимым от экземпляра Car, объявите его вне класса, если вы хотите, чтобы он был Car.Door, поместите его в компаньонobject Car вместо class Car
  4. Сделайте is_door_open методом Door (без аргумента Door), а не Car.Он имеет полный доступ к вмещающему автомобилю (с Car.this как в java или объявив псевдоним для этого в автомобиле с class Car {car =>)
...