Bu, Liskov Substitution Principle ile ilgilidir: weaker access privileges in subclass (even for Java)'u atayamazsınız. var
değerini def
yapmak, ayarlayıcıyı def x_= (y: T): Unit
özel olarak yapar (@Staix'in dediği gibi). Yani, Seadan Car
, Car
resmi türüne sahip olduğunda - erişilmemelidir, ancak derleyici genel olarak bu tür durumları bulamamaktadır (yalnızca resmi türler derleme zamanında bilinir), böylece bu tür davranışlar daha zayıf bir ayrıcalık gibi devre dışı bırakılır:
val car2 = new SeadanCar
car.age = 422 //compiler error, can't mutate "def age"
val car: Car = new SeadanCar
car.age = 42 //now you had mutated immutable
Değiştirilebilirlik Prensibi, davranış, üst düzeyine döktükten sonra değiştirilmemelidir. Öte yandan
, scala Régis Jean-Gilles söyledi @ gibi değişkenin sadece gaz giderici kısmını geçersiz olabilir, ama sezgisel olarak kullanıcı
var
override def
sonra değişmez hale bekler çünkü bu, çok açık bir çözüm değildir. Ve aslında
var
'unuzu
var
'u görmeniz gereken gibi iki hizmet (okuyucu ve yazar) olarak görmeniz, UAP-uyumluluğun tam tersini gerektiriyorken, hem okuyucu hem de yazarın tek bir notasyon ile temsil edilmesi gerekir.
P.S. Asıl soru, scala'nın UAP uyumluluk eksikliğine işaret ediyor. Dediğim gibi, sadece var
'un okuyucusu ve yazarı olduğu gibi bırakarak UAP ile tutarsız olacak - bu, var
'u geçersiz kılma özelliğini engelliyor (böylece varlıkları her iki şekilde de geçersiz kılabilirsiniz: hesaplama ve depolama gibi) LSP nedeniyle zaten geçersiz kılabilirsiniz. Ama şu anki scala'nın çözümü de sorunlu.
trait Car { def age: Int = 7; def age_=(a: Int) = {}}
class SeadanCar extends Car { override def age: Int = 5}
Ama yapamam
// just repeating your example
trait Car { var age: Int = 7 }
class SeadanCar extends Car { override def age: Int = 5}
Yani Scala'nın miras UAP ile uyumlu olacak şekilde değil görünüyor: Eğer mümkün olduğunu görebilirsiniz. IMHO, en büyük sorun, okuyucu ve var'ın kendisinin de aynı isimlere sahip olması. Bu yüzden onları ayırt edemezsiniz (tanımlarken, erişemediğinizde).
scalaxx> (new SeadanCarReadOnly).age //call age_ here
resxx: Int = 5
scalaxx> (new SeadanCarReadOnly).age_
resxx: Int = 5
gibi değil: benim önerilen örnekte age_
geçersiz kılma gitmelidir ki
trait Car { def age_: Int = 7; def age_=(a: Int) = {}}
class SeadanCarReadOnly extends Car { override def age: Int = 5} //can't compile as reader is closed
class SeadanCarVar extends Car { override var age: Int = 5}
class SeadanCarReadOnly extends Car { override def age_: Int = 5}
trait Car2 { var age = 100500 }
class SeadanCarReadOnly extends Car2 { override def age_: Int = 5}
Not: Ben gibi bir şeyle bunu çözmek istiyorum Cource
trait Car2 { @BeanProperty var age = 100500 }
class SeadanCarReadOnly extends Car2 { override def getAge: Int = 5}
//which leads to inconsistency:
scala> (new SedanCar()).age
res6: Int = 30
scala> (new SedanCar()).getAge
res7: Int = 54
, böyle yaklaşım var age
ve def age_; def age_=
'u aynı anda geçersiz kılmayı devre dışı bırakmalıdır:
trait Car2 { var age = 100500 }
class SeadanCarReadOnly extends Car2 {
override var age = 17;
override def age_: Int = 5 //should be compile error here
}
ancak bu durum söz konusu değişebilirlik/immutabilty kısmı ile ilgili olarak
PS/2 Sadece söz geriye dönük uyumluluk, hızla Scala dilinde bunu uygulamaya zordur, definetely (bunu yapamaz nedeniyle) LSPye:
trait Car { def age: Int = 7; def age_=(a: Int) = {}}
class SedanCar extends Car { override val age = 42 }
regardl:
trait Car { var age: Int = 32 } //or without initial value
class SedanCar extends Car { override val age = 42 }
Ve nedeniyle LSP + UAP için, bunu yapmak mümkün olmamalı Bu gerçeği sizin için :)
Tanılar, dönüştürülebilir varaibles değil, yöntem tanımları olduğundan. SedanCar'da yaş = 32’yi yaparsanız ne yapmak istersiniz? –
Bence OP'nin sorusu tamamen mantıklı. Scala genellikle iyi bir sebepten dolayı tek tip erişim ilkesine bağlı olarak sunulur. Daha sonra, 'yaş' var tanımını, bir çift getter ve ayarlayıcı ('age' ve age_ =') yönteminin tanımından başka bir şey olarak görmemek mantıksız olmaz. Bu durumda, aslında yalnızca alıcıyı geçersiz kılacak ve ayarlayıcıyı olduğu gibi bırakacak olan 'yaşı' kesinlikle geçersiz kılmalıyım. –