Search code examples
rubyinheritancemultiple-inheritance

Problem with inheritance. NoMethodError: undefined method


I'm making a university project. The project is about a game (like a monopoly). This week, we have studied inheritance and now, we have to use in the project. I have some problems with the children class constructors.

I have this parent class:

class Casilla
    attr_reader :numeroCasilla
    attr_accessor :precioCompra

    def initialize(numCas, coste)
      @numeroCasilla = numCas
      @precioCompra = coste
    end

    def self.copia(casilla)
      self.new(casilla.numeroCasilla, casilla.precioCompra)
    end

    # Dejamos este método ya que no podemos modificar precioCompra desde calle
    def setTitulo(ttl)
      @precioCompra = ttl.precioCompra
    end

    def soyEdificable; end
    def tengoPropietario; end

    private :setTitulo
  end

This is one child class:

class Calle < Casilla
        attr_reader :titulo
        attr_reader :tipo

      # def initialize(casilla, ttl)
      #     copia(casilla,ttl)
      # end

        def self.copia(casilla,ttl)
            super(casilla)
            @titulo = ttl
            @tipo = TipoCasilla::CALLE

            self
        end

        def soyEdificable
            salida = true
            salida
        end

        def tengoPropietario
            salida = @titulo.tengoPropietario();
            salida
        end

        def setTitulo(ttl)
            @titulo = ttl
            super(ttl)
        end

        def propietarioEncarcelado
            @titulo.propietarioEncarcelado
        end

        def asignarPropietario(jugador)
            @titulo.propietario = jugador;
            @titulo
        end

        def pagarAlquiler
            @titulo.pagarAlquiler
        end

        private :setTitulo
    end

The last child class:

class OtraCasilla < Casilla
        attr_reader :tipo

      # def initialize(casilla, tp)
      #     copia(casilla)
      #     @tipo = tp
      # end

        def self.copia(casilla, tipo)
            super(casilla)
            @tipo = tipo

            return self
        end

        def soyEdificable
            salida = false
            salida
        end

        def tengoPropietario
            salida = false
            salida
        end 

        def to_s
          puts super
          puts " \n Tipo: #{@tipo} \n"
        end
    end

The parent class has two diferent ways to appear, like a "Calle" with specifics variable or other diferent forms (with same variables). TipoSorpresa is a enum with types of "Casilla". The problem is with the constructors. In other class when I want to initialize a Calle object or otraCasilla object, I use

Calle.copia(···)
otraCasilla(···)

The run works fine, but when I want to access to a class element, the compiler say me that this element doesn't exist. This is the zone of the error:

@casillas = Array.new

@casillas<< OtraCasilla.copia(Casilla.new(0, 0), TipoCasilla::SALIDA)
@casillas<< Calle.copia(Casilla.new(1, 500), TituloPropiedad.new("Av. de Andalucía", 500, 50, 20, 150, 250))
puts @casillas[1].titulo.nombre  # I put this to check if the constructor is good

In the last line, we have this error:

NoMethodError: undefined method `titulo' for ModeloQytetet::Calle:Class

Thank you for your time and sorry if my english is not good.


Solution

  • In your copia method, you are returning self, but that is a class method, so self refers to the class itself.

    Instead, you want to return the instance of the class. I haven't seen inheritance used in this way exactly, but I would guess that when you call super(casilla), it calls the top-level copia method which calls new inside the Casilla class. So you would end up with a Casilla instance.

    I would remove all the super calls from each copia method (and any other class methods) to get things working and then DRY (remove duplications) it up afterwards.