জাভা ডিফল্ট পদ্ধতি ব্যবহার


13

কয়েক দশক ধরে এটা ক্ষেত্রে যে ইন্টারফেসগুলি ছিল হয়েছে শুধুমাত্র শুধুমাত্র (শুধুমাত্র) মেথড স্বাক্ষর উল্লেখ জন্য। আমাদের বলা হয়েছিল যে এটি ছিল "জিনিসগুলি করার সঠিক উপায় ™"।

তারপরে জাভা 8 বেরিয়ে এসে বলল:

ভাল, এর, আহ, এখন আপনি ডিফল্ট পদ্ধতিগুলি নির্ধারণ করতে পারেন। চালাতে হবে, বাই।

আমি কীভাবে অভিজ্ঞ জাভা বিকাশকারী এবং যারা সম্প্রতি এটি শুরু করেছিলেন (গত কয়েক বছর) দুজনেই এটি হজম করছেন সে সম্পর্কে আমি আগ্রহী। আমি কীভাবে জাভা গোঁড়া ও অনুশীলনের সাথে এটি খাপ খায় তা নিয়েও আমি ভাবছি।

আমি কিছু পরীক্ষামূলক কোড তৈরি করছি এবং আমি কিছু সংশোধন করার সময়, আমি এমন একটি ইন্টারফেস দিয়ে শেষ করেছি যা কেবল একটি স্ট্যান্ডার্ড ইন্টারফেস (Iteable) প্রসারিত করে এবং দুটি ডিফল্ট পদ্ধতি যুক্ত করে। এবং আমি সত্যবাদী হব, আমি এটি সম্পর্কে বেশ খারাপ লাগছে।

আমি জানি এটি সামান্য উন্মুক্ত রয়েছে তবে এখন জাভা 8 এর বাস্তব প্রকল্পগুলিতে ব্যবহার করার জন্য কিছুটা সময় হয়ে গেছে, তখনও কি ডিফল্ট পদ্ধতি ব্যবহারের জন্য কোনও গোঁড়ামি রয়েছে? তারা যখন আলোচিত হয় তখন আমি সাধারণত যেটি দেখি তা হ'ল বিদ্যমান গ্রাহকগণকে ভঙ্গ না করে কীভাবে কোনও ইন্টারফেসে নতুন পদ্ধতি যুক্ত করা যায় about তবে শুরু থেকে এটি ব্যবহার সম্পর্কে কী আমি উপরে উদাহরণ হিসাবে উদাহরণস্বরূপ। তাদের ইন্টারফেসে বাস্তবায়ন সরবরাহ করে কেউ কি কোনও সমস্যা নিয়েছে?


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

1
আমি মনে করি যে তারা ডিফল্ট পদ্ধতিগুলি যুক্ত করার কারণটি মূলত এটি যাতে সম্পূর্ণ ভিন্ন ইন্টারফেস না করে সংগ্রহের ইন্টারফেসগুলি প্রসারিত করতে পারে
জাস্টিন

1
@ জাস্টিন: java.util.function.Functionব্র্যান্ড-নতুন ইন্টারফেসে ডিফল্ট পদ্ধতি ব্যবহারের জন্য দেখুন ।
জার্গ ডব্লু মিট্টাগ

@ জাস্টিন আমার অনুমান যে এই প্রধান ড্রাইভার ছিল। আমার সত্যিকার অর্থে প্রক্রিয়াটির দিকে মনোযোগ দেওয়া শুরু করা উচিত কারণ তারা সত্যিকার অর্থে পরিবর্তন শুরু করে।
জিমি জেমস 15

উত্তর:


12

দুর্দান্ত ব্যবহারের ক্ষেত্রে আমি যাকে "লিভার" ইন্টারফেস বলে থাকি: ইন্টারফেসগুলিতে কেবল সংখ্যার বিমূর্ত পদ্ধতি রয়েছে (আদর্শ 1), তবে প্রচুর পরিমাণে "লিভারেজ" সরবরাহ করে যাতে তারা আপনাকে প্রচুর কার্যকারিতা সরবরাহ করে: আপনি কেবল আপনার ক্লাসে 1 টি পদ্ধতি প্রয়োগ করতে হবে তবে "বিনামূল্যে জন্য" প্রচুর অন্যান্য পদ্ধতি পান। একটি একক বিমূর্ত সঙ্গে, একটি সংগ্রহ ইন্টারফেসের চিন্তা করুন, উদাহরণস্বরূপ foreachপদ্ধতি এবং defaultপদ্ধতি পছন্দ map, fold, reduce, filter, partition, groupBy, sort, sortBy, ইত্যাদি

এখানে উদাহরণ তুলে ধরা হলো। এর সাথে শুরু করা যাক java.util.function.Function<T, R>। এটিতে একটি একক বিমূর্ত পদ্ধতি রয়েছে R apply<T>। এবং এর দুটি ডিফল্ট পদ্ধতি রয়েছে যা আপনাকে আগে বা পরে দুটি ভিন্ন উপায়ে ফাংশনটি রচনা করতে দেয়। এই উভয় রচনা পদ্ধতি কার্যকরভাবে ব্যবহার করে প্রয়োগ করা হয়apply :

default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
    return (V v) -> apply(before.apply(v));
}

default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
    return (T t) -> after.apply(apply(t));
}

আপনি তুলনামূলক অবজেক্টগুলির জন্য একটি ইন্টারফেসও তৈরি করতে পারেন, এরকম কিছু:

interface MyComparable<T extends MyComparable<T>> {
  int compareTo(T other);

  default boolean lessThanOrEqual(T other) {
    return compareTo(other) <= 0;
  }

  default boolean lessThan(T other) {
    return compareTo(other) < 0;
  }

  default boolean greaterThanOrEqual(T other) {
    return compareTo(other) >= 0;
  }

  default boolean greaterThan(T other) {
    return compareTo(other) > 0;
  }

  default boolean isBetween(T min, T max) {
    return greaterThanOrEqual(min) && lessThanOrEqual(max);
  }

  default T clamp(T min, T max) {
    if (lessThan(   min)) return min;
    if (greaterThan(max)) return max;
                          return (T)this;
  }
}

class CaseInsensitiveString implements MyComparable<CaseInsensitiveString> {
  CaseInsensitiveString(String s) { this.s = s; }
  private String s;

  @Override public int compareTo(CaseInsensitiveString other) {
    return s.toLowerCase().compareTo(other.s.toLowerCase());
  }
}

বা একটি অতি সরলিকৃত সংগ্রহের কাঠামো, যেখানে সমস্ত সংগ্রহ অপারেশনগুলি ফিরে আসবে Collection, আসল প্রকারটি নির্বিশেষে:

interface MyCollection<T> {
  void forEach(java.util.function.Consumer<? super T> f);

  default <R> java.util.Collection<R> map(java.util.function.Function<? super T, ? extends R> f) {
    java.util.Collection<R> l = new java.util.ArrayList();
    forEach(el -> l.add(f.apply(el)));
    return l;
  }
}

class MyArray<T> implements MyCollection<T> {
  private T[] array;

  MyArray(T[] array) { this.array = array; }

  @Override public void forEach(java.util.function.Consumer<? super T> f) {
    for (T el : array) f.accept(el);
  }

  @Override public String toString() {
    StringBuilder sb = new StringBuilder("(");
    map(el -> el.toString()).forEach(s -> { sb.append(s); sb.append(", "); } );
    sb.replace(sb.length() - 2, sb.length(), ")");
    return sb.toString();
  }

  public static void main(String... args) {
    MyArray<Integer> array = new MyArray<>(new Integer[] {1, 2, 3, 4});
    System.out.println(array);
    // (1, 2, 3, 4)
  }
}

ল্যাম্বডাসের সাথে এটি মিশ্রণে খুব আকর্ষণীয় হয়ে ওঠে, কারণ এই জাতীয় "লিভার" ইন্টারফেস ল্যাম্বডা দ্বারা প্রয়োগ করা যেতে পারে (এটি একটি এসএএম ইন্টারফেস)।

এটি একই ব্যবহারের ক্ষেত্রে সি'এর জন্য এক্সটেনশন পদ্ধতিগুলি যুক্ত করা হয়েছিল, তবে ডিফল্ট পদ্ধতিগুলির একটি স্বতন্ত্র সুবিধা রয়েছে: সেগুলি "যথাযথ" উদাহরণ পদ্ধতি, যার অর্থ তাদের ইন্টারফেসের ব্যক্তিগত প্রয়োগের বিশদটিতে অ্যাক্সেস রয়েছে ( privateইন্টারফেস পদ্ধতিগুলি আসছে) জাভা 9) এ, যেখানে এক্সটেনশন পদ্ধতিগুলি কেবল স্থির পদ্ধতির জন্য সিনট্যাকটিক চিনি।

জাভা যদি কখনও ইন্টারফেস ইনজেকশন পায় তবে এটি টাইপ-সেফ, স্কোপড, মডুলার বানর-প্যাচিংয়ের অনুমতি দেবে। এটি জেভিএম-তে ভাষা প্রয়োগকারীদের জন্য অত্যন্ত আকর্ষণীয় হবে: এই মুহুর্তে, উদাহরণস্বরূপ, জে রবি হয় জাভা ক্লাস থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হয় বা তাদের অতিরিক্ত রুবি শব্দার্থবিজ্ঞান সরবরাহ করতে জড় করে তবে আদর্শিকভাবে তারা একই ক্লাসটি ব্যবহার করতে চায়। ইন্টারফেস ইনজেকশন পদ্ধতি এবং ডিফল্ট, তারা উদ্বুদ্ধ পারে যেমন একটি RubyObjectইন্টারফেসে java.lang.Object, যাতে একটি জাভা Objectএবং একটি রুবি Objectহয় সঠিক একই জিনিস


1
আমি এটি পুরোপুরি অনুসরণ করি না। ইন্টারফেসের ডিফল্ট পদ্ধতিটি ইন্টারফেসের অন্যান্য পদ্ধতির ক্ষেত্রে বা অবজেক্টে সংজ্ঞায়িত পদ্ধতিগুলির সাথে সংজ্ঞায়িত করতে হয়। আপনি কীভাবে একটি ডিফল্ট পদ্ধতিতে অর্থপূর্ণ একক পদ্ধতি ইন্টারফেস তৈরি করতে পারেন তার উদাহরণ দিতে পারেন? আপনার প্রদর্শনের জন্য জাভা 9 সিনট্যাক্সের প্রয়োজন হলে এটি ঠিক আছে।
জিমি জেমস 20

উদাহরণস্বরূপ: একটি Comparableএকটি বিমূর্ত সঙ্গে ইন্টারফেস compareToপদ্ধতি, এবং ডিফল্ট lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual, isBetween, এবং clampপদ্ধতি, সব দিক থেকে বাস্তবায়িত compareTo। অথবা, কেবলমাত্র দেখুন java.util.function.Function: এটিতে একটি বিমূর্ত applyপদ্ধতি এবং দুটি ডিফল্ট রচনা পদ্ধতি রয়েছে, উভয়ই শর্তাবলী প্রয়োগ করা হয়েছে apply। আমি একটি Collectionইন্টারফেসের উদাহরণ দেওয়ার চেষ্টা করেছি , তবে এগুলি সমস্তই টাইপ-নিরাপদ হওয়া জবাবদিহি এবং এই উত্তরের জন্য দীর্ঘ - আমি নন-টাইপ-নিরাপদ, নন-টাইপ-সংরক্ষণযোগ্য সংস্করণকে একটি শট দেওয়ার চেষ্টা করব। সাথে থাকুন.
জার্গ ডব্লু মিট্টাগ

3
উদাহরণগুলি সাহায্য করে। ধন্যবাদ। আপনি একক পদ্ধতি ইন্টারফেস বলতে কী বোঝাতে চেয়েছি তা ভুল বুঝেছি।
জিমি জেমস 16

ডিফল্ট পদ্ধতিগুলির অর্থ কী যে একক বিমূর্ত পদ্ধতি ইন্টারফেসের আর কোনও একক পদ্ধতি ইন্টারফেস হতে হবে না ;-)
জার্গ ডব্লু মিত্তাগ ২

আমি এটি সম্পর্কে চিন্তাভাবনা করছিলাম এবং এটি আমার কাছে ঘটেছিল যে অ্যাবস্ট্রাক্ট কালেকশন এবং অ্যাবস্ট্রাকলিস্ট মূলত আপনি এখানে যে বিষয়ে কথা বলছেন তা হ'ল (1 এর পরিবর্তে 2 পদ্ধতি তবে আমি তা অত্যন্ত গুরুত্বপূর্ণ বলে মনে করি না।) যদি এগুলি ডিফল্ট পদ্ধতিগুলির সাথে ইন্টারফেস হিসাবে পুনরায় আবৃত্তি করা হত তবে এটি হবে আকার যুক্ত করে কোনও সংগ্রহকে পুনরাবৃত্তিযোগ্য করে তুলতে খুব সহজ হোন এবং যে কোনও কিছু থেকে একটি তালিকা তৈরি করাও যদি আপনি সূচকটি বুঝতে পারেন এবং আকারটি জানতে পারেন তবে এটি একটি স্ন্যাপ।
জিমি জেমস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.