เหตุใดเราจึงไม่ควรใช้การป้องกันแบบคงที่ใน java


122

ฉันกำลังเจอคำถามนี้มีวิธีลบล้างตัวแปรคลาสใน Java หรือไม่? ความคิดเห็นแรกที่มี 36 upvotes คือ:

ถ้าคุณเคยเห็นให้protected staticเรียกใช้

ใครสามารถอธิบายได้ว่าทำไมprotected staticขมวดคิ้ว?


6
finalมีอะไรผิดปกติกับข้อมูลแบบคงที่ได้รับการคุ้มครองตราบใดที่มันเป็น เขตข้อมูลคงที่ที่ไม่เปลี่ยนแปลงที่ใช้ร่วมกันระหว่างชั้นเรียนเป็นสาเหตุของความกังวลอย่างแน่นอน หลายคลาสที่อัปเดตฟิลด์แบบคงที่ไม่น่าจะเชื่อถือได้หรือง่ายต่อการติดตามโดยเฉพาะอย่างยิ่งเนื่องจากการมีฟิลด์หรือวิธีการป้องกันใด ๆ บ่งบอกว่าคลาสนั้นมีจุดมุ่งหมายเพื่อขยายคลาสโดยคลาสในแพ็กเกจอื่นอาจเป็นคลาสที่ไม่อยู่ภายใต้การควบคุมของ ผู้เขียนชั้นเรียนที่มีเขตข้อมูลที่มีการป้องกัน
VGR

6
@VGR finalไม่ได้หมายความว่าฟิลด์นั้นไม่เปลี่ยนรูป คุณสามารถแก้ไขการobjectอ้างอิงโดยfinalตัวแปรอ้างอิงได้ตลอดเวลา
Zeeshan

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

@LoneRider คุณพูดถูก ฉันคิดว่าไม่เปลี่ยนรูปและสุดท้ายก็ไม่รับประกันอย่างนั้น
VGR

แม้แต่ฉันก็มาที่นี่ด้วยคำถามเดียวกัน
Raj Rajeshwar Singh Rathore

คำตอบ:


86

มันเป็นโวหารมากกว่าปัญหาโดยตรง มันแสดงให้เห็นว่าคุณคิดไม่ถูกว่าจะเกิดอะไรขึ้นกับชั้นเรียน

คิดถึงความstaticหมาย:

ตัวแปรนี้มีอยู่ในระดับชั้นมันไม่ได้อยู่แยกต่างหากสำหรับแต่ละอินสแตนซ์และก็ไม่ได้มีความเป็นอยู่ที่เป็นอิสระในการเรียนซึ่งขยายฉัน

คิดถึงความprotectedหมาย:

ตัวแปรนี้จะเห็นได้จากชั้นนี้ชั้นเรียนในแพคเกจเดียวกันและการเรียนซึ่งขยายฉัน

ทั้งสองความหมายไม่ได้เป็นเอกสิทธิ์เฉพาะของกันและกัน แต่ค่อนข้างใกล้เคียงกัน

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

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

หากต้องการดูตัวอย่างหนึ่งว่าสิ่งนี้สามารถทำลายสิ่งต่าง ๆ ได้อย่างไรและเพื่อแสดงให้เห็นว่าฉันหมายถึงอะไรโดยตัวแปรที่ไม่มีการดำรงอยู่อย่างอิสระให้ลองใช้โค้ดตัวอย่างนี้:

public class Program {
    public static void main (String[] args) throws java.lang.Exception {
        System.out.println(new Test2().getTest());
        Test.test = "changed";
        System.out.println(new Test2().getTest());
    }
}

abstract class Test {
    protected static String test = "test";
}

class Test2 extends Test {
    public String getTest() {
        return test;
    }
}

คุณจะเห็นผลลัพธ์:

test
changed

ลองเองได้ที่: https://ideone.com/KM8u8O

ชั้นTest2สามารถเข้าถึงสมาชิกคงtestจากTestโดยไม่จำเป็นต้องมีคุณสมบัติชื่อ - แต่ก็ไม่ได้รับมรดกหรือได้รับสำเนาของตัวเอง มันกำลังมองไปที่วัตถุเดียวกันในหน่วยความจำ


4
พวกคุณติดมรดก กรณีทั่วไปที่เห็นคือมีคนต้องการเข้าถึงแพ็กเกจโดยไม่เปิดเผยต่อสาธารณะ (เช่นการทดสอบหน่วย)
spudone

3
@spudone แต่โดยทั่วไปการทดสอบหน่วยจะอยู่ในแพ็คเกจเดียวกัน เพื่อให้พวกเขาเข้าถึงคุณเพียงแค่ใช้ระดับการเข้าถึงเริ่มต้น (แพ็คเกจ) Protected ให้การเข้าถึงคลาสย่อยด้วยซึ่งไม่จำเป็นหรือเกี่ยวข้องกับการทดสอบหน่วย
Tim B

1
@Kamafeather Protected หมายความว่าเด็ก ๆ สามารถมองเห็นคุณจากชั้นเรียนต่างๆและชั้นเรียนใด ๆ ในแพ็คเกจเดียวกันก็สามารถเห็นคุณได้ ใช่โปรแกรมอยู่ในแพ็คเกจเดียวกันและด้วยเหตุนี้จึงสามารถเห็นสมาชิกที่ได้รับการป้องกัน
Tim B

2
" จากนั้นคลาสที่ขยายออกไปสามารถปรับเปลี่ยนพฤติกรรมได้ " ซึ่งจะเป็นการละเมิดหลักการของ Liskov Subsitution คลาสย่อยไม่ควรปรับเปลี่ยนพฤติกรรมของซุปเปอร์ไทป์ สิ่งนี้อยู่ภายใต้อาร์กิวเมนต์ "a square ไม่ใช่สี่เหลี่ยมผืนผ้า" ทั้งหมด: การปรับ superclass ( Rectangle) เพื่อปรับความกว้าง / ความสูงเพื่อให้แน่ใจว่าความเท่าเทียมกันจะ (for Square) จะให้ผลลัพธ์ที่ไม่ต้องการหากคุณต้องแทนที่ supertype ทุกรายการด้วยอินสแตนซ์ของประเภทย่อย
ไดออกซิน

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

32

มันขมวดคิ้วเพราะมันขัดแย้งกัน

ทำให้ตัวแปรprotectedหมายถึงมันจะถูกใช้ภายในแพคเกจหรือจะได้รับมรดกภายในประเภทรอง

ทำให้ตัวแปรstaticทำให้มันเป็นสมาชิกคนหนึ่งของชั้นเรียนการขจัดความตั้งใจที่จะรับมัน สิ่งนี้เหลือเพียงความตั้งใจที่จะใช้ภายในแพ็คเกจและเรามีpackage-privateไว้สำหรับสิ่งนั้น (ไม่มีตัวปรับแต่ง)

สถานการณ์เดียวที่ฉันพบว่ามีประโยชน์คือถ้าคุณประกาศคลาสที่ควรใช้เพื่อเปิดแอปพลิเคชัน (เช่น JavaFX Application#launchและต้องการเปิดใช้งานจากคลาสย่อยเท่านั้นหากทำเช่นนั้นโปรดตรวจสอบว่าเมธอดนั้นเป็นfinalไปด้วย ไม่อนุญาตให้ซ่อนแต่นี่ไม่ใช่ "บรรทัดฐาน" และอาจถูกนำไปใช้เพื่อป้องกันการเพิ่มความซับซ้อนโดยเพิ่มวิธีใหม่ในการเปิดแอปพลิเคชัน

หากต้องการดูระดับการเข้าถึงของตัวปรับแต่งแต่ละตัวโปรดดูสิ่งนี้: บทช่วยสอน Java - การควบคุมการเข้าถึงสมาชิกของคลาส


4
ฉันไม่เข้าใจว่าจะstaticกำจัดเจตนาในการสืบทอดมันได้อย่างไร เนื่องจากคลาสย่อยของฉันในแพ็กเกจอื่นยังคงต้องการฟิลด์ super protectedเพื่อเข้าถึงแม้ว่าจะเป็นstaticไฟล์. package-privateช่วยไม่ได้
Aobo Yang

@AoboYang protected staticคุณกำลังขวาซึ่งเป็นเหตุผลที่บางคนใช้ แต่เป็นกลิ่นรหัสดังนั้นส่วน " วิ่ง " ตัวปรับแต่งการเข้าถึงและการสืบทอดเป็นสองเรื่องที่แตกต่างกัน ใช่คุณจะไม่สามารถเข้าถึงสมาชิกแบบคงที่จากคลาสระดับสูงได้หากเป็นpackage-privateเช่นนั้น แต่คุณไม่ควรพึ่งพาการสืบทอดกับstaticฟิลด์อ้างอิงตั้งแต่แรก มันเป็นสัญญาณของการออกแบบที่ไม่ดี คุณจะสังเกตเห็นความพยายามในการลบล้างstaticวิธีการไม่ให้ผลลัพธ์ซึ่งเป็นสัญญาณที่ชัดเจนว่าการสืบทอดไม่ได้อิงตามคลาส หากคุณต้องการเข้าถึงนอกคลาสหรือแพ็กเกจควรเป็นpublic
ไดออกซิน

3
ในตอนแรกฉันมีคลาสที่มีprivate staticฟังก์ชัน util อยู่ แต่ฉันคิดว่าอาจมีคนต้องการปรับปรุงหรือปรับแต่งจากคลาสของฉันและฟังก์ชัน util เหล่านี้อาจให้ความสะดวกกับพวกเขาด้วย publicอาจไม่เหมาะสมเนื่องจากวิธีการใช้ไม่เหมาะสำหรับผู้ใช้อินสแตนซ์ของคลาสของฉัน คุณช่วยฉันหาการออกแบบที่ดีแทนได้protectedไหม ขอบคุณ
Aobo Yang

ในลิงก์นั้นระบุว่า 'ใช้ระดับการเข้าถึงที่ จำกัด ที่สุดที่เหมาะสมสำหรับสมาชิกบางคน ใช้ส่วนตัวเว้นแต่คุณจะมีเหตุผลที่ดีที่จะไม่ทำ ' ซึ่งขัดแย้งกับคำถามนี้มีความคิดอย่างไร?
Cecilia

13

ฉันไม่เห็นเหตุผลเฉพาะว่าทำไมถึงต้องขมวดคิ้ว อาจมีทางเลือกอื่นในการบรรลุพฤติกรรมเดียวกันได้เสมอและจะขึ้นอยู่กับสถาปัตยกรรมที่แท้จริงว่าทางเลือกเหล่านี้ "ดีกว่า" มากกว่าวิธีการคงที่ที่มีการป้องกันหรือไม่ แต่ตัวอย่างหนึ่งที่วิธีการป้องกันคงที่มีเหตุผลอย่างน้อยก็อาจเป็นดังต่อไปนี้:

(แก้ไขแยกเป็นแพ็กเกจแยกกันเพื่อให้การใช้งานprotectedชัดเจนขึ้น)

package a;
import java.util.List;

public abstract class BaseClass
{
    public Integer compute(List<Integer> list)
    {
        return computeDefaultA(list)+computeDefaultB(list);
    }

    protected static Integer computeDefaultA(List<Integer> list)
    {
        return 12;
    }
    protected static Integer computeDefaultB(List<Integer> list)
    {
        return 34;
    }
}

ได้มาจากสิ่งนั้น:

package a.b;

import java.util.List;

import a.BaseClass;

abstract class ExtendingClassA extends BaseClass
{
    @Override
    public Integer compute(List<Integer> list)
    {
        return computeDefaultA(list)+computeOwnB(list);
    }

    private static Integer computeOwnB(List<Integer> list)
    {
        return 56;
    }
}

คลาสอื่นที่ได้รับ:

package a.b;

import java.util.List;

import a.BaseClass;

abstract class ExtendingClassB extends BaseClass
{
    @Override
    public Integer compute(List<Integer> list)
    {
        return computeOwnA(list)+computeDefaultB(list);
    }

    private static Integer computeOwnA(List<Integer> list)
    {
        return 78;
    }
}

protected staticปรับแต่งได้อย่างแน่นอนจะมีความชอบธรรมที่นี่:

  • วิธีการอาจเป็นstaticเพราะไม่ขึ้นอยู่กับตัวแปรอินสแตนซ์ ไม่ได้มีวัตถุประสงค์เพื่อใช้เป็นวิธีการหลายรูปแบบโดยตรง แต่เป็นวิธี "ยูทิลิตี้" ที่นำเสนอการใช้งานเริ่มต้นซึ่งเป็นส่วนหนึ่งของการคำนวณที่ซับซ้อนมากขึ้นและทำหน้าที่เป็น "องค์ประกอบพื้นฐาน" ของการนำไปใช้จริง
  • วิธีการไม่ควรเป็นpublicเพราะเป็นรายละเอียดการนำไปใช้งาน และพวกเขาไม่สามารถเป็นได้privateเพราะพวกเขาควรถูกเรียกโดยคลาสขยาย นอกจากนี้ยังไม่มีการเปิดเผย "เริ่มต้น" เนื่องจากจะไม่สามารถเข้าถึงได้สำหรับชั้นเรียนที่ขยายในแพ็คเกจอื่น ๆ

(แก้ไข: เราสามารถสันนิษฐานได้ว่าความคิดเห็นเดิมอ้างถึงฟิลด์เท่านั้นไม่ใช่วิธีการ - อย่างไรก็ตามมันกว้างเกินไป)


ในกรณีนี้คุณควรกำหนดค่าเริ่มต้นการใช้งานที่เป็นprotected final(เนื่องจากคุณไม่ต้องการให้พวกเขาแทนที่) staticไม่ใช่ ความจริงที่ว่าเมธอดไม่ใช้ตัวแปรอินสแตนซ์ไม่ได้หมายความว่าควรจะเป็นstatic(แม้ว่าจะทำได้ )
barfuin

2
@ โทมัสแน่นอนในกรณีนี้ก็เป็นไปได้เช่นกัน โดยทั่วไป: สิ่งนี้เป็นอัตนัยบางส่วนอย่างแน่นอน แต่กฎทั่วไปของฉันคือ: เมื่อวิธีการไม่ได้มีไว้เพื่อใช้ในหลายรูปแบบและสามารถเป็นแบบคงที่ได้ฉันจึงทำให้มันคงที่ ในทางตรงกันข้ามกับการสร้างมันfinalไม่เพียง แต่ทำให้ชัดเจนว่าเมธอดไม่ได้ตั้งใจที่จะถูกลบล้างเท่านั้น แต่ยังทำให้ผู้อ่านเข้าใจได้อย่างชัดเจนว่าเมธอดนั้นไม่ได้ใช้ตัวแปรอินสแตนซ์ รวบรัด: ไม่มีเหตุผลที่จะไม่ทำให้มันคงที่
Marco13

1
เมื่อวิธีการไม่ได้มีวัตถุประสงค์เพื่อใช้ในหลายรูปแบบและสามารถเป็นแบบคงที่ได้ฉันจึงทำให้มันคงที่ - สิ่งนี้จะทำให้คุณมีปัญหาเมื่อคุณเริ่มใช้กรอบการจำลองสำหรับการทดสอบหน่วย แต่สิ่งนี้ทำให้เราไปสู่หัวข้อที่แตกต่างออกไป ...
barfuin

@ Marco13 นอกจากนี้ยังมีกรณีที่คุณทำบางอย่างprotectedไม่ใช่เพื่อแสดงการสืบทอด แต่ให้เก็บไว้ในแพ็คเกจเดียว - ไม่เปิดเผย ฉันเดาว่าอินเทอร์เฟซที่ปิดสนิทจะมีประโยชน์ในลักษณะนี้เมื่อพวกเขาจะอยู่ใน java
Eugene

@ ยูจีนความคิดเห็นนั้นทำให้ฉันหงุดหงิดเล็กน้อย การมองเห็นแพ็กเกจสามารถทำได้โดยไม่ต้องมีตัวปรับแต่งใด ๆ ในขณะที่protected"การสืบทอดคลาส (แม้จะอยู่คนละแพ็กเกจก็ตาม)" ...
โค 13

7

สมาชิกแบบคงที่จะไม่ได้รับการสืบทอดและสมาชิกที่ได้รับการป้องกันจะมองเห็นได้เฉพาะในคลาสย่อยเท่านั้น (และแน่นอนว่าเป็นคลาสที่มี) ดังนั้น a จึงprotected staticมีการมองเห็นเช่นเดียวกับที่staticบ่งบอกถึงความเข้าใจผิดโดยผู้เข้ารหัส


1
คุณช่วยระบุแหล่งที่มาสำหรับคำชี้แจงแรกของคุณได้ไหม ในการทดสอบอย่างรวดเร็ว int คงที่ที่ได้รับการป้องกันจะถูกสืบทอดและนำกลับมาใช้ในคลาสย่อยโดยไม่มีปัญหา
hiergiltdiestfu

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

2
อืม ... ไม่นะ แพ็กเกจส่วนตัวและprotectedไม่เหมือนกัน หากคุณเพียงแค่พูดว่าstaticฟิลด์จะมองเห็นได้เฉพาะคลาสย่อยในแพ็กเกจเดียวกัน
Aaron Digulla

1
@AaronDigulla protected staticช่วยให้การเข้าถึงภายในแพคเกจหรือจากประเภทรอง การสร้างตัวแปรคงที่จะลบความตั้งใจของคลาสย่อยออกไปโดยเหลือเพียงความตั้งใจเดียวเท่านั้นที่สามารถเข้าถึงได้จากภายในแพ็กเกจ
ไดออกซิน

@VinceEmigh: ขอโทษนะฉันกำลังคุยกับโบฮีเมียน ควรทำให้ชัดเจนมากขึ้น
Aaron Digulla

5

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

โดยทั่วไปบางคนหลีกเลี่ยงที่จะใช้protectedด้วยเหตุผลหลายประการและบางคนคิดว่าstaticควรหลีกเลี่ยงตัวแปรที่ไม่ใช่ตัวแปรสุดท้าย(โดยส่วนตัวแล้วฉันก็เห็นอกเห็นใจคนหลังในระดับหนึ่ง) ดังนั้นฉันเดาว่าการรวมกันของprotectedและstaticต้องดูไม่ดี ^ 2สำหรับผู้ที่ อยู่ในทั้งสองกลุ่ม


3

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


1

อย่างที่คนส่วนใหญ่ตอบ:

  • protectedหมายถึง - ' package-private + visibility to subclasses - คุณสมบัติ / พฤติกรรมถูกส่งมา'
  • staticหมายถึง - ' ตรงกันข้ามกับอินสแตนซ์ - เป็นคุณสมบัติ / พฤติกรรมของคลาสกล่าวคือไม่ได้รับผลกระทบ '

ดังนั้นจึงมีความขัดแย้งและเข้ากันไม่ได้เล็กน้อย

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

package X;
public abstract class AbstractType {
    protected Object field1;
    protected Object field2;
    ...
    protected Object fieldN;

    protected static abstract class BaseBuilder<T extends BaseBuilder<T>> {
        private Object field1; // = some default value here
        private Object field2; // = some default value here
        ...
        private Object fieldN; // = some default value here

        public T field1(Object value) { this.field1 = value; return self();}
        public T field2(Object value) { this.field2 = value; return self();}
        ...
        public T fieldN(Object value) { this.fieldN = value; return self();}
        protected abstract T self(); // should always return this;
        public abstract AbstractType build();
    }

    private AbstractType(BaseBuilder<?> b) {
        this.field1 = b.field1;
        this.field2 = b.field2;
        ...
        this.fieldN = b.fieldN;
    }
}

แล้วทำไมprotected static? เนื่องจากฉันต้องการประเภทย่อยที่ไม่ใช่นามธรรมAbstactTypeซึ่งใช้ Builder ที่ไม่ใช่นามธรรมของตัวเองและอยู่ภายนอกpackage Xเพื่อให้สามารถเข้าถึงและนำไฟล์BaseBuilder.

package Y;
public MyType1 extends AbstractType {
    private Object filedN1;

    public static class Builder extends AbstractType.BaseBuilder<Builder> {
        private Object fieldN1; // = some default value here

        public Builder fieldN1(Object value) { this.fieldN1 = value; return self();}
        @Override protected Builder self() { return this; }
        @Override public MyType build() { return new MyType(this); }
    }

    private MyType(Builder b) {
        super(b);
        this.fieldN1 = b.fieldN1;
    }
}

แน่นอนว่าเราสามารถBaseBuilderเปิดเผยต่อสาธารณะได้ แต่แล้วเราก็พบกับคำแถลงที่ขัดแย้งกัน:

  • เรามีคลาสที่ไม่สามารถสร้างได้ทันที (นามธรรม)
  • เราจัดหาผู้สร้างสาธารณะสำหรับมัน

ดังนั้นในทั้งสองกรณีprotected staticและpublicผู้สร้างabstract classเราจึงรวมคำแถลงที่ขัดแย้งกัน มันเป็นเรื่องของความชอบส่วนบุคคล

อย่างไรก็ตามฉันยังคงชอบpublicผู้สร้างมากกว่าabstract classเพราะprotected staticสำหรับฉันแล้วรู้สึกไม่เป็นธรรมชาติในโลกของ OOD และ OOP!


0

protected staticมีอะไรผิดปกติขึ้นอยู่กับการมี สิ่งหนึ่งที่ผู้คนจำนวนมากมองข้ามไปคือคุณอาจต้องการเขียนกรณีทดสอบสำหรับวิธีการคงที่ซึ่งคุณไม่ต้องการเปิดเผยภายใต้สถานการณ์ปกติ ฉันสังเกตว่าสิ่งนี้มีประโยชน์อย่างยิ่งสำหรับการทดสอบการเขียนสำหรับวิธีการคงที่ในคลาสยูทิลิตี้

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