Forum: Italian Ruby user group Metodi di classi ereditate

6f8382c757ca1573eaf7b61a807800ce?d=identicon&s=25 Iwan Buetti (Guest)
on 2013-07-08 11:43
(Received via mailing list)
Carissimi lettori,
vi illustro il seguente problema relativo alla chiamata di un metodo di
una classe ereditata.

Ho due classi Time1 e Time2 che ereditano in cascata da Time (tralascio
i metodi particolari)

class Time1 < Time
  # ...
end

class Time2 < Time1
  # ...
end

t = Time2.now
r = t + 3600 # adding 1 hour
purtroppo ora r  di class Time, e invece vorrei che rimanesse di classe
uguale a quella di partenza, ovvero Time2.

Allora introduco in Time dei metodi per "ricastare" e modifico come qui
di seguito:

Time.class_eval do
  def to_time2
    Time2.parse(to_s)
  end

  def to_time1
    Time1.parse(to_s)
  end
end

class Time1 < Time
  def +(seconds)
    super(seconds).to_time1
  end
end

class Time2 < Time1
  def +(seconds)
    super(seconds).to_time2
  end
end

r = Time2.now + 3600
ora r  correttamente di class Time2, tuttavia ci sono 2 casting in
cascata che suppongo poco performanti

Come posso modificare il codice affinch quando chiamo un metodo di
istanza di Time da un'istanza di classe che eredita da essa (cio Time1 o
Time2) il tipo del valore ritornato sia uguale a quella del chiamante?


Grazie mille per ogni risposta,
ciao

iwan
1a45b192d0bbaf167afb43a41859e313?d=identicon&s=25 Ju Liu (Guest)
on 2013-07-08 12:23
(Received via mailing list)
Ciao Iwan,

direi che in generale l'approccio è corretto, perché il metodo '+' di
Time
restituisce un oggetto di tipo Time; quindi se vuoi che restituisca
qualcos'altro devi ricastare l'oggetto alla classe che desideri (se vuoi
usare super), oppure ridefinire completamente il metodo in modo da
sostituirne integralmente il comportamento.

L'unico problema che vedo con il tuo codice è che viola il principio OOP
che le classi madri non dovrebbero mai sapere nulla delle classi figlie,
mentre tu stai inserendo i metodi 'to_time1' e 'to_time2' che vanno a
sporcare la classe madre con specifiche implementazioni delle classi
figlie. Quello che farei io è qualcosa di questo tipo:

class Time1 < Time
> puts r.inspect
>
> r = Time2.now + 7200
> puts r.class
> puts r.inspect
>

che restituisce qualcosa di questo tipo

Time1
> 2013-07-08 13:20:39 +0200
> Time2
> 2013-07-08 14:20:39 +0200
>

Dimmi se qualcosa non ti è chiaro :)

    Ju

--*
*M.Sc. Ju Liu
Card: http://zerp.ly/ju-liu
--
Società Cooperativa weLaika
Corso Vigevano 14/B, 10154 Torino (TO), Italy
http://welaika.com - info@welaika.com


2013/7/8 Iwan Buetti <iwan.buetti@gmail.com>
Dfa0e5f195b6f312006b465809b76b0b?d=identicon&s=25 Emanuele DelBono (Guest)
on 2013-07-08 12:33
(Received via mailing list)
+1 per JU

Aggiungo:

http://en.wikipedia.org/wiki/Liskov_substitution_principle


2013/7/8 Ju Liu <ju.liu@welaika.com>
6f8382c757ca1573eaf7b61a807800ce?d=identicon&s=25 Iwan Buetti (Guest)
on 2013-07-08 14:29
(Received via mailing list)
WOW! Bello, mi piace! :-)
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.