Forum: Ruby methods in subclasses

Posted by john rxjmo (rxjmo)
on 2013-03-07 22:42
Hi,
I'm new to ruby programming and I want to ask you if you can help me on
this.
I have created 3 classes (c1, c2, c3) and I want to do 3 sublasses (sc1,
sc2, sc3).

the classes are related.

I want to define a method in cs1 (uses variables and methods from c1)
and use it from sc2.

When I run the module I get this error:
I get this error : "NoMethodError: undefined method `r180' for
#<c1:0x000000055683a8>

sample code:
class sc2 < c2
  # this method (m1) is defined in c2
  def m1
    super
    # I want to add this part
    # @b: defined in c2 as an instance of c1
    @r.bind('u', proc {@b.r180})
  end
end

class sc1 < c1
  # I added this method
  def r180
    # go, @gir, @cb.m() and d() are defined
    # in c1
    if !go? and @gir?
      @cb.m()
    end
    d()
  end
end

Can you help me please.
Posted by Eric Christopherson (echristopherson)
on 2013-03-07 23:30
(Received via mailing list)
On Thu, Mar 7, 2013 at 3:42 PM, john rxjmo <lists@ruby-forum.com> wrote:
>
>     # @b: defined in c2 as an instance of c1
>       @cb.m()
>     end
>     d()
>   end
> end

Is r180 actually defined in c1? It would be easier to help if we could
see c1 and c2.
Posted by john rxjmo (rxjmo)
on 2013-03-08 09:11
No, r180 is not defined in c1, only in the subclass sc1

class c3
  def initialize (pa, b)
    @alr = pa
    @ri = (0..(@alr.size-1)).to_a.sample
    @c = AC.sample
    @bp = [5, 0]
    @b = b
    @moved = true
  end

  ...

 end

=============================================

class c2
  def initialize
    @r = TRoot.new
    @t = TTimer.new
    set_b
    @running = true
    m1
    buttons
    rg
  end

  ...

  def m1
    @r.bind('n', proc {self.ng})

    @r.bind('p', proc {self.pause})

    @r.bind('q', proc {exitProgram})

    @r.bind('a', proc {@b.mle})

    @r.bind('w', proc {@b.rcc})
  end
end

================================================

class c1

  def initialize (g)
    @gr = Array.new(nr) {Array.new(nc)}
    @cb = c3.np(self)
    @sc = 0
    @ga = ga
    @delay = 500
  end

  ...
  # this fucntion is like the I wanna add to my subclass
  def rcc
    if !go? and @gir?
      @cb.m()
    end
    d()
  end
end
Posted by Calvin B. (calvin_b)
on 2013-03-08 13:01
(Received via mailing list)
Hello,

On 08.03.2013 09:11, john rxjmo wrote:
> No, r180 is not defined in c1, only in the subclass sc1
that's the problem, then. c1 does not know anything about the methods
you define on it's subclasses. That's just how OOP goes. Think of it
this way: A Dog is an Animal (class Dog inherits from class Animal). Can
you make assumptions on what an instance of Dog can do if you have an
Animal? The Animal class may define a method "walk" (which is then
available in all subclasses), but if it doesn't define a method "bark",
how can you call "bark" on an Animal? Inheritance works just one way. (I
hope my analogy helped you, if not, I'm sorry if I confused you even 
more..)

To solve your problem you could define @b in your initialize method of
c2 as an instance of sc1 (because sc1 has a method r180 while c1 does
not). You could also define a method r180 on c1, although that won't
give you the behavior you defined in sc1 - at least not if you don't
copy r180's source from sc1.
Hope I could help!

Kind regards,
Calvin
Posted by john rxjmo (rxjmo)
on 2013-03-08 19:26
I think I'm confused before your post :).
I thought that the goal of subclasses is the ability to add more methods 
than the ones in the super class.

Thank you for your help.
Posted by Calvin B. (calvin_b)
on 2013-03-08 22:19
(Received via mailing list)
Hello,

On 08.03.2013 19:26, john rxjmo wrote:
> I think I'm confused before your post :).
> I thought that the goal of subclasses is the ability to add more methods
> than the ones in the super class.
>
> Thank you for your help.

by expanding on the subclasses you add information, yes, but that
doesn't affect the parent class.

Kind regards,
Calvin
Posted by Matthew Kerwin (mattyk)
on 2013-03-09 00:37
(Received via mailing list)
On Mar 9, 2013 7:20 AM, "Calvin Bornhofen" <calvin.bornhofen@web.de> 
wrote:
>> Thank you for your help.
>
>
> by expanding on the subclasses you add information, yes, but that doesn't
affect the parent class.
>
> Kind regards,
> Calvin
>

Indeed. The point of a subclass is to create a *new type* of object, 
which
refines or specialises or builds on an existing type.

For example, you could have the following class hierarchy:

vehicle > land_vehicle > car

All vehicles share some common code, properties, and methods; but cars 
have
some that planes and trains don't. Modifying 'car' cannot affect 
'vehicle'
or 'land_vehicle' without also affecting planes and trains.

What makes it a bit more complex is that in this case it's possible (and
presumably sensible) to instantiate a 'vehicle' directly, and have that
object be a fully functioning transporter. Thus land_vehicle and car are
*specialising* vehicle (restricting the domain, for example limiting it 
to
only land-based travel).

Now in this case there seems to be some parallel hierarchy going on;
extending the metaphor, it's as though vehicle includes a 'driver' 
object,
but car wants to replace it with a 'car_driver' (and plane with 'pilot',
etc.)  This is a lot trickier; you need to refactor it so that the code 
in
'vehicle' that instantiates 'driver' can be overridden in the 
sub-classes,
or something similar.

I find drawing on paper or a whitboard helps.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.