getters และ setters ทำงานอย่างไร?


107

ฉันมาจากโลก php คุณช่วยอธิบายได้ไหมว่า getters และ setters คืออะไรและสามารถให้ตัวอย่างได้หรือไม่?


@ yegor256 ฉันเข้าใจการเปรียบเทียบ dog & ball ของคุณและฉันก็สนับสนุนมันด้วยซ้ำ แต่ถ้าวัตถุ "สิ่งมีชีวิต" เก็บค่าดั้งเดิมเป็นครั้งคราวเช่น ID? จะเป็นอย่างไรหากคุณต้องการก้าวไปไกลกว่าการมอบหมายงานง่ายๆ แต่ไม่ต้องการเขียนชั้นเรียนใหม่เพื่อจัดการกับค่าดั้งเดิมเท่านั้น
Jacksonkr

คำตอบ:


127

ไม่จำเป็นต้องมีบทช่วยสอนสำหรับเรื่องนี้ อ่านข้อมูลเกี่ยวกับการห่อหุ้ม

private String myField; //"private" means access to this is restricted

public String getMyField()
{
     //include validation, logic, logging or whatever you like here
    return this.myField;
}
public void setMyField(String value)
{
     //include more logic
     this.myField = value;
}

11
ดังนั้น getter เป็นเพียงวิธีการรับฟิลด์ส่วนตัวและ setter กำลังตั้งค่าฟิลด์ใหม่ ขอบคุณสำหรับคำอธิบายที่ยอดเยี่ยมตามรหัส
ajsie

1
คุณช่วยส่งพารามิเตอร์ไปยัง getter ได้ไหม
ajsie

2
noname: ไม่ใช่และไม่ Getter เป็นวิธีการรับค่า แต่ไม่เปิดเผยค่าที่มีอยู่ในฟิลด์นั่นคือถ้าคุณเรียกsomeObj.getTime().setHour(5)ว่าไม่ควรส่งผลต่อsomeObjสถานะภายในของ นอกจากนี้ setters และ getters (accessors และ mutators ตามชื่อนักแสดง)มีลายเซ็นวิธีการที่เข้มงวดมากซึ่งหมายความว่า getter ไม่มีพารามิเตอร์ใด ๆ วิธีการโดยทั่วไปควรทำเพียงสิ่งเดียวเท่านั้น
Esko

4
@noname: เมื่อสิ่งที่เรียบง่ายได้รับชื่อที่ซับซ้อน / ใหญ่ / นามธรรมคุณจะมีสิ่งที่เรียกว่า "รูปแบบการออกแบบ" .... และนี่คือตัวอย่างของรูปแบบคำอธิบายแนวคิดแบบเรียกซ้ำที่ฉันเพิ่งคิดค้น ;-)
namespaceform

3
@qed: thisคีย์เวิร์ดเป็นทางเลือกเว้นแต่จะมีข้อขัดแย้งกับบางสิ่งที่มีขอบเขตเฉพาะเจาะจงมากขึ้น ในตัวอย่างที่คุณให้ setter ที่สร้างขึ้นจะมีพารามิเตอร์เดียวที่มีชื่อตรงกับชื่อฟิลด์ดังนั้นจึงthis.fieldName = fieldNameถูกใช้เพื่อแยกแยะว่าฟิลด์ถูกกำหนดให้แทนที่จะเป็นพารามิเตอร์ที่กำหนดให้กับตัวเองตามที่fieldName = fieldnameจะบรรลุ ไม่มีความขัดแย้งดังกล่าวเกิดขึ้นใน getter
Paul Creasey

39

ใน Java getters และ setters เป็นฟังก์ชันธรรมดาโดยสิ้นเชิง สิ่งเดียวที่ทำให้พวกเขาได้รับหรือ setters คือการประชุม getter for foo เรียกว่า getFoo และ setter เรียกว่า setFoo ในกรณีของบูลีน getter เรียกว่า isFoo นอกจากนี้ยังต้องมีการประกาศเฉพาะดังที่แสดงในตัวอย่างของ getter และ setter สำหรับ 'name':

class Dummy
{
    private String name;

    public Dummy() {}

    public Dummy(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

เหตุผลในการใช้ getters และ setters แทนที่จะทำให้สมาชิกของคุณเป็นแบบสาธารณะก็คือทำให้สามารถเปลี่ยนการใช้งานได้โดยไม่ต้องเปลี่ยนอินเทอร์เฟซ นอกจากนี้เครื่องมือและชุดเครื่องมือจำนวนมากที่ใช้การสะท้อนเพื่อตรวจสอบวัตถุยอมรับเฉพาะวัตถุที่มีตัวรับและตัวตั้งค่าเท่านั้น ตัวอย่างเช่นJavaBeansต้องมี getters และ setters รวมถึงข้อกำหนดอื่น ๆ


9
ผู้ก่อสร้างเหล่านั้นไม่ควรมี 'โมฆะ' หรือ?
Jason Hartley

ความว่างเปล่ามีความจำเป็นที่นี่ หากคุณไม่มีคุณจะได้รับ:error: invalid method declaration; return type required
แดน

3
ไม่จำเป็นต้องใช้โมฆะที่นี่
Shashi Kiran

2
@JasonHartley: ตัวสร้างไม่มีประเภทส่งคืน
wassimans

@Mark Byers ดังนั้นคอนสตรัคเตอร์จึงใช้สำหรับการเริ่มต้นอินสแตนซ์และ setter จะใช้เพื่อเปลี่ยนแอ็ตทริบิวต์ที่กำหนด ถูกต้องหรือไม่
carloswm85

12
class Clock {  
        String time;  

        void setTime (String t) {  
           time = t;  
        }  

        String getTime() {  
           return time;  
        }  
}  


class ClockTestDrive {  
   public static void main (String [] args) {  
   Clock c = new Clock;  

   c.setTime("12345")  
   String tod = c.getTime();  
   System.out.println(time: " + tod);  
 }
}  

เมื่อคุณเรียกใช้โปรแกรมโปรแกรมจะเริ่มต้นในแหล่งจ่ายไฟหลัก

  1. สร้างวัตถุ c
  2. ฟังก์ชันsetTime()ถูกเรียกโดยอ็อบเจ็กต์ c
  3. ตัวแปรtimeถูกตั้งค่าเป็นค่าที่ส่งผ่าน
  4. ฟังก์ชันgetTime()ถูกเรียกโดยอ็อบเจ็กต์ c
  5. เวลาจะถูกส่งกลับ
  6. มันจะผ่านไปtodและtodพิมพ์ออกมา

10

คุณอาจต้องการอ่าน " ทำไมวิธี getter และ setter จึงชั่วร้าย ":

แม้ว่าเมธอด getter / setter จะเป็นสิ่งที่พบเห็นได้ทั่วไปใน Java แต่ก็ไม่ได้เป็นแบบเชิงวัตถุ (OO) โดยเฉพาะ ในความเป็นจริงมันสามารถทำลายความสามารถในการบำรุงรักษาของโค้ดของคุณ ยิ่งไปกว่านั้นการปรากฏตัวของวิธี getter และ setter จำนวนมากเป็นธงสีแดงที่โปรแกรมไม่จำเป็นต้องได้รับการออกแบบมาอย่างดีจากมุมมองของ OO

บทความนี้อธิบายว่าเหตุใดคุณจึงไม่ควรใช้ getter และ setter (และเมื่อใดที่คุณสามารถใช้ได้) และแนะนำวิธีการออกแบบที่จะช่วยให้คุณหลุดพ้นจากความคิดของ getter / setter


3

1. getters / setters ที่ดีที่สุดฉลาด

นี่คือตัวอย่างจาวาสคริปต์จาก mozilla:

var o = { a:0 } // `o` is now a basic object

Object.defineProperty(o, "b", { 
    get: function () { 
        return this.a + 1; 
    } 
});

console.log(o.b) // Runs the getter, which yields a + 1 (which is 1)

ผมเคยใช้เหล่านี้มากเพราะพวกเขาจะน่ากลัว ฉันจะใช้มันเมื่อได้รับจินตนาการด้วยการเข้ารหัส + แอนิเมชั่นของฉัน ตัวอย่างเช่นสร้างตัวตั้งค่าที่เกี่ยวข้องกับNumberหมายเลขที่แสดงบนหน้าเว็บของคุณ เมื่อหมาจะใช้มันเคลื่อนไหวหมายเลขเดิมไปยังหมายเลขใหม่โดยใช้ทวีเนอร์ ถ้าตัวเลขเริ่มต้นคือ 0 และคุณตั้งค่าเป็น 10 คุณจะเห็นตัวเลขพลิกจาก 0 ถึง 10 อย่างรวดเร็วสมมติว่าครึ่งวินาที ผู้ใช้ชื่นชอบสิ่งนี้และสนุกที่จะสร้าง

2. Getters / setters ใน php

ตัวอย่างจาก soft

<?php
class MyClass {
  private $firstField;
  private $secondField;

  public function __get($property) {
    if (property_exists($this, $property)) {
      return $this->$property;
    }
  }

  public function __set($property, $value) {
    if (property_exists($this, $property)) {
      $this->$property = $value;
    }

    return $this;
  }
}
?>

การอ้างอิง:


2

นี่คือตัวอย่างเพื่ออธิบายวิธีที่ง่ายที่สุดในการใช้ getter และ setter ใน java เราสามารถทำได้อย่างตรงไปตรงมามากขึ้น แต่ getter และ setter มีบางอย่างที่พิเศษคือเมื่อใช้ private member ของ parent class ในคลาสย่อยในการสืบทอด คุณสามารถทำให้เป็นไปได้โดยใช้ getter และ setter

package stackoverflow;

    public class StackoverFlow 

    {

        private int x;

        public int getX()
        {
            return x;
        }

        public int setX(int x)
        {
          return  this.x = x;
        }
         public void showX()
         {
             System.out.println("value of x  "+x);
         }


        public static void main(String[] args) {

            StackoverFlow sto = new StackoverFlow();
            sto.setX(10);
            sto.getX();
            sto.showX();
        }

    }

ฉันจะไม่ลงคะแนนให้คุณ (ไม่คุ้มกับความพยายาม) โปรดทราบว่า (1) คุณได้ตอบคำถามเกี่ยวกับJavaซึ่งภาษาโปรแกรมควรอยู่ใน Java (2) หากคุณต้องการโพสต์ตรวจสอบให้แน่ใจว่าเค้าโครงนั้นถูกต้อง (3) การใช้การห่อหุ้ม (getter (หรือ accessor) และ setters (หรือ mutators)) ของคุณไม่ถูกต้อง โปรดค้นหาความหมายของการห่อหุ้ม ... (ตรวจสอบคำตอบที่ได้รับการโหวต)
KarelG

1
@KarelG ขอโทษที่ฉันไม่ได้อ่านแท็ก ฉันอัปเดตเป็น java ขอบคุณที่ทำให้ฉันเข้าใจ
Bashir ahmad
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.