ตัวแปร เมธอด และค่าคงที่ ของคลาส

ในบทก่อนหน้า คุณได้เรียนรู้เกี่ยวกับคลาสในเบื้องต้นไปแล้ว ในบทนี้จะเป็นเนื้อหาเพิ่มเติมเกี่ยวกับคลาส เราจะแนะนำให้คุณรู้จักกับสมาชิกประเภทอื่นๆ ของคลาส ได้แก่ ตัวแปรคลาส คลาสเมธอด และค่าคงที่ของคลาส และก่อนที่จะเริ่มต้น มาดูกันก่อนว่าสมาชิกของคลาสนั้นมีอะไรบ้าง

  • Instance variables หรือแอตทริบิวต์คือตัวแปรที่ใช้สำหรับเก็บข้อมูลของออบเจ็ค หรือใช้กำหนดคุณสมบัติให้กับออบเจ็ค
  • Instance methods คือเมธอดที่ใช้กำหนดการทำงานออบเจ็ต หรือดำเนินการบางอย่างเกี่ยวกับแอตทริบิวต์ของออบเจ็ค
  • Class variables คือตัวแปรที่ประกาศไว้ในคลาส และไม่ใช่ตัวแปรของออบเจ็ค
  • Class methods คือเมธอดที่ประกาศไว้ในคลาส และไม่ใช่เมธอดของออบเจ็ค
  • Class constants คือค่าคงที่ประกาศไว้ในคลาส

Instance variables และ Instance methods ที่เป็นตัวแปรและเมธอดที่ผูกับออบเจ็ค ซึ่งคุณได้เรียนรู้ไปแล้วในบทคลาสและออบเจ็ค ในบทนี้เราจะพูดถึงสมาชิกประเภทที่เหลือ

Class methods

คลาสเมธอด (Class methods) นั้นเป็นเมธอดที่ผูกติดอยู่กับคลาส มันใช้สำหรับกำหนดเมธอดเพื่อทำงานบางอย่างเกี่ยวกับคลาสนั้น คลาสเมธอดไม่ได้เป็นส่วนหนึ่งของออบเจ็คที่สร้างมาจากคลาส แต่ว่ามันสามารถใช้เพื่อทำงานบางอย่างเกี่ยวกับออบเจ็คเหล่านั้นได้ เราจะมีหลายตัวอย่างสำหรับการใช้งานคลาสเมธอด

ในตัวอย่างแรก เราจะสร้างคลาสของวงกลมซึ่งภายในคลาสจะมีแอตทริบิวต์สำหรับเก็บรัศมีของวงกลม และเมธอดเพื่อคำนวณหาพื้นที่ของวงกลม และเราจะสร้างคลาสเมธอดในคลาสนี้ นี่เป็นโค้ดของโปรแกรม

class_methods.rb
class Circle

    attr_accessor(:radius)

    def initialize(r)
        @radius = r
    end

    def area
        return Math::PI * (@radius ^ 2)
    end

    def self.compare(a, b)
        if a.area < b.area
            return -1
        elsif a.area > b.area
            return 1
        else
            return 0
        end
    end

end

c1 = Circle.new(5)
c2 = Circle.new(8)

puts "c1 area: #{c1.area}"
puts "c2 area: #{c2.area}"
puts Circle.compare(c1, c2)

ในตัวอย่าง เราได้สร้างที่มีชื่อว่า Circle คลาสนี้ใช้สำหรับสร้างออบเจ็คของวงกลม ภายในคลาสเราได้กำหนดให้คลาสมีหนึ่งแอตทริบิวต์คือ radius ซึ่งเป็นรัศมีของวงกลม และหนึ่งเมธอด area ที่ใช้สำหรับคำนวณหาพื้นที่ของวงกลมจากรัศมีของมัน

attr_accessor(:radius)
...
def area
    return Math::PI * (@radius ^ 2)
end

แอตทริบิวต์ radius นั้นสามารถเรียกอีกอย่างหนึ่งว่า Instance variable และเมธอด area นั้นจะเรียกว่า Instance methods ซึ่งทั้งสองอย่างนี้จะเป็นสมาชิกของออบเจ็ค กล่าวคือเมื่อเรานำคลาสไปสร้างออบเจ็ค เราจะสามารถเข้าถึงตัวแปรและเมธอดผ่านทางออบเจ็คได้นั่นเอง

def self.compare(a, b)
    if a.area < b.area
        return -1
    elsif a.area > b.area
        return 1
    else
        return 0
    end
end

สำหรับเมธอด self.compare นั้นเป็นคลาสเมธอด คลาสเมธอดนั้นเป็นเมธอดที่ผูกติดกับคลาส เราสามารถสร้างคลาสเมธอดได้โดยการขึ้นต้นชื่อคลาสด้วย self ซึ่ง self นั้นเป็นออบเจ็คที่ใช้อ้างถึงคลาสปัจจุบัน เมธอดนี้ใช้เพื่อเปรียบเทียบพื้นที่ของออบเจ็คสองออบเจ็ค โดยส่งค่ากลับเป็นตัวเลขจำนวนเต็ม ขึ้นอยู่กับว่าพื้นที่ของออบเจ็ค a นั้นน้อยกว่า มากกว่า หรือเท่ากับพื้นที่ของออบเจ็ค b

c1 = Circle.new(5)
c2 = Circle.new(8)

puts "c1 area: #{c1.area}"
puts "c2 area: #{c2.area}"

หลังจากนั้นเราได้นำคลาสมาสร้างออบเจ็คสองออบเจ็คคือ c1 และ c2 และกำหนดรัศมีให้กับออบเจ็คทั้งสองเป็น 5 และ 8 ตามลำดับ และเราได้แสดงผลพื้นที่ของออบเจ็ควงกลมทั้งสองโดยการเรียกใช้งานเมธอด area

puts Circle.compare(c1, c2)

ในคำสั่งนี้เป็นการเรียกใช้งานคลาสเมธอด สามารถเรียกได้ทันทีโดยใช้ชื่อคลาสและตามด้วยชื่อของเมธอด ในรูปแบบ Circle.compare เราไม่จำเป็นต้องสร้างออบเจ็คเพื่อเรียกใช้งานคลาสเมธอดเหมือนกับ Instance เมธอด

c1 area: 21.991148575128552
c2 area: 31.41592653589793
-1

นี่เป็นผลลัพธ์การทำงานของโปรแกรม เราได้แสดงพื้นของออบเจ็ควงกลมและแสดงผลลัพธ์การเปรียบเทียบพื้นที่จากเมธอด compare เมธอดส่งค่ากลับเป็น -1 ซึ่งหมายความว่าออบเจ็ค c1 นั้นมีพื้นน้อยกว่าออบเจ็ค c2

ตัวอย่างต่อไปสำหรับการใช้งานคลาสเมธอดคือในกรณีที่เราอยากจะประกาศเมธอด และใช้คลาสสำหรับจัดกลุ่มเมธอดเหล่านั้นเข้าด้วยกัน นี่เป็นตัวอย่าง

class_methods2.rb
class MyMath

    def self.add(a, b)
        return a + b
    end

    def self.subtract(a, b)
        return a - b
    end

    def self.multiply(a, b)
        return a * b
    end

    def self.divide(a, b)
        return a / b
    end

end

puts MyMath.add(2, 3)
puts MyMath.subtract(10, 3)
puts MyMath.multiply(8, 4)
puts MyMath.divide(7, 2)

ในตัวอย่างต่อมา เราได้สร้างคลาสที่มีชื่อว่า MyMath คลาสนี้ไม่มีแอตทริบิวต์และ Instance เมธอด นั่นหมายความว่ามันไม่สามารถนำไปสร้างออบเจ็คเพื่อใช้งานได้ ในทางกลับกัน ในคลาสได้มีการประกาศคลาสเมธอดสี่เมธอดขึ้นมา ซึ่งเมธอดเหล่าใช้สำหรับการดำเนินการพื้นฐานทางคณิตศาสตร์ ได้แก่ การบวก การลบ การคูณ และการหาร

ตัวอย่างนี้เพียงแค่ต้องการแสดงให้เห็นว่าเราสามารถสร้างเมธอดภายในคลาสสำหรับใช้งานได้ เมธอดเหล่านี้ไม่ได้มีความเกี่ยวข้องกัน แต่มันเป็นเมธอดสำหรับการดำเนินการพื้นฐานทางคณิตศาสตร์เหมือนกัน ดังนั้นเราจึงรวบรวมมันไว้ภายในคลาส MyMath

puts MyMath.add(2, 3)
puts MyMath.subtract(10, 3)
puts MyMath.multiply(8, 4)
puts MyMath.divide(7, 2)

หลังจากนั้นเป็นการเรียกใช้งานเมธอดต่างๆ และแสดงผลลัพธ์การทำงานของเมธอดเหล่านั้นออกมาทางหน้าจอ

5
7
32
3

นี่เป็นผลลัพธ์การทำงานของโปรแกรม ในตัวอย่างแสดงให้เห็นว่าเราสามารถสร้างเมธอดภายในคลาส เพื่อจัดกลุ่มเมธอดเหล่านั้นเข้าด้วยกันได้

สำหรับตัวอย่างของคลาสเมธอดที่พบได้ในภาษา Ruby เช่นในคลาส Math หรือคลาส Time สองคลาสนี้มีคลาสเมธอดเป็นจำนวนมากที่เราสามารถเรียกใช้ได้ นี่เป็นตัวอย่างการใช้งานคลาสเมธอดจาคลาส Math และคลาส Time

puts Math.sin(1)    # => 0.8414709848078965
puts Math.cos(1)    # => 0.5403023058681398
puts Math.tan(0.5)  # => 0.5463024898437905

puts Time.now       # => 2020-04-12 00:03:14 +0700

Class variables

ตัวแปรคลาส (Class variables) นั้นเป็นตัวแปรที่ผูกติดอยู่กับคลาส มันใช้สำหรับเก็บข้อมูลบางอย่างที่เกี่ยวข้องกับคลาสนั้น เราสามารถเข้าถึงตัวแปรคลาสได้ผ่านชื่อของคลาสโดยไม่จำเป็นต้องสร้างออบเจ็คเพื่อเข้าถึง ตัวแปรคลาสในภาษา Ruby นั้นจะเหมือนกับตัวแปร Static ในภาษาอื่นๆ มาดูตัวอย่างการประกาศตัวแปรคลาสในภาษา Ruby

class_variables.rb
class Person

    @@count = 0

    attr_accessor(:first_name, :last_name)

    def initialize(first_name, last_name)
        @first_name = first_name
        @last_name = last_name
        @@count = @@count + 1
    end

    def full_name
        return @first_name + " " + @last_name
    end

    def self.count=(value)
        @@count = value
    end

    def self.count
        return @@count
    end

end

p1 = Person.new("Matteo", "Marcus")
p2 = Person.new("George", "Wilde")
p3 = Person.new("Andy", "Murch")

puts "#{Person.count} objects were created"
puts p1.full_name
puts p2.full_name
puts p3.full_name

ในตัวอย่าง เราได้สร้างคลาส Person ซึ่งเป็นคลาสของบุคคลที่ประกอบไปด้วยแอตทริบิวต์สองตัวคือ first_name และ last_name มันใช้สำหรับเก็บชื่อและนามสกุลตามลำดับ และเรามีเมธอด full_name สำหรับรับค่าเอาชื่อเต็มที่ประกอบไปด้วยชื่อและนามสกุล

@@count = 0

สิ่งที่หน้าสนใจเกี่ยวกับคลาสนี้ก็คือเราได้ประกาศตัวแปรคลาสที่มีชื่อว่า @@count ตัวแปรคลาสในภาษา Ruby นั้นจะต้องขึ้นต้นด้วยเครื่องหมาย @@ เสมอ เราจะใช้ตัวแปรนี้สำหรับนับจำนวนออบเจ็คทั้งหมดที่ถูกสร้างจากคลาส Person ของเรา และเรากำหนดค่าเริ่มต้นให้กับตัวแปรเป็น 0

def initialize(first_name, last_name)
    @first_name = first_name
    @last_name = last_name
    @@count = @@count + 1
end

ภายในเมธอด initialize ซึ่งเป็นคอนสตรัคเตอร์ของคลาส เราได้เพิ่มค่าของตัวแปร @@count ขึ้นไปหนึ่ง นั่นหมายความว่าทุกๆ ครั้งที่มีการสร้างออบเจ็ค เราจะทำการนับว่าออบเจ็คถูกสร้างไปแล้วกี่ครั้งนั่นเอง

def self.count=(value)
    @@count = value
end

def self.count
    return @@count
end

สองเมธอดต่อมานั้นเป็นคลาสเมธอดสำหรับเข้าถึงตัวแปรคลาสจากภายนอกคลาส ในการเข้าถึงตัวแปรคลาสเพื่อกำหนดค่าหรืออ่านค่า เราจำเป็นต้องกำหนดเมธอดสำหรับการทำงานดังกล่าว ในตัวอย่างเราได้สร้างเมธอด self.count= เพื่อใช้สำหรับกำหนดค่าให้กับตัวแปรคลาส @@count และเมธอด self.count สำหรับรับเอาค่าของตัวแปรคลาสจากภายในคลาสไปใช้ที่ด้านนอกคลาส

p1 = Person.new("Matteo", "Marcus")
p2 = Person.new("George", "Wilde")
p3 = Person.new("Andy", "Murch")

หลังจากนั้นเรานำคลาสของเรามาสร้างออบเจ็คสามออบเจ็ค ทุกครั้งที่ออบเจ็คถูกสร้างตัวแปร @@count จะทำการนับเพิ่มขึ้นทีละหนึ่ง

puts "#{Person.count} objects were created"

ในโค้ดบรรทัดนี้เป็นการเรียกใช้งานคลาสเมธอด count เพื่อรับเอาค่าจากตัวแปรคลาส @@count มาแสดงที่ด้านนอกคลาส

3 objects were created
Matteo Marcus
George Wilde
Andy Murch

นี่เป็นผลลัพธ์การทำงานของโปรแกรม เราได้แสดงจำนวนออบเจ็คทั้งหมดที่ถูกสร้างโดยคลาส Person และแสดงชื่อของออบเจ็ค

เราสามารถเปลี่ยนแปลงค่าของตัวแปรคลาสจากภายนอกคลาสได้จากเมธอด self.count= ที่เราสร้างขึ้น ตัวอย่างนี้เป็นการรีเซตค่าในตัวแปรให้เท่ากับ 0

Person.count = 0

Class constants

ค่าคงที่ของคลาส (Class constants) นั้นเหมือนกับค่าคงที่แบบปกติที่ประกาศไว้ในส่วนของโปรแกรมหลัก แต่สิ่งที่แตกต่างกันคือค่าคงที่ของคลาสนั้นจะถูกประกาศไว้ภายในคลาสแทน และเช่นเดิมชื่อของมันจะต้องขึ้นต้นด้วยตัวพิมพ์ใหญ่และค่าของมันจะไม่สามารถเปลี่ยนแปลงได้ นี่เป็นตัวอย่างของการประกาศค่าคงที่ของคลาสในภาษา Ruby

class_constants.rb
class Blog

    NAME = "MarcusCode"
    URL = "marcuscode.com"
    AUTHOR = "Matteo Marcus"

end

puts Blog::NAME
puts Blog::URL
puts Blog::AUTHOR

ในตัวอย่าง เราได้สร้างคลาสที่ชื่อว่า Blog ภายในคลาสเราได้ประกาศค่าคงที่สามตัวสำหรับเก็บชื่อของบล็อค ที่อยู่ของบล็อค และชื่อผู้เขียนบล็อค การประกาศค่าคงที่นั้นจะใช้ตัวดำเนินการกำหนดค่า = เหมือนค่าคงที่ปกติ และชื่อของค่าคงที่จะต้องขึ้นต้นด้วยตัวพิมพ์ใหญ่เสมอ หรือเป็นตัวพิมพ์ใหญ่ทั้งหมดก็ได้

puts Blog::NAME
puts Blog::URL
puts Blog::AUTHOR

หลังจากที่ค่าคงที่ได้ถูกประกาศภายในคลาส เราสามารถเข้าถึงค่าคงที่จากภายนอกคลาสได้โดยใช้ชื่อคลาส ตามด้วยเครื่องหมาย :: และชื่อของค่าคงที่ในรูปแบบ Blog::NAME ในตัวอย่างเราได้แสดงค่าคงที่ทั้งสามออกทางหน้าจอ

MarcusCode
marcuscode.com
Matteo Marcus

นี่เป็นผลลัพธ์การทำงานของโปรแกรม ในการประกาศและใช้งานค่าคงที่ของคลาสในภาษา Ruby

ในบทนี้ คุณได้เรียนรู้เกี่ยวกับตัวแปร เมธอด และค่าคงที่ของคลาสในภาษา Ruby เราได้พูดถึงตัวแปรและเมธอดของคลาส ซึ่งใช้สำหรับเก็บข้อมูลและทำงานบางอย่างเกี่ยวกับคลาส และค่าคงที่ของคลาสที่ใช้สำหรับประกาศค่าคงที่ไว้ในคลาส เพื่อแยกหมวดหมู่ของค่าคงที่ให้เป็นระเบียบและเพื่อให้ง่ายต่อการใช้งาน