ব্যক্তিগত [এটি] বনাম প্রাইভেট


112

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

class Dummy {
    private var name = "default name"
}

class Dummy {
    private[this] var name = "default name"
}

দ্বিতীয়টি আরও কঠোর এবং আমি এটি পছন্দ করি তবে আমার কি সবসময় এটি ব্যবহার করা উচিত বা যদি আমার কোনও দৃ strong় কারণ থাকে?

সম্পাদনা: আমি দেখতে পাচ্ছি যে এখানে private[this] কিছু সাবসকেস এবং এর পরিবর্তে thisআমি অন্যান্য সংশোধকগুলি ব্যবহার করতে পারি: "প্যাকেজ, শ্রেণি বা সিঙ্গলটন অবজেক্ট"। তাই আমি এটি কিছু বিশেষ ক্ষেত্রে রেখে দেব।


উত্তর:


59

আমি মনে করি না যে এটি খুব বেশি গুরুত্বপূর্ণ, যেহেতু কোনও পরিবর্তন কেবল একটি শ্রেণিকেই স্পর্শ করবে। সুতরাং privateওভার protectedবেশি পছন্দ করার সবচেয়ে গুরুত্বপূর্ণ কারণটি publicপ্রযোজ্য নয়।

private[this]কর্মক্ষমতা সত্যিই গুরুত্বপূর্ণ যেখানে ব্যবহার করুন (যেহেতু আপনি এই পদ্ধতিগুলির পরিবর্তে সরাসরি ক্ষেত্র অ্যাক্সেস পাবেন)। অন্যথায়, কেবল একটি শৈলীতে স্থির হন যাতে লোকেরা এই সম্পত্তি কেন privateএবং সেটি কেন তা বোঝার দরকার নেই private[this]


6
@ ওম-নাম -মম আসলে, অনেক কিছুই বলার নেই। জেআইটি-তে privateযাইহোক উত্পন্ন অ্যাকসেসর পদ্ধতি কলগুলি ইনলাইন করা উচিত , সুতরাং প্রভাবটি শূন্য বা কমপক্ষে খুব কম হওয়া উচিত।
আলেক্সি রোমানভ

9
এই উত্তরটি বিভ্রান্তিমূলক, আসল কারণ হ'ল ঘোষণা-সাইটের ভিন্নতা (এই উত্তরটি দেখুন: stackoverflow.com/a/9727849/445715 )।
অ্যান্ড্রে ব্রেস্লাভ

1
@AndreyBreslav আমি অসম্মতি যে এই হল কারণ। হ্যাঁ, এই জাতীয় কেস বিদ্যমান আছে তবে উত্তর হিসাবে এটি বেশ বিরল।
আলেক্সি রোমানভ

3
হুম। নীচে মারেক আদামেকের উত্তরটি ব্যক্তিগতকে ব্যক্তিগত [এটি] ব্যক্তিগত পছন্দ করার আসল কারণ বলে মনে হচ্ছে। উদ্দেশ্যটি হ'ল শ্রেণীর সমস্ত দৃষ্টির বিপরীতে একটি নির্দিষ্ট উদাহরণে অ্যাক্সেস সীমাবদ্ধ করা।
রাম রাজামনি

3
@ অ্যালেক্সারোমানভ - প্রশ্নটি জিজ্ঞাসা করে "আমাকে কি সবসময় ডিফল্টরূপে এটি ব্যবহার করা উচিত?" আমি মনে করি আপনি একই ক্লাসের অন্য কোনও উদাহরণ থেকে যদি ক্ষেত্রের প্রয়োজন হয় তবে ব্যক্তিগত [এটি] ব্যবহার করা যাবে না বলে আপনি নিজের উত্তরটি উন্নত করতে পারেন।
রাম রাজমনি

130

এমন একটি মামলা রয়েছে যেখানে private[this]কোড সংকলন করা প্রয়োজন। এটি ভেরিয়েন্স স্বরলিপি এবং পরিবর্তনীয় ভেরিয়েবলগুলির একটি মিথস্ক্রিয়া সাথে করতে হবে। নিম্নলিখিত (অকেজো) শ্রেণি বিবেচনা করুন:

class Holder[+T] (initialValue: Option[T]) {
    // without [this] it will not compile
    private[this] var value = initialValue

    def getValue = value
    def makeEmpty { value = None }
}

সুতরাং এই শ্রেণিটি একটি alচ্ছিক মান ধরে রাখতে, একটি বিকল্প হিসাবে এটি ফিরিয়ে আনা এবং ব্যবহারকারীকে makeEmptyমানটি মুছে ফেলার জন্য কল করতে সক্ষম করে (যার ফলে ভেরিও)। যেমনটি বলা হয়েছে, এটি বিন্দুটি প্রদর্শন করা ব্যতীত।

আপনি যদি এই কোডটির privateপরিবর্তে এই কোডটি সংকলনের চেষ্টা private[this]করেন তবে নিম্নলিখিত ত্রুটি বার্তায় ব্যর্থ হবে:

ত্রুটি: সমবায়ু প্রকার টি মান মানের বিকল্প অপশন [টি] টাইপের বিপরীতে অবস্থিত হয় [শ্রেণিধারক [+ টি] (প্রারম্ভিক মূল্য: বিকল্প [টি]) {

এই ত্রুটিটি ঘটে কারণ মানটি কোভেরিয়েন্ট টাইপ টি (+ টি) এর পরিবর্তিত পরিবর্তনশীল যা সাধারণত এটির হিসাবে ব্যক্তিগত হিসাবে চিহ্নিত না হলে সমস্যা হয় private[this]। এই বিশেষ কেসটি পরিচালনা করতে এই সংকলকটির বৈকল্পিক পরীক্ষায় বিশেষ হ্যান্ডলিং রয়েছে।

সুতরাং এটি রহস্যজনক কিন্তু একটি কেস আছে যেখানে private[this]প্রয়োজন হয় private


1
আমি দেখতে পাচ্ছি যে মিশ্রনটি যখন মিশ্রণে থাকে তখন এটি কেন ব্যর্থ হয়, তবে কিছুই কেন পরিবর্তনযোগ্য নয় যখন আমি একই ত্রুটি পাব ?
ম্যাট ক্যান্টর

34

private var nameclass Dummy(এবং তার সহযোগী object Dummy) এর যে কোনও পদ্ধতি থেকে অ্যাক্সেসযোগ্য ।

private[this] var namethisকেবল অবজেক্টের পদ্ধতি থেকে অ্যাক্সেসযোগ্য , অন্য বস্তুর থেকে নয় class Dummy


18

ব্যক্তিগত [এটি] (সুরক্ষিত [এটি] সমতুল্য) এর অর্থ হ'ল "y" কেবল একই পরিস্থিতিতে পদ্ধতিতে দৃশ্যমান। উদাহরণস্বরূপ, আপনি দ্বিতীয় বারের মতো সমান পদ্ধতিতে y উল্লেখ করতে পারেন নি, অর্থাত্ "this.y == that.y" "that.y" তে একটি সংকলন ত্রুটি তৈরি করবে। (উৎস)

সুতরাং আপনি যতবার ইচ্ছা প্রাইভেট করতে পারেন [এটি] তবে আপনার যদি এটি উল্লেখ করার দরকার হয় তবে কিছু সমস্যা হতে পারে


13
private[this]সমান নয় protected[this]protected[this]সাবক্লাস উদাহরণগুলি সদস্যকে অ্যাক্সেস করতে দেয়।
ড্রেক্সিন

আপনি this.y == that.yব্যক্তিগত বা বেসরকারী উভয়ই ব্যবহার করতে পারেন [এটি], আমি কেবল উভয়ই চেষ্টা করেছিলাম

12

এটি স্কেল 2.11.5 ব্যবহার করে পরীক্ষা করা হয়েছিল। নীচের কোড বিবেচনা করুন

class C(private val x: Int) {
  override def equals(obj: Any) = obj match {
    case other: C => x == other.x
    case _ => false
  }
}

println(new C(5) == new C(5)) //true
println(new C(5) == new C(4)) //false

এটি এই জাভা (1.8) কোড হিসাবে সংকলন এবং কাজ করবে

class C {
    private int x;

    public C(int x) {
        this.x = x;
    }

    public boolean equals(Object obj) {
        if (obj instanceof C) {
            return ((C) obj).x == x;
        }
        else {
            return false;
        }
    }
}

System.out.println(new C(5).equals(new C(5))); //true
System.out.println(new C(5).equals(new C(4))); //false

তবে আপনি যদি '[এটি]' সংশোধক ব্যবহার করেন তবে নীচের কোডটি সংকলন করবে না

class C(private[this] val x: Int) {
  override def equals(obj: Any) = obj match {
    case other: C => this.x == other.x //problem is here
    case _ => false
  }
}

এটি কারণ প্রথম ক্ষেত্রে 'x' শ্রেণীর স্তরে অ্যাক্সেসযোগ্য, তবে দ্বিতীয় ক্ষেত্রে এটি আরও কঠোর উদাহরণ স্তর। এর অর্থ হল যে 'x' কেবলমাত্র এটির সাথে সম্পর্কিত উদাহরণ থেকে অ্যাক্সেস করা যেতে পারে। সুতরাং 'this.x' ঠিক আছে তবে 'other.x' হয় না।

অ্যাক্সেস মডিফায়ারগুলি সম্পর্কে আরও তথ্যের জন্য আপনি "স্ক্যালায় ইন প্রোগ্রামিং: একটি বিস্তৃত ধাপে ধাপে গাইড" বইয়ের ১৩.৫ সেকশনটি পড়তে পারেন।


1
প্রশ্নটি জিজ্ঞাসা করছে না এর private[this]অর্থ কী । প্রথম বাক্যটি নোট করুন।
আলেক্সি রোমানভ

9

বেসরকারী সংশোধক ( প্রাইভেট [এক্স] ) এ স্কোপ যুক্ত করার সময় , এটি কার্যকরভাবে একটি "আপ" এক্স হিসাবে আচরণ করে, যেখানে এক্স কিছু সংযুক্তি প্যাকেজ, শ্রেণি বা সিঙ্গলটন অবজেক্টকে মনোনীত করে।

উদাহরণস্বরূপ, বেসরকারী [বার] , যেখানে বারটি একটি প্যাকেজ মানে প্যাকেজ বারের অন্তর্ভুক্ত প্রতিটি শ্রেণীর প্রতিটি উদাহরণ সংশোধনকারী যে কোনও সদস্যকে সীমাবদ্ধ রাখে তা অ্যাক্সেস করতে পারে।

ব্যক্তিগত [এটি] এর ক্ষেত্রে , এর অর্থ হল যে সদস্যটি কেবলমাত্র প্রতিটি ঘটনার জন্য অ্যাক্সেসযোগ্য। এটি নিম্নলিখিত উদাহরণে আরও স্পষ্ট হয়ে ওঠে:

class Foo(foo:Foo){  
   private[this] val i = 2
   println(this.i + foo.i)
}

>>error: value i is not a member of Foo

class Foo(foo:Foo){  
    private val i = 2
    println(this.i + foo.i)
}

>>defined class Foo

যেমন আপনি দেখতে পাচ্ছেন, দ্বিতীয় ফুতে কোনও সমস্যা নেই যেহেতু কোনও উদাহরণ বেসরকারী ভাল i অ্যাক্সেস করতে পারে। তবে প্রথম ফু এর জন্য একটি ত্রুটি আছে কারণ প্রতিটি উদাহরণ অন্য আইনের আই দেখতে পাবে না।

এটি প্রাইভেট লিখতে ভাল অনুশীলন [এটি] যেহেতু এটি একটি আরও বড় বাধা আরোপ করে।


6

জাভা জাতীয় বেশিরভাগ ওওপি প্রোগ্রামিং ভাষায়, ব্যক্তিগত ক্ষেত্র / পদ্ধতিগুলির অর্থ এই ব্যক্তিগত ক্ষেত্রগুলি / পদ্ধতিগুলি শ্রেণীর বাইরে বাইরে অ্যাক্সেসযোগ্য নয়। তবে, একই শ্রেণীর উদাহরণ / অবজেক্টগুলি অ্যাসাইনমেন্ট অপারেটর ব্যবহার করে বা অনুলিপি নির্মাণকারীর মাধ্যমে অবজেক্টগুলির ব্যক্তিগত ক্ষেত্রগুলিতে অ্যাক্সেস পেতে পারে। স্কালায়, ব্যক্তিগত [এটি] অবজেক্ট প্রাইভেট, যা নিশ্চিত করে যে একই শ্রেণীর অন্য কোনও বস্তু ব্যক্তিগত [এই] সদস্যদের অ্যাক্সেস করতে অক্ষম।

উদাহরণ

1. ব্যক্তিগত ব্যতীত [এটি]

object ObjectPrivateDemo {

  def main(args: Array[String]) {
    var real = new User("realUserName", "realPassword")
    var guest = new User("dummyUserName", "dummyPassword")
    real.displayUser(guest)

  }
}

class User(val username:String,val password:String) {
  private var _username=username
  private var _password=password



  def displayUser(guest:User){

         println(" guest username="+guest._username+" guest password="+guest._password)
       guest._username= this._username
    guest._password=  this._password
       println(" guest username="+guest._username+" guest password="+guest._password)


  }
}

2. ব্যক্তিগত ব্যবহার করা [এটি]

class User(val username: String, val password: String) {
  private var _username = username
  private[this] var _password = password



  def displayUser(guest: User) {

    println(this._username)
    println(this._password)

    guest._username = this._username
    // for guest._password it will give this :error  value _password is not member of class User
    guest._password = this._password

  }
}

তাই ব্যক্তিগত [এটি] নিশ্চিত করে যে _ পাসওয়ার্ড ক্ষেত্রটি কেবল এটির মাধ্যমেই অ্যাক্সেসযোগ্য।


এটি এখন পর্যন্ত পরিষ্কার এবং আরও উদ্দেশ্যমূলক উত্তর।
লুকাস লিমা

2

আলেক্সি রোমানভ উল্লেখ করেছেন পারফরম্যান্স ইস্যুটি সম্পর্কে বিস্তারিত জানাতে, আমার অনুমানের কয়েকটি এখানে। "স্ক্যালায় ইন প্রোগ্রামিং: একটি বিস্তৃত ধাপে ধাপে গাইড, দ্বিতীয় সংস্করণ" বইয়ের উদ্ধৃতিগুলি বিভাগ 18.2:

স্কালায়, প্রতিটি ভ্যার যা কোনও না কোনও অবজেক্টের বেসরকারী সদস্য প্রকৃতপক্ষে এটির সাথে একটি গেটর এবং সেটার পদ্ধতিটি সংজ্ঞায়িত করে।

এটি পরীক্ষা করার জন্য, এই কোডটি সংকলনের ত্রুটি ঘটাবে:

class PrivateTest{
  var data: Int = 0
  def data_=(x : Int){
    require(x > 0)
    data = x
  }
}

সম্পর্কে স্কেলা অভিযোগ error: ambiguous reference to overloaded definitiondata_=সাহায্য করবে না ওভাররাইড কীওয়ার্ড যুক্ত করে প্রমাণ করা উচিত যে পদ্ধতিটি সংকলক দ্বারা উত্পাদিত হয়েছে। যোগ করার পদ্ধতি privateপরিবর্তনশীল শব্দ dataএখনও এই সংকলন ত্রুটি হতে হবে। তবে, নিম্নলিখিত কোডটি জরিমানা সংকলন করেছে:

class PrivateTest{
  private[this] var data: Int = 0
  def data_=(x : Int){
    require(x > 0)
    data = x
  }
}

সুতরাং, আমি অনুমান করি যে private[this]স্কেলারটি গেটর এবং সেটার পদ্ধতিগুলি উত্পাদন করা থেকে রোধ করবে। সুতরাং, এই ধরণের ভেরিয়েবল অ্যাক্সেস করা গিটার এবং সেটার পদ্ধতি কল করার ওভারহেড সংরক্ষণ করবে।


1

আমার কি সর্বদা এটি ডিফল্টরূপে ব্যবহার করা উচিত? অথবা আমি কেবলমাত্র নির্দিষ্ট কিছু ক্ষেত্রে এটি ব্যবহার করব যেখানে একই শ্রেণীর অবজেক্টের জন্য এমনকি ক্ষেত্রের মান পরিবর্তন করতে আমাকে স্পষ্টভাবে সীমাবদ্ধ করতে হবে? অন্য কথায় আমার মধ্যে কীভাবে নির্বাচন করা উচিত

private[this]আপনি যদি ভেরিয়েবল সিঙ্ক্রোনাইজ করার পরিকল্পনা করেন তবে এটি ব্যবহার করা ভাল ।

এখানে স্পার্ক দলের স্কেল স্টাইল গাইডের একটি ভাল উদাহরণ :

// The following is still unsafe.
class Foo {
  private var count: Int = 0
  def inc(): Unit = synchronized { count += 1 }
}

// The following is safe.
class Foo {
  private[this] var count: Int = 0
  def inc(): Unit = synchronized { count += 1 }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.