আমাদের জাভাতে সুরক্ষিত স্ট্যাটিক কেন ব্যবহার করা উচিত নয়


122

আমি এই প্রশ্নটি দিয়ে যাচ্ছিলাম জাভাতে ক্লাস ভেরিয়েবলগুলি ওভাররাইড করার কোনও উপায় আছে কি? 36 টি আপভোটের সাথে প্রথম মন্তব্যটি ছিল:

যদি আপনি কখনও একটি দেখতে পান protected static, চালান।

কেউ কি ব্যাখ্যা করতে পারেন যে কেন একটি protected staticঅলঙ্কৃত করা হয়?


6
কোনও সুরক্ষিত স্ট্যাটিক ক্ষেত্রের যতক্ষণ তা নেই তেমন কোনও সমস্যা নেই final। ক্লাসে ভাগ করা একটি পরিবর্তনীয় স্থির ক্ষেত্র অবশ্যই উদ্বেগের কারণ। স্ট্যাটিক ক্ষেত্র আপডেট করে একাধিক ক্লাসগুলি নির্ভরযোগ্য বা অনুসরণ করা সহজ নয়, বিশেষত যেহেতু কোনও সুরক্ষিত ক্ষেত্র বা পদ্ধতির উপস্থিতি থেকেই বোঝা যায় যে ক্লাসটি অন্যান্য প্যাকেজগুলির ক্লাস দ্বারা প্রসারিত হতে পারে, সম্ভবত ক্লাসগুলি এর নিয়ন্ত্রণাধীন নয় সুরক্ষিত ক্ষেত্র সমেত শ্রেণীর লেখক।
ভিজিআর

6
@ ভিজিআর, এর finalঅর্থ ক্ষেত্রটি অপরিবর্তনীয়। আপনি সর্বদা রেফারেন্স ভেরিয়েবল objectদ্বারা রেফারেন্সটি সংশোধন করতে পারেন final
জিশান

@VGR- এর সাথে আমি একমত নই আপনি কেবল স্থিতিশীল পরিবর্তনশীল তৈরির কারণ হ'ল কেবল পীড়িত হয়ে অন্য প্যাকেজের মধ্যে থেকে অ্যাক্সেস পাওয়া এবং একক ক্ষেত্রে অ্যাক্সেস উত্তরাধিকারের কারণ হওয়া উচিত নয়। এটি একটি ত্রুটিযুক্ত নকশা, আইএমও এবং আপনি যদি এটি অবলম্বন করেন তবে আপনার অ্যাপ্লিকেশনটির কাঠামোটি পুনর্বিবেচনা করা উচিত। যদিও এটি আমার মতামত।
ডায়াক্সিন

@ লোনরাইডার আপনি ঠিক বলেছেন আমি অপরিবর্তনীয় চিন্তা করছিলাম, এবং চূড়ান্ত অবশ্যই এর নিশ্চয়তা দেয় না।
ভিজিআর

এমনকি আমি এখানে একই প্রশ্ন থেকে এসেছি।
রাজ রাজেশ্বর সিং রাঠোর

উত্তর:


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
তোমরা ছেলেরা উত্তরাধিকারসূত্রে ঝুলবে। সাধারণ ক্ষেত্রে যেখানে এটি দেখা যায় তা হ'ল কেউ এটিকে সর্বজনীন না করে প্যাকেজ অ্যাক্সেস চান (যেমন ইউনিট পরীক্ষা)।
স্পুডোন

3
@ স্পডোন কিন্তু ইউনিট পরীক্ষাগুলি সাধারণত একই প্যাকেজে রাখা হয়। তাদের অ্যাক্সেস দেওয়ার জন্য আপনি কেবল ডিফল্ট (প্যাকেজ) অ্যাক্সেস স্তর ব্যবহার করেন। সুরক্ষিত সাবক্লাসগুলিতেও অ্যাক্সেস দেয় যা ইউনিট পরীক্ষার জন্য প্রয়োজনীয় বা প্রাসঙ্গিক নয়।
টিম বি

1
@ কামাফেদার সুরক্ষিত মানে শিশুরা আপনাকে বিভিন্ন ক্লাস থেকে দেখতে পারে এবং একই প্যাকেজের যে কোনও ক্লাস আপনাকে দেখতে পাবে। হ্যাঁ প্রোগ্রাম একই প্যাকেজে রয়েছে এবং সেইজন্য সুরক্ষিত সদস্যটিকে দেখতে পাবেন।
টিম বি

2
" প্রসারিত শ্রেণি তারপরে আচরণটি সংশোধন করতে পারে " এটি লিসকোভ সাবস্ক্রিপশন নীতি লঙ্ঘন করবে। একটি সাবক্লাসের এটির সুপার টাইপের আচরণটি পরিবর্তন করা উচিত নয়। এটি পুরো "একটি বর্গক্ষেত্র একটি আয়তক্ষেত্র নয়" যুক্তির আওতায় পড়ে: Rectangleসমতা নিশ্চিত করার জন্য প্রস্থ / উচ্চতা সামঞ্জস্য করতে সুপারক্লাস ( ) সামঞ্জস্য করা (কারণ Square) আপনি যদি প্রতিটি সুপার টাইপের উপ-টাইপের উদাহরণ দিয়ে প্রতিস্থাপন করেন তবে অনাকাঙ্ক্ষিত ফলাফল আনবে।
ডায়াক্সিন

1
" কেবলমাত্র আমি দেখতে পাচ্ছি যে আপনি দুজনকে কোথায় একসাথে ব্যবহার করতে পারেন তা হ'ল যদি আপনার কোনও বিমূর্ত শ্রেণি প্রসারিত করার জন্য ডিজাইন করা হয়েছিল এবং প্রসারিত শ্রেণি তখন মূলটিতে সংজ্ঞায়িত ধ্রুবক ব্যবহার করে আচরণটি সংশোধন করতে পারে " তবে কিছুটা লুকানো থাকলেও এটি এতে রয়েছে আছে। কোড উদাহরণটি বিবৃতিও প্রকাশ করে
ডায়োক্সিন

32

এটি বিপরীতমুখী কারণ এটিকে নষ্ট করে দেওয়া।

পরিবর্তনশীল তৈরি করার protectedঅর্থ এটি প্যাকেজের মধ্যে ব্যবহার করা হবে বা এটি একটি সাবক্লাসের মধ্যে উত্তরাধিকার সূত্রে প্রাপ্ত হবে ।

পরিবর্তনশীল করা staticএটিকে বর্গের সদস্য হিসাবে তৈরি করে, উত্তরাধিকার সূত্রে উত্তীর্ণ হওয়ার উদ্দেশ্যগুলি সরিয়ে দেয় । এই পাতার শুধুমাত্র ব্যবহার করা হচ্ছে যার উদ্দেশ্য একটি প্যাকেজ মধ্যে , এবং আমরা আছে package-privateযে জন্য (কোন পরিবর্তক)।

শুধুমাত্র অবস্থা আমি এই দরকারী খুঁজে পাইনি যদি আপনি কোন ক্লাসে যে অ্যাপ্লিকেশন (JavaFX মত আরম্ভ করার জন্য ব্যবহার করা উচিত প্রকাশক হয়েছে Application#launch, এবং শুধুমাত্র একটি উপশ্রেণী থেকে লঞ্চ করতে সক্ষম হতে চেয়েছিলেন। যদি তাই হয় করছেন, নিশ্চিত পদ্ধতি এছাড়াও finalথেকে আড়াল করা অস্বীকার করুন । তবে এটি "আদর্শ" নয়, এবং সম্ভবত অ্যাপ্লিকেশনগুলি চালু করার নতুন উপায় যুক্ত করে আরও জটিলতা রোধ করার জন্য প্রয়োগ করা হয়েছিল।

প্রতিটি সংশোধকের অ্যাক্সেসের স্তরগুলি দেখতে এটি দেখুন: জাভা টিউটোরিয়ালস - কোনও শ্রেণীর সদস্যদের অ্যাক্সেস নিয়ন্ত্রণ করা


4
আমি বুঝতে পারি না যে staticএটি উত্তরাধিকারী হওয়ার উদ্দেশ্যগুলি কীভাবে মুছে ফেলবে । কারণ অন্য একটি প্যাকেজে আমার সাবক্লাসের এখনও protectedঅ্যাক্সেস করার জন্য সুপার ফিল্ডটি প্রয়োজন , যদিও তা staticpackage-privateসাহায্য করতে পারে না
আওবো ইয়াং

@ আবো ইয়্যাং আপনি ঠিক বলেছেন, এজন্য কিছু লোক ব্যবহার করে protected static। তবে এটি একটি কোড গন্ধ, সুতরাং " রান " অংশ। অ্যাক্সেস মডিফায়ার এবং উত্তরাধিকার দুটি পৃথক বিষয়। হ্যাঁ, আপনি যদি একটি সুপার ক্লাস থেকে স্থিতিশীল সদস্য হয়ে থাকেন তবে এটি অ্যাক্সেস করতে পারবেন না package-private। তবে আপনার staticপ্রথমে রেফারেন্স ক্ষেত্রগুলির উত্তরাধিকারের উপর নির্ভর করা উচিত নয় ; এটি দুর্বল ডিজাইনের লক্ষণ। আপনি লক্ষ্য করবেন যে ওভাররাইড staticপদ্ধতিতে প্রচেষ্টাগুলি কোনও ফল দেয় না, এটি একটি স্পষ্ট লক্ষণ যে উত্তরাধিকার শ্রেণিভিত্তিক নয়। আপনার যদি শ্রেণি বা প্যাকেজের বাইরে অ্যাক্সেসের প্রয়োজন হয় তবে তা হওয়া উচিতpublic
ডায়াক্সিন

3
আমার private staticপ্রথমে কিছু ব্যবহারকারীর ফাংশন সহ একটি ক্লাস রয়েছে তবে আমি মনে করি যে কেউ আমার ক্লাস থেকে উন্নতি করতে বা কাস্টমাইজ করতে চাইতে পারে এবং এই ব্যবহারের ক্রিয়াকলাপগুলি তাদের সুবিধাদিও করতে পারে। publicব্যবহারের পদ্ধতিগুলি আমার শ্রেণীর উদাহরণগুলির ব্যবহারকারীর জন্য নয় বলে উপযুক্ত হতে পারে। আপনি কি আমাকে পরিবর্তে একটি ভাল নকশা আঁকা সাহায্য করতে পারেন protected? ধন্যবাদ
আবো ইয়াং

এই লিঙ্কটিতে, এটি বলেছে 'সর্বাধিক সীমাবদ্ধ অ্যাক্সেস স্তরটি ব্যবহার করুন যা কোনও নির্দিষ্ট সদস্যের জন্য উপলব্ধি করে। আপনার কাছে না দেওয়ার উপযুক্ত কারণ না থাকলে প্রাইভেট ব্যবহার করুন '' , যা এই প্রশ্ন থেকে কোন মতবিরোধী?
সিসিলিয়া

13

কেন এটিকে ঘৃণা করা উচিত তার কোনও বিশেষ কারণ আমি দেখছি না। একই আচরণ অর্জনের জন্য সর্বদা বিকল্প থাকতে পারে এবং এই বিকল্পগুলি সুরক্ষিত স্ট্যাটিক পদ্ধতির চেয়ে "আরও ভাল" কিনা তা নির্ভর করে ach তবে একটি উদাহরণ যেখানে সুরক্ষিত স্ট্যাটিক পদ্ধতিটি যুক্তিসঙ্গত হবে, কমপক্ষে, নিম্নলিখিতগুলি হতে পারে:

( 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(যদিও তা পারে )।
বারফুইন

2
@ থমাস শিওর, এক্ষেত্রে এটিও সম্ভব হবে। সাধারণভাবে: এটি অবশ্যই আংশিকভাবে বিষয়গত, তবে আমার থাম্বের নিয়মটি হল: যখন কোনও পদ্ধতি বহুত্বপূর্ণভাবে ব্যবহার করার উদ্দেশ্যে নয় এবং এটি স্থির হতে পারে, তখন আমি এটিকে স্থির করে তুলি। এটি তৈরি বিপরীতে final, এটা না শুধুমাত্র পরিষ্কার যে পদ্ধতি ওভাররাইড করা যেতে উদ্দেশ্যে না হয় করা, এটা অতিরিক্ত পাঠক যে পদ্ধতি উদাহরণস্বরূপ ভেরিয়েবল ব্যবহার করে না এমন স্পষ্ট করে তোলে। সুতরাং সংক্ষিপ্তভাবে: এটিকে স্থির না করার কোনও কারণ নেই ।
মার্কো 13

1
যখন কোনও পদ্ধতি বহুপদীভাবে ব্যবহারের উদ্দেশ্যে নয় এবং এটি স্থির হতে পারে, তখন আমি এটিকে স্থির করে তুলি। - আপনি ইউনিট পরীক্ষার জন্য মক ফ্রেমওয়ার্ক ব্যবহার শুরু করলে এটি আপনাকে সমস্যার মধ্যে ফেলবে। তবে এটি আমাদেরকে একটি অন্য বিষয়ের দিকে নিয়ে যায় ...
বারফুইন

@ মার্কো 13 এরও আছে যখন আপনি কিছু বানাবেন protected, উত্তরাধিকার দেখাবে না, তবে এটি একটি একক প্যাকেজের আওতায় রাখবেন - প্রকাশিত হবে না। আমার ধারণা, সিল করা ইন্টারফেসগুলি যখন জাভাতে যাবে তখন এই পদ্ধতিতে সহায়ক হয়ে উঠবে
ইউজিন

@ ইউজিন এই মন্তব্য আমাকে কিছুটা বিরক্ত করে। প্যাকেজ-দৃশ্যমানতা কোনও সংশোধক ছাড়াই অর্জন করা যায়, protectedযার অর্থ "উত্তরাধিকারী শ্রেণি (এমনকি বিভিন্ন প্যাকেজগুলিতেও)" ...
মার্কো 13

7

স্থিতিশীল সদস্যদের উত্তরাধিকার সূত্রে প্রাপ্ত হয় না এবং সুরক্ষিত সদস্যরা কেবলমাত্র সাবক্লাসে দৃশ্যমান (এবং অবশ্যই এটি সমেত শ্রেণিটি), সুতরাং কোডারের দ্বারা ভুল বোঝাবুঝির পরামর্শ দেয় এমন একটির protected staticএকই দৃশ্যমানতা রয়েছে static


1
আপনি দয়া করে আপনার প্রথম বিবৃতি জন্য একটি উত্স প্রদান করতে পারেন? দ্রুত পরীক্ষায়, একটি সুরক্ষিত স্ট্যাটিক ইন্ট উত্তরাধিকার সূত্রে প্রাপ্ত হয়েছিল এবং কোনও সমস্যা ছাড়াই একটি সাবক্লাসে পুনরায় ব্যবহার করা হয়েছিল।
hiergiltdiestfu

সুরক্ষিত স্ট্যাটিকের প্যাকেজ-প্রাইভেট স্ট্যাটিকের মতো একই দৃশ্যমানতা রয়েছে, ব্যক্তিগত স্ট্যাটিক নয়। এটি যুক্ত করার জন্য, আপনি সুরক্ষিত এবং স্থিতিশীল ব্যবহার করছেন, এটি প্যাকেজ-ব্যক্তিগত করার জন্য কেবল অ্যাক্সেস পরিবর্তনকারীকে সরিয়ে ফেলা ভাল (যদি আপনার উদ্দেশ্যগুলি প্যাকেজের মধ্যে এটি অ্যাক্সেসযোগ্য করে তোলা হত)
ডায়োক্সিন

2
আহ ... না। ব্যক্তিগত প্যাকেজ এবং protectedএকই নয়। যদি আপনি কেবল বলেন static, ক্ষেত্রটি একই প্যাকেজে কেবল সাবক্লাসে দৃশ্যমান।
অ্যারন ডিজুল্লা

1
@ অ্যারনডিগুল্লা প্যাকেজের মধ্যে বা একটি সাবক্লাস থেকেprotected static অ্যাক্সেসের অনুমতি দেয় । একটি পরিবর্তনশীল স্থিতিশীল করা সাবক্লাসিংয়ের উদ্দেশ্যগুলি সরিয়ে দেয়, প্যাকেজের মধ্যে থেকে কেবলমাত্র উদ্দেশ্য অ্যাক্সেস হয়ে যায়।
ডায়াক্সিন

@ ভিনসেমিঃ: দুঃখিত, আমি বোহেমিয়ার সাথে কথা বলছিলাম। এটি আরও পরিষ্কার করা উচিত ছিল।
অ্যারন দিগুলা

5

আসলে এখানে মূলত ভুল কিছু নেই protected static। আপনি যদি সত্যই কোনও স্থিতিশীল পরিবর্তনশীল বা পদ্ধতি চান যা প্যাকেজ এবং ঘোষক শ্রেণীর সমস্ত সাবক্লাসের জন্য দৃশ্যমান হয় তবে এগিয়ে যান এবং এটি তৈরি করুন protected static

কিছু মানুষ সাধারণত ব্যবহার করতে এড়াতে protectedবিভিন্ন কারণের জন্য এবং কিছু লোক মনে অ চূড়ান্ত staticভেরিয়েবল (আমি ব্যক্তিগতভাবে কিছু মাত্রায় আধুনিক দুঃখে) সব উপায়ে এড়িয়ে চলা উচিত, তাই আমি সমন্বয় অনুমান protectedএবং staticচেহারা আবশ্যক খারাপ ^ 2 ঐ যে উভয় গ্রুপের অন্তর্গত।


3

সুরক্ষিত এমনটি ব্যবহার করা হয় যাতে এটি সাবক্লাসে ব্যবহার করা যায়। কংক্রিটের ক্লাসগুলির প্রসঙ্গে আপনি যখন একই ভেরিয়েবলটি অ্যাক্সেস করতে পারেন তখন কোনও সুরক্ষিত স্ট্যাটিক সংজ্ঞায়িত করার কোনও যুক্তি নেই। যাহাতে কমপ্লায়ার একটি স্ট্যাটিক উপায়ে সুপার ক্লাসের স্ট্যাটিক ভেরিয়েবলটি অ্যাক্সেস করার জন্য একটি সতর্কতা দেবে।


1

বেশিরভাগ লোক যেমন উত্তর দিয়েছে:

  • protectedঅর্থ - ' প্যাকেজ-প্রাইভেট + সাবক্লাসে দৃশ্যমানতা - সম্পত্তি / আচরণ নিরীক্ষণ করা হয় '
  • 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যা এর নিজস্ব নন-অ্যাবস্ট্রাক্ট বিল্ডারকে প্রয়োগ করে এবং এটি 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আমার কাছে ওওডি ও ওওপি বিশ্বে আরও অপ্রাকৃত মনে হয়!


0

থাকার সাথে কোন দোষ নেই protected static। প্রচুর লোকেরা যে বিষয়টিকে অবহেলিত করছে তা হ'ল আপনি যে স্ট্যাটিক পদ্ধতির জন্য পরীক্ষার কেসগুলি লিখতে চান যা আপনি সাধারণ পরিস্থিতিতে প্রকাশ করতে চান না। আমি লক্ষ্য করেছি যে এটি ইউটিলিটি ক্লাসে স্থির পদ্ধতির জন্য পরীক্ষা লেখার জন্য বিশেষভাবে কার্যকর।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.