বিমূর্ত ক্ষেত্র কেন?


103

জাভা ক্লাসগুলির বিমূর্ত ক্ষেত্রগুলির মতো বিমূর্ত ক্ষেত্র থাকতে পারে না কেন?

উদাহরণস্বরূপ: আমার দুটি ক্লাস রয়েছে যা একই বিমূর্ত বেস শ্রেণিকে প্রসারিত করে। এই দুটি ক্লাসের প্রত্যেকটির একটি পদ্ধতি রয়েছে যা স্ট্রিং ধ্রুবক ব্যতীত অভিন্ন, যা তাদের মধ্যে ত্রুটির বার্তা হিসাবে ঘটে। ক্ষেত্রগুলি যদি বিমূর্ত হতে পারে তবে আমি এই ধ্রুবক বিমূর্ততা তৈরি করতে পারি এবং পদ্ধতিটিকে বেস শ্রেণিতে টানতে পারি। পরিবর্তে, আমাকে getErrMsg()এই ক্ষেত্রে ডাকা একটি বিমূর্ত পদ্ধতি তৈরি করতে হবে , এটি স্ট্রিংকে ফিরে আসে, দুটি উদ্ভূত শ্রেণিতে এই পদ্ধতিটিকে ওভাররাইড করে এবং তারপরে আমি পদ্ধতিটি টানতে পারি (যা এখন বিমূর্ত পদ্ধতি বলে)।

আমি কেন ক্ষেত্রটিকে শুরু করতে বিমূর্ত করতে পারি না? জাভা কি এটির নকশা তৈরি করতে পারত?


4
দেখে মনে হচ্ছে আপনি ক্ষেত্রটিকে অ-ধ্রুবক তৈরি করে এবং কেবল কনস্ট্রাক্টরের মাধ্যমে মান সরবরাহ করে, 2 শ্রেণির পরিবর্তে এক শ্রেণির 2 টি উদাহরণ দিয়ে শেষ করে এই পুরো বিষয়টিটিকেই ছাপিয়ে ফেলতে পারেন।
Nate

5
একটি সুপার ক্লাসে ক্ষেত্রগুলি বিমূর্ত করে তোলে, আপনি সুনির্দিষ্ট করেছেন যে প্রতিটি উপ শ্রেণীর অবশ্যই এই ক্ষেত্রটি থাকতে হবে, সুতরাং এটি একটি অ-বিমূর্ত ক্ষেত্রের থেকে আলাদা নয়।
পিটার লরি

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

4
@ লিলেটিটাস ২27 আমি মনে করি 3.5 বছর আগে আমার বক্তব্যটি ছিল যে বিমূর্ত ক্ষেত্রগুলি প্রয়োগের মাধ্যমে একটি ইন্টারফেসের ব্যবহারকারীকে আলাদা করার পুরো ধারণাটি ভাঙা ব্যতীত খুব বেশি পরিবর্তন হবে না।
পিটার লরে

এটি সহায়ক হবে কারণ এটি শিশু শ্রেণিতে কাস্টম ফিল্ড টীকাগুলির অনুমতি দিতে পারে
48

উত্তর:


106

আপনি আপনার বিমূর্ত শ্রেণিতে একটি চূড়ান্ত ক্ষেত্র যা এর নির্মাতা (অনির্ধারিত কোড) থেকে শুরু করা হয়েছে তার দ্বারা আপনি যা বর্ণনা করেছেন তা করতে পারেন:

abstract class Base {

    final String errMsg;

    Base(String msg) {
        errMsg = msg;
    }

    abstract String doSomething();
}

class Sub extends Base {

    Sub() {
        super("Sub message");
    }

    String doSomething() {

        return errMsg + " from something";
    }
}

যদি আপনার শিশু শ্রেণি সুপার কন্সট্রাক্টরের মাধ্যমে চূড়ান্ত সূচনা করতে "ভুলে যায়" তবে কম্পাইলার একটি সতর্কতা একটি ত্রুটি দেবে, ঠিক যেমন একটি বিমূর্ত পদ্ধতি প্রয়োগ করা হয়নি তখন।


এখানে চেষ্টা করার জন্য কোনও সম্পাদক পান নি, তবে এটিই আমি পোস্ট করতে যাচ্ছিলাম ..
টিম

6
"সংকলক একটি সতর্কতা দেবে"। প্রকৃতপক্ষে, চাইল্ড কনস্ট্রাক্টর একটি অস্তিত্বহীন নোর্গস কনস্ট্রাক্টর ব্যবহার করার চেষ্টা করবে এবং এটি সংকলন ত্রুটি (কোনও সতর্কতা নয়)।
স্টিফেন সি

এবং @ স্টেফেন সি-এর মন্তব্যে যুক্ত করা, "যেমন যখন একটি বিমূর্ত পদ্ধতি প্রয়োগ করা হয় না" তেমনি একটি ত্রুটিও, সতর্কবার্তা নয়।
লরেন্স গনসালভেস

4
ভাল উত্তর - এটি আমার পক্ষে কাজ করেছে। আমি জানি এটি পোস্ট হওয়ার পরে অনেক দিন হয়েছে তবে মনে Baseহয় এটি ঘোষণার দরকার abstract
স্টিভ চেম্বারস

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

8

আমি তাতে কোন লাভ দেখছি না। আপনি ফাংশনটি বিমূর্ত শ্রেণিতে স্থানান্তর করতে পারেন এবং কিছু সুরক্ষিত ক্ষেত্রকে ওভাররাইড করতে পারেন। আমি জানি না এটি ধ্রুবকগুলির সাথে কাজ করে তবে তবে প্রভাবটি একই:

public abstract class Abstract {
    protected String errorMsg = "";

    public String getErrMsg() {
        return this.errorMsg;
    }
}

public class Foo extends Abstract {
    public Foo() {
       this.errorMsg = "Foo";
    }

}

public class Bar extends Abstract {
    public Bar() {
       this.errorMsg = "Bar";
    }
}

সুতরাং আপনার বক্তব্যটি হ'ল আপনি সাবক্ল্যাসে যা কিছু প্রয়োগ / ওভাররাইডিং / প্রয়োগ করতে চান errorMsg? আমি ভেবেছিলাম আপনি কেবল বেস ক্লাসে পদ্ধতিটি রাখতে চান এবং তখন ক্ষেত্রের সাথে কীভাবে আচরণ করবেন তা জানেন না।


5
ঠিক আছে, আমি অবশ্যই এটি করতে পারে। এবং আমি এটা ভেবেছিলাম। কিন্তু কেন আমি বেস শ্রেণীর মধ্যে একটি মান সেট করতে হবে যখন আমি এই সত্যটি জানতে পারি যে আমি প্রতিটি উত্পন্ন শ্রেণিতে এই মানটিকে ওভাররাইড করতে চলেছি? আপনার যুক্তিটিও যুক্তিযুক্তভাবে ব্যবহার করা যেতে পারে যে বিমূর্ত পদ্ধতিতে অনুমতি দেওয়ার কোনও মূল্য নেই।
পল রেইনার্স

4
আচ্ছা এই উপায় না যে উপশ্রেণী রয়েছে মান ওভাররাইড করতে। আমি কেবল সংজ্ঞায়িত করতে পারি protected String errorMsg;যে কোন উপায়ে প্রয়োগ করে যে আমি সাবক্লাসে মান সেট করেছিলাম। এটি অ্যাবস্ট্রাক্ট ক্লাসগুলির মতো যা বাস্তবে স্থানধারক হিসাবে সমস্ত পদ্ধতি প্রয়োগ করে যাতে বিকাশকারীদের প্রতিটি পদ্ধতি প্রয়োগ করতে হয় না যদিও তাদের এটির প্রয়োজন হয় না।
ফেলিক্স ক্লিং

7
বলাটি প্রয়োগ protected String errorMsg;করে না যে আপনি সাবক্লাসে মান সেট করেছেন।
লরেন্স গনসাল্ভেস

4
যদি মানটি যদি বাতিল হয়ে থাকে তবে আপনি যদি এটি "প্রয়োগকারী" হিসাবে গণ্য করেন না, তবে আপনি অ-প্রয়োগকারীকে কী বলবেন?
লরেন্স গনসালভেস

9
@ ফেলিক্স, প্রয়োগকারী এবং চুক্তিগুলির মধ্যে একটি পার্থক্য রয়েছে । এই পুরো পোস্টটি বিমূর্ত শ্রেণীর চারদিকে কেন্দ্রিক, যা ঘুরেফিরে এমন একটি চুক্তি উপস্থাপন করে যা অবশ্যই কোনও সাবক্লাস দ্বারা পূরণ করা আবশ্যক। সুতরাং, যখন আমরা একটি বিমূর্ত ক্ষেত্র থাকার কথা বলি, তখন আমরা বলছি যে কোনও সাবক্লাস অবশ্যই সেই ক্ষেত্রের মান প্রতি চুক্তি অনুসারে বাস্তবায়ন করবে। আপনার পদ্ধতির কোনও মান গ্যারান্টি দেয় না, এবং চুক্তি যেমনটি প্রত্যাশিত হয় তা স্পষ্ট করে দেয় না। খুব, খুব আলাদা
lilitus27

3

স্পষ্টতই এটির অনুমতি দেওয়ার জন্য এটি নকশা করা যেতে পারে তবে কভারগুলির আওতায় এটি এখনও গতিশীল প্রেরণা করতে হবে, এবং সেইজন্য একটি পদ্ধতি কল। জাভার নকশা (কমপক্ষে প্রথম দিনগুলিতে) কিছুটা হলেও সংখ্যালঘু হওয়ার চেষ্টা ছিল। এটি হ'ল ডিজাইনাররা নতুন বৈশিষ্ট্য যুক্ত করা এড়াতে চেষ্টা করেছেন যদি তারা ভাষায় ইতিমধ্যে অন্যান্য বৈশিষ্ট্যগুলির দ্বারা সহজেই সিমুলেটেড করা যায়।


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

0

আপনার শিরোনাম পড়ে, আমি ভেবেছিলাম আপনি বিমূর্ত উদাহরণ সদস্যদের উল্লেখ করছেন; এবং আমি তাদের জন্য খুব বেশি ব্যবহার দেখতে পেলাম না। তবে বিমূর্ত স্থির সদস্যরা সম্পূর্ণ অন্য বিষয় another

আমি প্রায়শই ইচ্ছে করেছিলাম যে আমি জাভাতে নিম্নলিখিতগুলির মতো একটি পদ্ধতি ঘোষণা করতে পারি:

public abstract class MyClass {

    public static abstract MyClass createInstance();

    // more stuff...

}

মূলত, আমি জোর দিয়ে বলতে চাই যে আমার অভিভাবক শ্রেণীর কংক্রিট বাস্তবায়নগুলি একটি নির্দিষ্ট স্বাক্ষর সহ একটি স্থির কারখানার পদ্ধতি সরবরাহ করে। এটি আমাকে একটি কংক্রিট শ্রেণীর সাথে একটি রেফারেন্স পেতে Class.forName()এবং নিশ্চিত হতে পারে যে আমি আমার পছন্দের একটি সম্মেলনে একটি নির্মাণ করতে পারি।


4
হ্যাঁ ... সম্ভবত এর অর্থ এই যে আপনি প্রতিবিম্বটি অনেক বেশি ব্যবহার করছেন !!
স্টিফেন সি

আমার কাছে এক অদ্ভুত প্রোগ্রামিং অভ্যাসের মতো শোনাচ্ছে। Class.forName (..) ডিজাইনের ত্রুটির মতো গন্ধ পাচ্ছে।
হুইস্কিসিয়ার

আজকাল আমরা মূলত এই ধরণের জিনিসটি সম্পাদন করতে স্প্রিং ডিআই ব্যবহার করি; তবে সেই কাঠামোটি পরিচিত ও জনপ্রিয় হওয়ার আগে আমরা বৈশিষ্ট্য বা এক্সএমএল ফাইলগুলিতে প্রয়োগের ক্লাস নির্দিষ্ট করে দেব, তারপরে তাদের লোড করার জন্য Class.forName () ব্যবহার করুন।
ড্রু উইলস

তাদের জন্য আমি আপনাকে ব্যবহারের একটি মামলা দিতে পারি। প্রায় অসম্ভব "বিমূর্ত ক্ষেত্র" অনুপস্থিতি একটি বিমূর্ত জেনেরিক ক্লাসে একটি জেনেরিক ধরনের একটি ক্ষেত্র ডিক্লেয়ার: @autowired T fieldName। যদি এর Tমতো কিছু হিসাবে সংজ্ঞায়িত T extends AbstractControllerকরা হয় তবে টাইপ AbstractControllerমোছার ফলে ক্ষেত্রটি টাইপ হিসাবে উত্পন্ন হয় এবং যা স্বায়ত্তশাসিত হতে পারে না কারণ এটি কংক্রিট নয় এবং অনন্য নয়। আমি সাধারণত সম্মত হই যে তাদের জন্য খুব বেশি ব্যবহার হয় না এবং তাই তারা ভাষায় অন্তর্ভুক্ত হয় না। আমি যেটির সাথে একমত হইব না তা হ'ল তাদের পক্ষে কোনও ব্যবহার নেই।
ডাব্লিক

0

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

public abstract class Base {
  public final int field;
  public Base() {
    if (this instanceof SubClassOne) {
      field = 1;
    } else if (this instanceof SubClassTwo) {
      field = 2;
    } else {
      // assertion, thrown exception, set to -1, whatever you want to do 
      // to trigger an error
      field = -1;
    }
  }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.