নতুন উপাদান যুক্ত করতে এনামগুলিকে কি সাবক্লাস করা যেতে পারে?


534

আমি একটি বিদ্যমান এনাম নিতে এবং এটিতে আরও উপাদান যুক্ত করতে চাই:

enum A {a,b,c}

enum B extends A {d}

/*B is {a,b,c,d}*/

জাভাতে এটি কি সম্ভব?


12
এটি করার কারণ হ'ল মূল উত্সটিতে একটি অবৈধ এনাম মান প্রবর্তন না করেই সেখানে একটি অবৈধ এনাম মান রয়েছে এমন পরিস্থিতি পরীক্ষা করা।
আর্কিমিডিজ ট্রাজানো

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

4
আসলে, যখন আপনি নতুন মানগুলির সাথে এনাম প্রসারিত করবেন, আপনি সাবক্লাস নয়, সুপারক্লাস তৈরি করছেন। আপনি "বর্ধিত" এনামের পরিবর্তে সর্বত্র বেস এনাম মানগুলি ব্যবহার করতে পারেন তবে বিপরীত নয়, সুতরাং লিসকভ সাবস্টিটিউশন নীতিমালা অনুসারে, বর্ধিত এনাম হ'ল বেস এনামের সুপারক্লাস।
ইলিয়া

@ ইলিয়া ... হ্যাঁ এটি সত্য। আমি উল্লেখ করলাম যে প্রশ্নের নির্দিষ্ট বাস্তব-ব্যবহারের ক্ষেত্রে রয়েছে। যুক্তি অনুরোধে জন্য, একটি বিবেচনা বেস এর Enum: PrimaryColours; এটা করতে চান যুক্তিযুক্ত সুপার -class Enum এই PrimaryAndPastelColoursনতুন রঙ নাম যোগ করে। লিসকভ তখনও ঘরে হাতি। সুতরাং কেন একটি বেস এনুম দিয়ে শুরু করবেন না: AllMyColours- এবং তারপরে কেউ সমস্ত বর্ণগুলিকে সাব- ক্লাস করতে পারে : এবং পরবর্তীকালে এটিতে সাব- ক্লাস করুন: (শ্রেণিবদ্ধতা মাথায় রেখে)। জাভা যদিও অনুমতি দেয় না। PrimaryAndPastelColoursPrimaryColours
হবে

উত্তর:


450

না, আপনি জাভাতে এটি করতে পারবেন না। অন্য কিছু dবাদ দিলে সম্ভবত এটির উদাহরণ হতে পারে A("প্রসারিত" এর সাধারণ ধারণা দেওয়া থাকলে) তবে ব্যবহারকারীরা কেবল Aএটি সম্পর্কে জানতেন না - এটি এনামের একটি সুপরিচিত সেট হওয়ার বিন্দুকে পরাস্ত করে? মান।

আপনি কীভাবে এটি ব্যবহার করতে চান সে সম্পর্কে যদি আমাদের আরও বলতে পারেন , আমরা সম্ভাব্যভাবে বিকল্প সমাধানের পরামর্শ দিতে পারি।


516
সমস্ত এনামগুলি স্পষ্টতই java.lang.Enum প্রসারিত করে। যেহেতু জাভা একাধিক উত্তরাধিকার সমর্থন করে না, একটি এনাম অন্য কিছু বাড়িয়ে দিতে পারে না।
givanse

9
আমি প্রসারিত করার কারণটি হ'ল কারণ আমি উদাহরণস্বরূপ ইন্টেনাম নামে একটি বেস ক্লাস করতে চাই, এটি দেখতে এটির মতো: stackoverflow.com/questions/1681976/enum-with-int-value-in-java/… । তারপরে আমার সমস্ত এনামগুলি এটিকে প্রসারিত করতে পারে ... এক্ষেত্রে কেবল উত্তরাধিকার থেকে উপকৃত হবে এবং এইভাবে আমাকে এই "অন্তর্নিহিত এনাম" কোডটি ঘন ঘন নকল করতে হবে না। আমি জাভাতে নতুন এবং সি # থেকে আসছি এবং আমি আশা করছি যে আমি কিছু মিস করছি। আমার বর্তমান মতামতটি হল জাভা এনামগুলি সি # এর তুলনায় একটি ব্যথা।
টাইলার কলিয়ার

30
@ টাইলার: সি # এনামগুলি কেবলমাত্র সংখ্যার সাথে যুক্ত নাম, কোনও স্বয়ংক্রিয় বৈধতা বা কোনও কিছুই ছাড়াই । আইএমও এনামগুলি জাভা এক বিট যা আসলে সি # এর চেয়ে ভাল।
জন স্কিটি

21
এখানে @ জনস্কিটের সাথে সম্মতিজনক নয়। আমার ব্যবহারের ক্ষেত্রে, আমি আমার বড় এনামগুলিতে সমস্ত বাজে যুক্তি যুক্ত করতে চাই এবং যুক্তিটি লুকিয়ে রাখতে চাই এবং একটি পরিষ্কার এনামকে সংজ্ঞায়িত করব যা অন্যটি লুকিয়ে রাখে। প্রচুর যুক্তিযুক্ত এনামগুলি ক্লিন ভেরিয়েবল ঘোষণার ধারণাটিকে মারধর করে যাতে আপনাকে শত স্থিতিশীল স্ট্রিং ভেরিয়েবলগুলি ঘোষণা করতে হয় না যাতে 5 এনাম সহ একটি শ্রেণি অপঠনযোগ্য এবং খুব বেশি লাইনে না যায়। আমি অন্য ডেভেলপারদের অনুলিপি এবং পরবর্তী প্রকল্পের জন্য কোড যে শান্তি পেস্ট পারেন পরিবর্তে এবং base_enum প্রসারিত সঙ্গে সংশ্লিষ্ট হতে চাই না ... এটা আমার কাছে জ্ঞান করে তোলে ...
MMM

43
@ জিভানসে ... জাভা.এলং এর নিখরচায় সম্প্রসারণের পয়েন্টে আপনার সাথে একমত হচ্ছেন না। এনাম উত্তরাধিকারের কারণ হওয়ায় জাভাতে প্রতিটি শ্রেণিও অবজেক্ট অবজেক্ট ক্লাসের উত্তরাধিকার সূত্রে তবুও এটি অন্য কোন শ্রেণির উত্তরাধিকারী হতে পারে Object->A->Bপরিবর্তে হায়ারার্কিতেObject->A->B extends Object
মিকিউমুন

317

এনামগুলি সম্ভাব্য মানগুলির একটি সম্পূর্ণ গণনা উপস্থাপন করে। সুতরাং (অপ্রয়োজনীয়) উত্তরটি হ'ল না।

বাস্তব সমস্যার উদাহরণ হিসাবে সপ্তাহের দিন, সাপ্তাহিক দিন এবং ইউনিয়নের সপ্তাহের দিনগুলি গ্রহণ করুন। আমরা সপ্তাহের দিনের মধ্যে সমস্ত দিন সংজ্ঞায়িত করতে পারি তবে তারপরে আমরা সপ্তাহের দিন এবং সপ্তাহান্তের দিনগুলিতে বিশেষ বৈশিষ্ট্যগুলি উপস্থাপন করতে সক্ষম হব না।

আমরা যা করতে পারি তা হ'ল সপ্তাহের দিন / সপ্তাহান্তের দিন এবং সপ্তাহের দিনগুলির মধ্যে ম্যাপিং সহ তিনটি এনাম টাইপ রয়েছে।

public enum Weekday {
    MON, TUE, WED, THU, FRI;
    public DayOfWeek toDayOfWeek() { ... }
}
public enum WeekendDay {
    SAT, SUN;
    public DayOfWeek toDayOfWeek() { ... }
}
public enum DayOfWeek {
    MON, TUE, WED, THU, FRI, SAT, SUN;
}

বিকল্পভাবে, আমাদের সপ্তাহের দিনের জন্য একটি ওপেন-এন্ড ইন্টারফেস থাকতে পারে:

interface Day {
    ...
}
public enum Weekday implements Day {
    MON, TUE, WED, THU, FRI;
}
public enum WeekendDay implements Day {
    SAT, SUN;
}

অথবা আমরা দুটি পদ্ধতির একত্রিত করতে পারি:

interface Day {
    ...
}
public enum Weekday implements Day {
    MON, TUE, WED, THU, FRI;
    public DayOfWeek toDayOfWeek() { ... }
}
public enum WeekendDay implements Day {
    SAT, SUN;
    public DayOfWeek toDayOfWeek() { ... }
}
public enum DayOfWeek {
    MON, TUE, WED, THU, FRI, SAT, SUN;
    public Day toDay() { ... }
}

20
এ নিয়ে সমস্যা নেই? একটি সুইচ বিবৃতি কোনও ইন্টারফেসে কাজ করবে না, তবে এটি নিয়মিত এনামে কাজ করে। ডাব্লু / স্যুইচ জাতীয় ধরণের কাজ না করা এনামগুলির সম্পর্কে একটি দুর্দান্ত জিনিসকে হত্যা করে।
ম্যানিয়াস

9
আমি ভাবছি এর সাথে আর কোনও সমস্যা হতে পারে। উইকডে.মোন এবং ডেওফিউক.মনের মধ্যে কোনও সমতা নেই। এটি কি এনামদের অন্যান্য বড় সুবিধা নয়? আমি এর চেয়ে ভাল সমাধান পাচ্ছি না, কেবল এটি উপলব্ধি করার সাথে সাথে আমি সেরা উত্তরটি খুঁজতে চেষ্টা করছি। == ব্যবহারে সক্ষম হবার অভাব হাতকে কিছুটা জোর করে।
স্নেকস

2
@ ক্রুসাডার হ্যাঁ, এটি হ'ল বাণিজ্য বন্ধ। আপনি যদি কিছু প্রসারণযোগ্য চান তবে আপনার স্থির সুইচ স্টেটমেন্ট থাকতে পারে না, আপনি যদি নির্দিষ্ট জ্ঞাত মানগুলির সেট চান তবে আপনি টটোলজিক্যালি কিছু প্রসারণযোগ্য হতে পারবেন না।
djechlin

3
এনাম থেকে ইন্টারফেসে যেতে, আপনি মানগুলিতে স্থিত কল () হারাবেন। এটি রিফ্যাক্টরিংটিকে শক্ত করে তোলে, বিশেষত যদি আপনি নিজের এনাম প্রসারিত করার এবং ইন্টারফেসটিকে একটি প্রতিষ্ঠিত এনামের বিমূর্ততা বাধা হিসাবে যুক্ত করার সিদ্ধান্ত নেন।
জোশুয়া গোল্ডবার্গ

4
একটি ইন্টারফেস থেকে এনাম নেওয়ার এই পদ্ধতির ব্যবহার জাভা 1.7 এপিআই, যেমন java.nio.file.Files.write () দ্বারা সর্বশেষ আর্গুমেন্ট হিসাবে ওপেন অপশনটির অ্যারে নেয় takes ওপেন অপশন একটি ইন্টারফেস, তবে আমরা যখন এই ফাংশনটি কল করি আমরা সাধারণত একটি স্ট্যান্ডার্ড ওপেন অপশন এনাম ধ্রুবকটি পাস করি যা ওপেন অপশন থেকে প্রাপ্ত। এটি এক্সটেনসিবল হওয়ার সুবিধা রয়েছে তবে এটির ঘাটতিও রয়েছে। বাস্তবায়ন ওপেন অপশনটি একটি ইন্টারফেসের সত্যতায় ভুগছে। এটি পাস করা অ্যারে থেকে একটি হ্যাশসেট <ওপেন অপশন> তৈরি করে, যখন এটি আরও একটি স্থান তৈরি করতে পারত- এবং সময়-দক্ষ এনামসেট। এবং এটি স্যুইচ ব্যবহার করতে পারে না।
ক্লিটোস কিরিয়াকু

71

এটির প্রস্তাবিত সমাধান হ'ল এক্সটেনসেবল এনাম প্যাটার্ন

এর মধ্যে একটি ইন্টারফেস তৈরি করা এবং আপনি বর্তমানে এনাম ব্যবহার করেন সেখানে তা জড়িত। তারপরে এনাম ইন্টারফেসটি বাস্তবায়ন করুন। নতুন এনুম করে ইন্টারফেসটি প্রসারিত করে আপনি আরও ধ্রুবক যুক্ত করতে পারেন।


ইন্টারফেসে কারখানার পদ্ধতিটি তাদের ব্যবহারের কথা বলা উপযুক্ত। বর্ধিতকরণ একটি কার্যক্ষম সমাধান নয় তা প্রদত্ত সম্পর্কিত এনামগুলির মধ্যে সাধারণ কার্যকারিতা ভাগ করে নেওয়ার দুর্দান্ত উপায়।
টিম ক্লেমনস

8
আপনি কি এই প্যাটার্ন সম্পর্কে আরও বিশদ (কোড :)) সরবরাহ করতে পারেন?
ধেরিক

3
এই প্যাটার্নটি কোনও এনামের মানগুলি বাড়ানোর অনুমতি দেয় না। জিজ্ঞাসা করা প্রশ্নে কোন বিষয়।
ইরিয়া

55

কভারগুলির নীচে আপনার ENUM সংকলক দ্বারা উত্পাদিত কেবল একটি নিয়মিত ক্লাস। যে উত্পন্ন শ্রেণি প্রসারিত java.lang.Enum। আপনি উত্পন্ন শ্রেণিটি প্রসারিত করতে পারবেন না এমন প্রযুক্তিগত কারণ হ'ল উত্পন্ন শ্রেণিfinal । এটি চূড়ান্ত হওয়ার ধারণাগত কারণগুলি এই বিষয়টিতে আলোচনা করা হয়েছে। তবে আমি আলোচনায় যান্ত্রিক যুক্ত করব।

এখানে একটি পরীক্ষা এনাম:

public enum TEST {  
    ONE, TWO, THREE;
}

জাভাপ থেকে প্রাপ্ত ফলাফল:

public final class TEST extends java.lang.Enum<TEST> {
  public static final TEST ONE;
  public static final TEST TWO;
  public static final TEST THREE;
  static {};
  public static TEST[] values();
  public static TEST valueOf(java.lang.String);
}

সম্ভবত আপনি নিজেরাই এই ক্লাসটি টাইপ করতে এবং "চূড়ান্ত" বাদ দিতে পারেন। তবে সংকলক আপনাকে সরাসরি "java.lang.Enum" প্রসারিত করতে বাধা দেয়। আপনি java.lang.Enum প্রসারিত না করার সিদ্ধান্ত নিতে পারেন, তবে তারপরে আপনার ক্লাস এবং এর উত্পন্ন ক্লাসগুলি java.lang.Enum এর উদাহরণ নয় ... যা আপনার পক্ষে কোনওভাবেই গুরুত্বপূর্ণ না!


1
খালি স্ট্যাটিক ব্লক কী করছে? 'স্ট্যাটিক {};'
সল্ট করুন

1
এটিতে কোনও কোড নেই। "জাভ্যাপ" প্রোগ্রামটি খালি ব্লকটি দেখায়।
ক্রিসকন্ট্রেল

এটি কিছু আছে না যদি এটি আছে অদ্ভুত?
soote

4
তুমি ঠিক! আমার ভুল. এটি কোডের খালি ব্লক নয়। আপনি যদি "জাভাপ-সি" চালনা করেন তবে আপনি স্ট্যাটিক ব্লকের ভিতরে আসল কোডটি দেখতে পাবেন। স্ট্যাটিক ব্লকটি সমস্ত ENUM দৃষ্টান্ত তৈরি করে (এক, দুটি এবং এখানে তিনটি)। এর জন্যে দুঃখিত.
ক্রিসকন্ট্রেল

1
সরল সত্যটি বলার জন্য ধন্যবাদ: কারণ java.lang.Enum চূড়ান্ত ঘোষণা করা হয়েছে।
বেনিয়ামিন

26
enum A {a,b,c}
enum B extends A {d}
/*B is {a,b,c,d}*/

হিসাবে লেখা যেতে পারে:

public enum All {
    a       (ClassGroup.A,ClassGroup.B),
    b       (ClassGroup.A,ClassGroup.B),
    c       (ClassGroup.A,ClassGroup.B),
    d       (ClassGroup.B) 
...
  • ক্লাসগ্রুপ.বি.জেটমেমবার্স () এ {এ, বি, সি, ডি contains রয়েছে

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

if(myEvent.is(State_StatusGroup.START)) makeNewOperationObject()..
if(myEnum.is(State_StatusGroup.STEP)) makeSomeSeriousChanges()..
if(myEnum.is(State_StatusGroup.FINISH)) closeTransactionOrSomething()..

উদাহরণ:

public enum AtmOperationStatus {
STARTED_BY_SERVER       (State_StatusGroup.START),
SUCCESS             (State_StatusGroup.FINISH),
FAIL_TOKEN_TIMEOUT      (State_StatusGroup.FAIL, 
                    State_StatusGroup.FINISH),
FAIL_NOT_COMPLETE       (State_StatusGroup.FAIL,
                    State_StatusGroup.STEP),
FAIL_UNKNOWN            (State_StatusGroup.FAIL,
                    State_StatusGroup.FINISH),
(...)

private AtmOperationStatus(StatusGroupInterface ... pList){
    for (StatusGroupInterface group : pList){
        group.addMember(this);
    }
}
public boolean is(StatusGroupInterface with){
    for (AtmOperationStatus eT : with.getMembers()){
        if( eT .equals(this))   return true;
    }
    return false;
}
// Each group must implement this interface
private interface StatusGroupInterface{
    EnumSet<AtmOperationStatus> getMembers();
    void addMember(AtmOperationStatus pE);
}
// DEFINING GROUPS
public enum State_StatusGroup implements StatusGroupInterface{
    START, STEP, FAIL, FINISH;

    private List<AtmOperationStatus> members = new LinkedList<AtmOperationStatus>();

    @Override
    public EnumSet<AtmOperationStatus> getMembers() {
        return EnumSet.copyOf(members);
    }

    @Override
    public void addMember(AtmOperationStatus pE) {
        members.add(pE);
    }
    static { // forcing initiation of dependent enum
        try {
            Class.forName(AtmOperationStatus.class.getName()); 
        } catch (ClassNotFoundException ex) { 
            throw new RuntimeException("Class AtmEventType not found", ex); 
        }
    }
}
}
//Some use of upper code:
if (p.getStatus().is(AtmOperationStatus.State_StatusGroup.FINISH)) {
    //do something
}else if (p.getStatus().is(AtmOperationStatus.State_StatusGroup.START)) {
    //do something      
}  

আরও কিছু উন্নত যুক্ত করুন:

public enum AtmEventType {

USER_DEPOSIT        (Status_EventsGroup.WITH_STATUS,
              Authorization_EventsGroup.USER_AUTHORIZED,
              ChangedMoneyAccountState_EventsGroup.CHANGED,
              OperationType_EventsGroup.DEPOSIT,
              ApplyTo_EventsGroup.CHANNEL),
SERVICE_DEPOSIT     (Status_EventsGroup.WITH_STATUS,
              Authorization_EventsGroup.TERMINAL_AUTHORIZATION,
              ChangedMoneyAccountState_EventsGroup.CHANGED,
              OperationType_EventsGroup.DEPOSIT,
              ApplyTo_EventsGroup.CHANNEL),
DEVICE_MALFUNCTION  (Status_EventsGroup.WITHOUT_STATUS,
              Authorization_EventsGroup.TERMINAL_AUTHORIZATION,
              ChangedMoneyAccountState_EventsGroup.DID_NOT_CHANGED,
              ApplyTo_EventsGroup.DEVICE),
CONFIGURATION_4_C_CHANGED(Status_EventsGroup.WITHOUT_STATUS,
              ApplyTo_EventsGroup.TERMINAL,
              ChangedMoneyAccountState_EventsGroup.DID_NOT_CHANGED),
(...)

উপরের দিকে যদি আমাদের কিছু ব্যর্থ হয় (myEvent.is (State_StatusGroup.FAIL)) তারপরে পূর্ববর্তী ইভেন্টগুলি পুনরাবৃত্তি করে আমরা সহজেই যাচাই করতে পারি যে আমাদের কীভাবে অর্থ হস্তান্তর ফিরিয়ে দিতে হবে:

if(myEvent2.is(ChangedMoneyAccountState_EventsGroup.CHANGED)) rollBack()..

এটি এর জন্য কার্যকর হতে পারে:

  1. প্রসেসিং লজিক সম্পর্কে এক্সক্লুসিট মেটা-ডেটা সহ, মনে রাখার মতো কম
  2. কিছু বহু-উত্তরাধিকার বাস্তবায়ন
  3. আমরা ক্লাস স্ট্রাকচার ব্যবহার করতে চাই না, প্রাক্তন। সংক্ষিপ্ত স্থিতির বার্তা প্রেরণের জন্য

13

এই পদ্ধতিতে আমি কীভাবে খুঁজে পেয়েছিলাম যে কোনও এনামকে অন্য এনামগুলিতে কীভাবে প্রসারিত করা যায়, এটি খুব সোজা উপায় approach

সুপস আপনার সাধারণ ধ্রুবক সহ একটি এনাম রয়েছে:

public interface ICommonInterface {

    String getName();

}


public enum CommonEnum implements ICommonInterface {
    P_EDITABLE("editable"),
    P_ACTIVE("active"),
    P_ID("id");

    private final String name;

    EnumCriteriaComun(String name) {
        name= name;
    }

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

তাহলে আপনি এইভাবে কোনও ম্যানুয়াল প্রসারিত করার চেষ্টা করতে পারেন:

public enum SubEnum implements ICommonInterface {
    P_EDITABLE(CommonEnum.P_EDITABLE ),
    P_ACTIVE(CommonEnum.P_ACTIVE),
    P_ID(CommonEnum.P_ID),
    P_NEW_CONSTANT("new_constant");

    private final String name;

    EnumCriteriaComun(CommonEnum commonEnum) {
        name= commonEnum.name;
    }

    EnumCriteriaComun(String name) {
        name= name;
    }

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

অবশ্যই প্রতিবার যখন আপনার একটি ধ্রুবক বাড়ানো দরকার তখন আপনাকে আপনার সাব-ইনম ফাইলগুলি সংশোধন করতে হবে।


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

11

আপনি যদি এটি মিস করেন তবে চমৎকার জোশুয়া ব্লচের বই " জাভা কার্যকর, ২ য় সংস্করণ " এর একটি অধ্যায় রয়েছে ।

  • অধ্যায় 6 - এনাম এবং টিকা
    • আইটেম 34: ইন্টারফেসের সাথে এক্সটেনসিবল এনামগুলিকে অনুকরণ করুন

এখানে সরান

শুধু উপসংহার:

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

সংক্ষেপে, আপনি যখন এক্সটেনসিবল এনাম টাইপ লিখতে পারবেন না, আপনি ইন্টারফেস প্রয়োগ করে এমন একটি বেসিক এনাম টাইপের সাথে যেতে একটি ইন্টারফেস লিখে এটি অনুকরণ করতে পারেন। এটি ক্লায়েন্টদের তাদের নিজস্ব এনাম লিখতে দেয় যা ইন্টারফেস প্রয়োগ করে। এই এনামগুলি তখনই ব্যবহৃত হবে যেখানে বেসিক এনাম টাইপ ব্যবহার করা যেতে পারে, ধরেই নেওয়া ইন্টারফেসের ক্ষেত্রে এপিআইগুলি লেখা হয়।


6

আমি enums এড়ানোর ঝোঁক, কারণ তারা এক্সটেনসিবল হয় না। ওপি-র উদাহরণ সহকারে থাকার জন্য, যদি ক কোনও লাইব্রেরিতে থাকে এবং খ আপনার নিজের কোডে বি হয়, আপনি যদি এটি এনাম হয় তবে আপনি এটিকে প্রসারিত করতে পারবেন না। আমি মাঝে মাঝে এনামগুলি প্রতিস্থাপন করি:

// access like enum: A.a
public class A {
    public static final A a = new A();
    public static final A b = new A();
    public static final A c = new A();
/*
 * In case you need to identify your constant
 * in different JVMs, you need an id. This is the case if
 * your object is transfered between
 * different JVM instances (eg. save/load, or network).
 * Also, switch statements don't work with
 * Objects, but work with int.
 */
    public static int maxId=0;
    public int id = maxId++;
    public int getId() { return id; }
}

public class B extends A {
/*
 * good: you can do like
 * A x = getYourEnumFromSomeWhere();
 * if(x instanceof B) ...;
 * to identify which enum x
 * is of.
 */
    public static final A d = new A();
}

public class C extends A {
/* Good: e.getId() != d.getId()
 * Bad: in different JVMs, C and B
 * might be initialized in different order,
 * resulting in different IDs.
 * Workaround: use a fixed int, or hash code.
 */
    public static final A e = new A();
    public int getId() { return -32489132; };
}

এড়াতে কিছু পিট রয়েছে, কোডে মন্তব্যগুলি দেখুন। আপনার প্রয়োজনের উপর নির্ভর করে এটি এনামগুলির একটি শক্ত, এক্সটেনসিবল বিকল্প।


1
উদাহরণস্বরূপ আপনার যদি কিছু সাধারণ প্রয়োজন হয় তবে এটি ঠিক আছে। তবে এনামগুলি এমন একটি সম্পত্তি সম্পত্তিও রয়েছে যা বেশ কার্যকর।
inor

6

স্ট্যাটিক ইনিশিয়ালাইজারে রানটাইম চেক সহ আমি এনাম উত্তরাধিকারের ধরণটি এভাবে বাড়িয়ে তুলি। BaseKind#checkEnumExtenderচেক যে "ব্যাপ্ত" enum ঠিক একই ভাবে বেস enum সব মান ঘোষণা তাই #name()এবং#ordinal() সম্পূর্ণরূপে সুসংগত থাকা।

মানগুলি ঘোষণার জন্য এখনও অনুলিপি-পেস্ট জড়িত রয়েছে তবে কেউ যদি বাড়ানো মানগুলি আপডেট না করে বেস ক্লাসে কোনও মান যুক্ত বা সংশোধন করে তবে প্রোগ্রামটি দ্রুত ব্যর্থ হয়।

একে অপরকে প্রসারিত বিভিন্ন এনামগুলির সাধারণ ব্যবহার:

public interface Kind {
  /**
   * Let's say we want some additional member.
   */
  String description() ;

  /**
   * Standard {@code Enum} method.
   */
  String name() ;

  /**
   * Standard {@code Enum} method.
   */
  int ordinal() ;
}

বেস এনাম, যাচাই করার পদ্ধতি সহ:

public enum BaseKind implements Kind {

  FIRST( "First" ),
  SECOND( "Second" ),

  ;

  private final String description ;

  public String description() {
    return description ;
  }

  private BaseKind( final String description ) {
    this.description = description ;
  }

  public static void checkEnumExtender(
      final Kind[] baseValues,
      final Kind[] extendingValues
  ) {
    if( extendingValues.length < baseValues.length ) {
      throw new IncorrectExtensionError( "Only " + extendingValues.length + " values against "
          + baseValues.length + " base values" ) ;
    }
    for( int i = 0 ; i < baseValues.length ; i ++ ) {
      final Kind baseValue = baseValues[ i ] ;
      final Kind extendingValue = extendingValues[ i ] ;
      if( baseValue.ordinal() != extendingValue.ordinal() ) {
        throw new IncorrectExtensionError( "Base ordinal " + baseValue.ordinal()
            + " doesn't match with " + extendingValue.ordinal() ) ;
      }
      if( ! baseValue.name().equals( extendingValue.name() ) ) {
        throw new IncorrectExtensionError( "Base name[ " + i + "] " + baseValue.name()
            + " doesn't match with " + extendingValue.name() ) ;
      }
      if( ! baseValue.description().equals( extendingValue.description() ) ) {
        throw new IncorrectExtensionError( "Description[ " + i + "] " + baseValue.description()
            + " doesn't match with " + extendingValue.description() ) ;
      }
    }
  }


  public static class IncorrectExtensionError extends Error {
    public IncorrectExtensionError( final String s ) {
      super( s ) ;
    }
  }

}

এক্সটেনশন নমুনা:

public enum ExtendingKind implements Kind {
  FIRST( BaseKind.FIRST ),
  SECOND( BaseKind.SECOND ),
  THIRD( "Third" ),
  ;

  private final String description ;

  public String description() {
    return description ;
  }

  ExtendingKind( final BaseKind baseKind ) {
    this.description = baseKind.description() ;
  }

  ExtendingKind( final String description ) {
    this.description = description ;
  }

}

4

@ টম হাটিনের উপর ভিত্তি করে - ট্যাকললাইন উত্তরটি আমরা সুইচ সমর্থন যুক্ত করি,

interface Day<T> {
    ...
  T valueOf();
}

public enum Weekday implements Day<Weekday> {
    MON, TUE, WED, THU, FRI;
   Weekday valueOf(){
     return valueOf(name());
   }
}

public enum WeekendDay implements Day<WeekendDay> {
    SAT, SUN;
   WeekendDay valueOf(){
     return valueOf(name());
   }
}

Day<Weekday> wds = Weekday.MON;
Day<WeekendDay> wends = WeekendDay.SUN;

switch(wds.valueOf()){
    case MON:
    case TUE:
    case WED:
    case THU:
    case FRI:
}

switch(wends.valueOf()){
    case SAT:
    case SUN:
}

valueOf()পদ্ধতিটির ব্যবহার কী ?
এক্সেল অ্যাডভেন্টো

@AxelAdvento ধারণা এখানে আমরা ইন্টারফেস উপর নির্ভর করে Dayপদ্ধতি আছে যা valueOf()তারপর switch(Day.valueOf()), এটা দ্বারা বাস্তবায়িত হচ্ছে WeekDay, WeekEndDayenums।
খালেদ লেলা

3

আমি আপনাকে অন্য উপায় গ্রহণের পরামর্শ দিচ্ছি suggest

বিদ্যমান গণনা প্রসারিত করার পরিবর্তে একটি বৃহত্তর তৈরি করুন এবং এর একটি উপসেট তৈরি করুন। উদাহরণস্বরূপ যদি আপনার কাছে পিইটি নামক একটি গণনা থাকে এবং আপনি এটি আনিমালে প্রসারিত করতে চান তবে তার পরিবর্তে এটি করা উচিত:

public enum ANIMAL {
    WOLF,CAT, DOG
} 
EnumSet<ANIMAL> pets = EnumSet.of(ANIMAL.CAT, ANIMAL.DOG);

সতর্কতা অবলম্বন করুন, পোষা প্রাণী কোনও অপরিবর্তনীয় সংগ্রহ নয়, আপনি আরও সুরক্ষার জন্য পেয়ারা বা জাভা 9 ব্যবহার করতে পারেন।


2

আমি নিজেই এই একই সমস্যাটি পেয়ে আমার দৃষ্টিভঙ্গি পোস্ট করতে চাই। আমি মনে করি যে এরকম কিছু করার জন্য কয়েকটি দম্পতি প্রেরণামূলক কারণ রয়েছে:

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

একটি ইন্টারফেস ব্যবহার সত্যিই এটি কাটবে না: আপনি দুর্ঘটনাক্রমে নকল এনাম মান পেতে পারেন। কাম্য নয়।

আমি কেবল এনামগুলিকে একত্রিত করে শেষ করেছি: এটি নিশ্চিত করে যে এর সাথে সম্পর্কিত শ্রেণীর সাথে কম শক্তভাবে আবদ্ধ হওয়ার ব্যয়ে কোনও নকল মান থাকতে পারে না। তবে, আমি বুঝতে পেরেছি যে সদৃশ সমস্যাটিই আমার প্রধান উদ্বেগ ছিল ...


2

একটি এনুমকে বাড়ানো কেন তা বোঝার জন্য ভাষা বাস্তবায়ন স্তরে যুক্তিসঙ্গত নয় যদি আপনি বর্ধিত এনুমের একটি উদাহরণকে কেবল একটি রুটিনে পাস করেন যা কেবলমাত্র এনুমকে বোঝে তবে কী হবে consider একটি স্যুইচ যা সংকলক প্রতিশ্রুতি দিয়েছিল যে সমস্ত ক্ষেত্রে coveredাকা পড়েছিল বাস্তবে extended প্রসারিত এনুম মানগুলি আবরণ করবে না।

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

এটি ওপি-র ইচ্ছা সম্পর্কে কোনও মন্তব্য নয়, কেবল জাভা কেন কখনই এটি করতে যাচ্ছে না।


1

আশায় আমার সহকর্মীর এই মার্জিত সমাধানটি এই দীর্ঘ পোস্টেও দেখা যায় আমি সাবক্লাসিংয়ের জন্য এই পদ্ধতির ভাগ করতে চাই যা ইন্টারফেসের পদ্ধতির অনুসরণ করে এবং তার বাইরেও।

দয়া করে সচেতন হন যে আমরা এখানে কাস্টম ব্যতিক্রমগুলি ব্যবহার করি এবং আপনি যদি নিজের ব্যতিক্রমগুলির সাথে প্রতিস্থাপন না করেন তবে এই কোডটি সংকলন করবে না।

ডকুমেন্টেশনটি বিস্তৃত এবং আমি আশা করি এটি আপনার বেশিরভাগের জন্য বোধগম্য।

প্রতিটি সাবক্ল্যাসড এনাম প্রয়োগ করার প্রয়োজন ইন্টারফেস interface

public interface Parameter {
  /**
   * Retrieve the parameters name.
   *
   * @return the name of the parameter
   */
  String getName();

  /**
   * Retrieve the parameters type.
   *
   * @return the {@link Class} according to the type of the parameter
   */
  Class<?> getType();

  /**
   * Matches the given string with this parameters value pattern (if applicable). This helps to find
   * out if the given string is a syntactically valid candidate for this parameters value.
   *
   * @param valueStr <i>optional</i> - the string to check for
   * @return <code>true</code> in case this parameter has no pattern defined or the given string
   *         matches the defined one, <code>false</code> in case <code>valueStr</code> is
   *         <code>null</code> or an existing pattern is not matched
   */
  boolean match(final String valueStr);

  /**
   * This method works as {@link #match(String)} but throws an exception if not matched.
   *
   * @param valueStr <i>optional</i> - the string to check for
   * @throws ArgumentException with code
   *           <dl>
   *           <dt>PARAM_MISSED</dt>
   *           <dd>if <code>valueStr</code> is <code>null</code></dd>
   *           <dt>PARAM_BAD</dt>
   *           <dd>if pattern is not matched</dd>
   *           </dl>
   */
  void matchEx(final String valueStr) throws ArgumentException;

  /**
   * Parses a value for this parameter from the given string. This method honors the parameters data
   * type and potentially other criteria defining a valid value (e.g. a pattern).
   *
   * @param valueStr <i>optional</i> - the string to parse the parameter value from
   * @return the parameter value according to the parameters type (see {@link #getType()}) or
   *         <code>null</code> in case <code>valueStr</code> was <code>null</code>.
   * @throws ArgumentException in case <code>valueStr</code> is not parsable as a value for this
   *           parameter.
   */
  Object parse(final String valueStr) throws ArgumentException;

  /**
   * Converts the given value to its external form as it is accepted by {@link #parse(String)}. For
   * most (ordinary) parameters this is simply a call to {@link String#valueOf(Object)}. In case the
   * parameter types {@link Object#toString()} method does not return the external form (e.g. for
   * enumerations), this method has to be implemented accordingly.
   *
   * @param value <i>mandatory</i> - the parameters value
   * @return the external form of the parameters value, never <code>null</code>
   * @throws InternalServiceException in case the given <code>value</code> does not match
   *           {@link #getType()}
   */
  String toString(final Object value) throws InternalServiceException;
}

বাস্তবায়নকারী ENUM বেস ক্লাস।

public enum Parameters implements Parameter {
  /**
   * ANY ENUM VALUE
   */
  VALUE(new ParameterImpl<String>("VALUE", String.class, "[A-Za-z]{3,10}"));

  /**
   * The parameter wrapped by this enum constant.
   */
  private Parameter param;

  /**
   * Constructor.
   *
   * @param param <i>mandatory</i> - the value for {@link #param}
   */
  private Parameters(final Parameter param) {
    this.param = param;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public String getName() {
    return this.param.getName();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public Class<?> getType() {
    return this.param.getType();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean match(final String valueStr) {
    return this.param.match(valueStr);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void matchEx(final String valueStr) {
    this.param.matchEx(valueStr);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public Object parse(final String valueStr) throws ArgumentException {
    return this.param.parse(valueStr);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public String toString(final Object value) throws InternalServiceException {
    return this.param.toString(value);
  }
}

উপ শ্রেণিবদ্ধ ENUM যা বেস বর্গ থেকে "উত্তরাধিকারসূত্রে"।

public enum ExtendedParameters implements Parameter {
  /**
   * ANY ENUM VALUE
   */
  VALUE(my.package.name.VALUE);

  /**
   * EXTENDED ENUM VALUE
   */
  EXTENDED_VALUE(new ParameterImpl<String>("EXTENDED_VALUE", String.class, "[0-9A-Za-z_.-]{1,20}"));

  /**
   * The parameter wrapped by this enum constant.
   */
  private Parameter param;

  /**
   * Constructor.
   *
   * @param param <i>mandatory</i> - the value for {@link #param}
   */
  private Parameters(final Parameter param) {
    this.param = param;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public String getName() {
    return this.param.getName();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public Class<?> getType() {
    return this.param.getType();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean match(final String valueStr) {
    return this.param.match(valueStr);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void matchEx(final String valueStr) {
    this.param.matchEx(valueStr);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public Object parse(final String valueStr) throws ArgumentException {
    return this.param.parse(valueStr);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public String toString(final Object value) throws InternalServiceException {
    return this.param.toString(value);
  }
}

পরিশেষে কিছু উপযোগ যুক্ত করতে জেনেরিক প্যারামিটার ইম্পল করুন।

public class ParameterImpl<T> implements Parameter {
  /**
   * The default pattern for numeric (integer, long) parameters.
   */
  private static final Pattern NUMBER_PATTERN = Pattern.compile("[0-9]+");

  /**
   * The default pattern for parameters of type boolean.
   */
  private static final Pattern BOOLEAN_PATTERN = Pattern.compile("0|1|true|false");

  /**
   * The name of the parameter, never <code>null</code>.
   */
  private final String name;

  /**
   * The data type of the parameter.
   */
  private final Class<T> type;

  /**
   * The validation pattern for the parameters values. This may be <code>null</code>.
   */
  private final Pattern validator;

  /**
   * Shortcut constructor without <code>validatorPattern</code>.
   *
   * @param name <i>mandatory</i> - the value for {@link #name}
   * @param type <i>mandatory</i> - the value for {@link #type}
   */
  public ParameterImpl(final String name, final Class<T> type) {
    this(name, type, null);
  }

  /**
   * Constructor.
   *
   * @param name <i>mandatory</i> - the value for {@link #name}
   * @param type <i>mandatory</i> - the value for {@link #type}
   * @param validatorPattern - <i>optional</i> - the pattern for {@link #validator}
   *          <dl>
   *          <dt style="margin-top:0.25cm;"><i>Note:</i>
   *          <dd>The default validation patterns {@link #NUMBER_PATTERN} or
   *          {@link #BOOLEAN_PATTERN} are applied accordingly.
   *          </dl>
   */
  public ParameterImpl(final String name, final Class<T> type, final String validatorPattern) {
    this.name = name;
    this.type = type;
    if (null != validatorPattern) {
      this.validator = Pattern.compile(validatorPattern);

    } else if (Integer.class == this.type || Long.class == this.type) {
      this.validator = NUMBER_PATTERN;
    } else if (Boolean.class == this.type) {
      this.validator = BOOLEAN_PATTERN;
    } else {
      this.validator = null;
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean match(final String valueStr) {
    if (null == valueStr) {
      return false;
    }
    if (null != this.validator) {
      final Matcher matcher = this.validator.matcher(valueStr);
      return matcher.matches();
    }
    return true;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void matchEx(final String valueStr) throws ArgumentException {
    if (false == this.match(valueStr)) {
      if (null == valueStr) {
        throw ArgumentException.createEx(ErrorCode.PARAM_MISSED, "The value must not be null",
            this.name);
      }
      throw ArgumentException.createEx(ErrorCode.PARAM_BAD, "The value must match the pattern: "
          + this.validator.pattern(), this.name);
    }
  }

  /**
   * Parse the parameters value from the given string value according to {@link #type}. Additional
   * the value is checked by {@link #matchEx(String)}.
   *
   * @param valueStr <i>optional</i> - the string value to parse the value from
   * @return the parsed value, may be <code>null</code>
   * @throws ArgumentException in case the parameter:
   *           <ul>
   *           <li>does not {@link #matchEx(String)} the {@link #validator}</li>
   *           <li>cannot be parsed according to {@link #type}</li>
   *           </ul>
   * @throws InternalServiceException in case the type {@link #type} cannot be handled. This is a
   *           programming error.
   */
  @Override
  public T parse(final String valueStr) throws ArgumentException, InternalServiceException {
    if (null == valueStr) {
      return null;
    }
    this.matchEx(valueStr);

    if (String.class == this.type) {
      return this.type.cast(valueStr);
    }
    if (Boolean.class == this.type) {
      return this.type.cast(Boolean.valueOf(("1".equals(valueStr)) || Boolean.valueOf(valueStr)));
    }
    try {
      if (Integer.class == this.type) {
        return this.type.cast(Integer.valueOf(valueStr));
      }
      if (Long.class == this.type) {
        return this.type.cast(Long.valueOf(valueStr));
      }
    } catch (final NumberFormatException e) {
      throw ArgumentException.createEx(ErrorCode.PARAM_BAD, "The value cannot be parsed as "
          + this.type.getSimpleName().toLowerCase() + ".", this.name);
    }

    return this.parseOther(valueStr);
  }

  /**
   * Field access for {@link #name}.
   *
   * @return the value of {@link #name}.
   */
  @Override
  public String getName() {
    return this.name;
  }

  /**
   * Field access for {@link #type}.
   *
   * @return the value of {@link #type}.
   */
  @Override
  public Class<T> getType() {
    return this.type;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public final String toString(final Object value) throws InternalServiceException {
    if (false == this.type.isAssignableFrom(value.getClass())) {
      throw new InternalServiceException(ErrorCode.PANIC,
          "Parameter.toString(): Bad type of value. Expected {0} but is {1}.", this.type.getName(),
          value.getClass().getName());
    }
    if (String.class == this.type || Integer.class == this.type || Long.class == this.type) {
      return String.valueOf(value);
    }
    if (Boolean.class == this.type) {
      return Boolean.TRUE.equals(value) ? "1" : "0";
    }

    return this.toStringOther(value);
  }

  /**
   * Parse parameter values of other (non standard types). This method is called by
   * {@link #parse(String)} in case {@link #type} is none of the supported standard types (currently
   * String, Boolean, Integer and Long). It is intended for extensions.
   * <dl>
   * <dt style="margin-top:0.25cm;"><i>Note:</i>
   * <dd>This default implementation always throws an InternalServiceException.
   * </dl>
   *
   * @param valueStr <i>mandatory</i> - the string value to parse the value from
   * @return the parsed value, may be <code>null</code>
   * @throws ArgumentException in case the parameter cannot be parsed according to {@link #type}
   * @throws InternalServiceException in case the type {@link #type} cannot be handled. This is a
   *           programming error.
   */
  protected T parseOther(final String valueStr) throws ArgumentException, InternalServiceException {
    throw new InternalServiceException(ErrorCode.PANIC,
        "ParameterImpl.parseOther(): Unsupported parameter type: " + this.type.getName());
  }

  /**
   * Convert the values of other (non standard types) to their external form. This method is called
   * by {@link #toString(Object)} in case {@link #type} is none of the supported standard types
   * (currently String, Boolean, Integer and Long). It is intended for extensions.
   * <dl>
   * <dt style="margin-top:0.25cm;"><i>Note:</i>
   * <dd>This default implementation always throws an InternalServiceException.
   * </dl>
   *
   * @param value <i>mandatory</i> - the parameters value
   * @return the external form of the parameters value, never <code>null</code>
   * @throws InternalServiceException in case the given <code>value</code> does not match
   *           {@link #getClass()}
   */
  protected String toStringOther(final Object value) throws InternalServiceException {
    throw new InternalServiceException(ErrorCode.PANIC,
        "ParameterImpl.toStringOther(): Unsupported parameter type: " + this.type.getName());
  }
}

0

আমার কোডে যাওয়ার উপায় যা নীচে থাকবে:

// enum A { a, b, c }
static final Set<Short> enumA = new LinkedHashSet<>(Arrays.asList(new Short[]{'a','b','c'}));

// enum B extends A { d }
static final Set<Short> enumB = new LinkedHashSet<>(enumA);
static {
    enumB.add((short) 'd');
    // If you have to add more elements:
    // enumB.addAll(Arrays.asList(new Short[]{ 'e', 'f', 'g', '♯', '♭' }));
}

LinkedHashSetউভয়ই সরবরাহ করে যে প্রতিটি এন্ট্রি কেবল একবার উপস্থিত রয়েছে এবং তাদের ক্রম সংরক্ষণ করা আছে। যদি অর্ডারটি কোনও ব্যাপার না, আপনি HashSetপরিবর্তে ব্যবহার করতে পারেন । নিম্নলিখিত কোডটি জাভাতে সম্ভব নয় :

for (A a : B.values()) { // enum B extends A { d }
    switch (a) {
        case a:
        case b:
        case c:
            System.out.println("Value is: " + a.toString());
        break;
        default:
            throw new IllegalStateException("This should never happen.");
    }
}

কোডটি নিম্নরূপ লেখা যেতে পারে:

for (Short a : enumB) {
    switch (a) {
        case 'a':
        case 'b':
        case 'c':
            System.out.println("Value is: " + new String(Character.toChars(a)));
        break;
        default:
            throw new IllegalStateException("This should never happen.");
    }
}

জাভা 7 থেকে আপনি এমনকি এটির সাথেও করতে পারেন String:

// enum A { BACKWARDS, FOREWARDS, STANDING }
static final Set<String> enumA = new LinkedHashSet<>(Arrays.asList(new String[] {
        "BACKWARDS", "FOREWARDS", "STANDING" }));

// enum B extends A { JUMP }
static final Set<String> enumB = new LinkedHashSet<>(enumA);
static {
    enumB.add("JUMP");
}

এনাম প্রতিস্থাপন ব্যবহার:

for (String a : enumB) {
    switch (a) {
        case "BACKWARDS":
        case "FOREWARDS":
        case "STANDING":
            System.out.println("Value is: " + a);
        break;
        default:
            throw new IllegalStateException("This should never happen.");
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.