2016-06-02 24 views
0

Ich studiere gerade in der Code-Schule und Mentor geben uns eine Heimarbeit, aber ich verstehe es nicht wirklich. Kannst du mir helfen?Erstellen von Klassen für geometrische Formen (Punkte, Linien, Quadrat, Dreieck, etc.) (Rubin)

So waren wir eine geometrische Formen über Klassen erstellen gestellt:

  1. vor allem wir eine Klasse Punkt
  2. das schaffen müssen, dann müssen wir Klasse Line (Linie erstellen - wenn zwei Punkte verbunden sind,
  3. )
  4. und der nächsten Schritt, zum Beispiel wollen wir einen Platz

und ich Code habe erstellen begonnen, und erstellt eine Klasse Point, mit zugänglichen Koordinaten (2d):

class Point 
    attr_accessor :x, :y 
    def initialize 
    @x = 10 
    @y = 10 
    end 
    def x=(value) 
    @x = value 
    end 
    def x() 
    @x 
    end 
    def y=(value) 
    @y = value 
    end 
    def y() 
    @y 
    end 
end 

Und zum Beispiel möchte ich eine neue Punktklasse erstellen. Also:

p = Point.new 
    p.x = 1 
    p.y = 5 
    print p # -> #<Point:0x007f9463089cc0> 

Und als Ergebnis, ich habe etwas, was wie folgt aus:

#<Point:0x007f9463089cc0> 

Was bedeutet das?

Aber wenn ich p.x und p.y drucken fragen - dann werde ich eine verständliche Folge haben:

print p.x, ", ", p.y # -> 1, 5 

Mache ich etwas falsch oder wie kann ich dieses Ergebnis auf dem Bildschirm zu verstehen?

Bitte, ich brauche Hilfe wirklich, dies zu verstehen ...

Vielen Dank für Ihre Hilfe!

Und eine andere Frage erscheint, gibt es irgendeine Verwendung in realen Programmierauftrag, um Punkt, Linien und geometrische Formen zu erstellen?

+0

Beachten Sie, dass 'print p' tatsächlich' print p.to_s'. Probieren Sie 'print p.inspect' aus. – Raffael

+0

@Raffael Nicht klar, was du meinst. Wenn das der Fall ist, wäre es eine unendliche Rekursion. – sawa

Antwort

1

Zuerst brauchen Sie nicht die Setter und Getter. Ich meine, Sie diese Methoden nicht schreiben müssen:

def x=(value) 
    @x = value 
    end 
    def x() 
    @x 
    end 
    def y=(value) 
    @y = value 
    end 
    def y() 
    @y 
    end 

Der Grund, warum Sie sich nicht diese Methoden benötigen, weil Sie diesen Aufruf haben:

attr_accessor :x, :y 

und das Verfahren (attr_accessor) tut Genau dieser Job für dich.

Zweitens möchten Sie möglicherweise etwas Flexibilität in Ihrem Konstruktor erlauben, d. H. Ihre Initialisierungsmethode, um die Werte für x und y zu übergeben und sie einfach auf 10 zu setzen, wenn nichts übergeben wird.So können Sie tun, um diese

def initialize(x = 10, y = 10) 
    @x = x 
    @y = y 
end 

Auf diese Weise werden Sie diese:

p1 = Point.new 
puts p.x # => 10 
puts p.y # => 10 

p2 = Point.new(15, 20) 
puts p.x # => 15 
puts p.y # => 20 

Beachten Sie, wie für p1 Ich habe keine Argumente übergeben und noch x und y beide fertig, wie erwartet, das ist weil wir einen Standardwert für sie in der Methodendefinition setzen, hier:

def initialize(x = 10, y = 10) 
Jetzt

, in Bezug auf Ihre Frage, warum sehen Sie das:

p = Point.new 
p.x = 1 
p.y = 5 
print p # -> #<Point:0x007f9463089cc0> 

was Punkt: 0x007fa003885bf8 bedeutet, dass Sie eine Instanz der Klasse Point haben (was Sie in Ihrer Variablen p haben). Standardmäßig ruft Ruby die Methode to_s für ein Objekt auf, wenn Sie versuchen, es zu drucken, da Sie in Ihrem Fall die Methode nicht definiert haben, die die Vererbungskette durchläuft, um zu sehen, wer diese Methode definiert. Es stellt sich heraus, dass diese Methode in der Object-Klasse gefunden wird (alle Ruby-Objekte erben implizit von der Object-Klasse). Das Standardverhalten dieser Methode besteht darin, den Namen der Klasse gefolgt von der ID der Instanz im folgenden Format auszudrucken: # (check : http://ruby-doc.org/core-2.3.1/Object.html#method-i-to_s)

Wenn Sie, dass dann können Sie die to_s Methode, um so etwas wie dies außer Kraft setzen ändern wollen:

def to_s 
    "Point #{x},#{y}" 
end 

auf diese Weise Sie erhalten:

puts Point.new # => Point 10,10 

Hoffnung, das hilft.

+0

Sie können auch 'p3 = Point.new (15)' anzeigen und beachten, dass der Wert von '@ y' nicht festgelegt werden kann und' @x' auf den Standardwert gesetzt ist. –

1

Es ist nichts falsch. #<Point:0x007f9463089cc0> bedeutet einfach, dass es sich um eine Instanz (#<>) der Klasse Point mit der Objekt-ID 0x007f9463089cc0 handelt. Eine Objekt-ID ist ein Bezeichner für die Ruby-Laufzeit, um jedes Objekt zu finden, ähnlich wie eine Speicheradresse.

Obwohl alles in Ordnung ist, gibt es in Ruby immer einen Weg, der zu weniger Code führt. Zum Beispiel

class Point 
    attr_accessor :x, :y 

    def initialize(x = 10, y = 10) 
    @x, @y = x, y 
    end 
end 

Oder sogar

Point = Struct.new(:x, :y) 
+0

Aber was ist der beste Weg, um diese Art von Arbeit zu machen? Ich verstehe: der kleinere Code = ist der bessere Weg. Aber was ist mit Computerspeicher, welche Art von Code benötigt weniger Speicher? –

+0

@AndreyDrozdov In diesem speziellen Fall müssen Sie nicht zu viel über den Speicherverbrauch nachdenken, da alle Arten zum Erstellen der Klasse "Point" O (1) Speicher verbrauchen, weit weniger als das Laden von Daten in Arrays oder Hashes, die O (n) Speicher oder das Laden großer Dateien. – Aetherus

0

Da erklären Sie attr_accessor :x, :y Sie tatsächlich brauchen nicht Getter und Setter für x und y zu definieren. So Ihre Klasse kann als

class Point 
    attr_accessor :x, :y 
    def initialize 
    @x = 10 
    @y = 10 
    end 
end 

Sie to_s eine Methode hinzufügen können auch vereinfacht werden Punkt

class Point 
    attr_accessor :x, :y 
    def initialize 
    @x = 10 
    @y = 10 
    end 

    def to_s 
    "(#{x}, #{y})" 
    end 
end 

so können Sie puts p verwenden und erhalten als ouptut (10, 10) wenn Sie

p = Point.new 
puts p 
(10, 10) 
tun

Hier bevorzuge ich puts statt print, weil es eine ne einfügen w Zeilenzeichen nach der Ausgabe, und es sieht besser lesbar aus. In to_s Methode verwende ich Ruby's String-Interpolation "#{}", um eine schöne Ausgabe für Ihre Punkt-Instanz zu erstellen.

0

Methods print und puts Ausgang das Ergebnis to_s und p gibt das Ergebnis der inspect. Wenn Sie diese Methoden nicht überschreiben, gibt eine benutzerdefinierte Klasse, die Object erbt, standardmäßig das Formular #<class_name:object_id> zurück, das Sie erhalten haben. Wenn Sie eine andere Ausgabe wünschen, überschreiben Sie diese Methoden, zum Beispiel

class Point 
    def to_s 
    "#@x,#@y" 
    end 
end 
... 
print p