আমি কেন একটি ইন্টারফেসে স্থির পদ্ধতিগুলি ঘোষণা করতে পারি না?


150

বিষয়টি বেশিরভাগ ক্ষেত্রে বলে - একটি ইন্টারফেসে স্থির পদ্ধতিগুলি ঘোষণা করা যায় না তার কারণ কী?

public interface ITest {
    public static String test();
}

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


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


9
এটি জাভা 8 বিটিডব্লুতে পাওয়া যাবে।
m0skit0

1
@ ভাদোরোয়েস্ট জিআইওয়াইএফ তবে যাইহোক, এখানে চেক করুন
m0skit0

2
অফিসিয়াল ডকুমেন্টেশন থেকে লিঙ্কগুলি: জাভা এসই টিউটোরিয়াল এবং জাভা ভাষার স্পেসিফিকেশন 9.2
লোগানএমজেজ

উত্তর:


85

এখানে খেলতে কয়েকটি সমস্যা রয়েছে। প্রথমটি কোনও স্থির পদ্ধতিটিকে সংজ্ঞা না দিয়ে ঘোষণার বিষয়টি। এই মধ্যে পার্থক্য

public interface Foo {
  public static int bar();
}

এবং

public interface Foo {
  public static int bar() {
    ...
  }
}

প্রথমটি কারণগুলির জন্য অসম্ভব যে কারণে এস্পো উল্লেখ করেছেন: আপনি জানেন না কোন বাস্তবায়নকারী শ্রেণিটি সঠিক সংজ্ঞা।

জাভা পারে আধুনিক মঞ্জুরি দিন; এবং প্রকৃতপক্ষে, জাভা 8 এ শুরু করে, এটি করে!


2
হ্যাঁ - এটি আদর্শগত নয় প্রযুক্তিগত। কারণটি আমি এটি চাই। যে ইন্টারফেসে কেবল একটি "স্থিতিশীল" প্রয়োগকরণ পদ্ধতি থাকতে পারে যা কেবল ইন্টারফেসে অন্যান্য "ইন্টারফেস" পদ্ধতিগুলি উল্লেখ করে যা ক্লাস প্রয়োগ করে সহজেই পুনরায় ব্যবহার করা যায়। তবে কেউ একটি ইন্টারফেসে একটি স্ট্যাটিক ক্লাস ঘোষণা করতে পারে যাতে মাইইনটারফেস.আইপল.ড.আইটি (মাইইনটারফেস i, অবজেক্ট [] আর্কস) এর মতো এমন কিছু সেখানে থাকতে পারে {...}
পিটার্ক

9
জাভা 8 যেহেতু, আপনি staticএকটি পদ্ধতিতে সংজ্ঞা দিতে পারেন interface। পদ্ধতিগুলি অবশ্যই হবে public
অলিভিয়ার গ্রাগোয়ার

4
@ অলিভিগ্রগ্রোয়ার ... এবং তাদের উত্তরাধিকার সূত্রে প্রাপ্ত নয়, যা মূল।
উইলিয়াম এফ জেমসন

1
উত্তম উত্তর, যদিও "আনুমানিক সমতুল্য" আরএফএলএমএও এক্সডি আমি এটিকে "কিছুটা সাদৃশ্যযুক্ত" এর মতো করে রেখেছি।
টিমো

44

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


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

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

4
@ টোটোফিল: ইন্টারফেসগুলি অবশ্যই একটি একক জাভা-ফাইলে থাকতে হবে না, তবে সংকলনের পরে এটির নিজস্ব শ্রেণি-ফাইল থাকবে। এটাই আমি লিখেছি।
মেনেমেন্ট 16

18

আমি আপনার প্রশ্নের উত্তর একটি উদাহরণ দিয়ে দেব। ধরুন আমাদের স্ট্যাটিক মেথড অ্যাড যুক্ত ম্যাথ ক্লাস ছিল। আপনি এই পদ্ধতিটিকে এভাবে কল করবেন:

Math.add(2, 3);

যদি ম্যাথটি কোনও শ্রেণীর পরিবর্তে একটি ইন্টারফেস হত তবে এর কোনও নির্ধারিত ফাংশন থাকতে পারে না। যেমন, ম্যাথ.এডিডি (2, 3) এর মতো কিছু বলার অর্থ নেই।


11

কারণটি নকশা-নীতিতে অন্তর্ভুক্ত, যে জাভা একাধিক উত্তরাধিকারের অনুমতি দেয় না। একাধিক উত্তরাধিকার নিয়ে সমস্যা নিম্নলিখিত উদাহরণ দ্বারা চিত্রিত করা যেতে পারে:

public class A {
   public method x() {...}
}
public class B {
   public method x() {...}
}
public class C extends A, B { ... }

এখন আপনি Cx () কল করলে কী হবে? এক্স () বা বিএক্স () কার্যকর হবে? একাধিক উত্তরাধিকারের প্রতিটি ভাষাতেই এই সমস্যাটি সমাধান করতে হবে।

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

public interface A {
   public static method x() {...}
}
public interface B {
   public static method x() {...}
}
public class C implements A, B { ... }

এখানে একই সমস্যা, আপনি Cx () কল করলে কী হবে?


ডাউনভোটের কোনও কারণ? একটি ব্যাখ্যা মন্তব্য দুর্দান্ত হবে।
মেনেমেন্ট 16

আমি ডাউনভোটার নই, তবে এটি অ স্থির পদ্ধতিগুলির জন্যও বৈধ নয়?
নওফাল

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

ঠিক আছে, বাস্তবায়ন অংশ ভুলে যান। প্রশ্ন আমরা কেন ঘোষিত না। হ্যাঁ সংকলক অভিযোগ করবে এবং কেন এটি প্রশ্ন। যা আমি মনে করি না আপনি উত্তর দিয়েছেন।
নওফাল

1
ইন্টারফেস Aধারণ int x(int z);ও ইন্টারফেস ধারণের চেয়ে পরিস্থিতি কীভাবে খারাপ হতে Bপারে string x(int x);? x(3)ইন্টারফেস সি এর অর্থ কী ?
সুপারক্যাট

7

স্থির পদ্ধতি উদাহরণ পদ্ধতি নয়। কোনও উদাহরণের প্রসঙ্গ নেই, সুতরাং এটি ইন্টারফেস থেকে বাস্তবায়নের জন্য কিছুটা বোধগম্য নয়।


5

এখন জাভা 8 আমাদের ইন্টারফেসে স্ট্যাটিক পদ্ধতিগুলিও সংজ্ঞায়িত করতে দেয়।

interface X {
    static void foo() {
       System.out.println("foo");
    }
}

class Y implements X {
    //...
}

public class Z {
   public static void main(String[] args) {
      X.foo();
      // Y.foo(); // won't compile because foo() is a Static Method of X and not Y
   }
}

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


4

আপনার প্রশ্নের এখানে একটি খুব সুন্দর এবং সংক্ষিপ্ত উত্তর আছে । (এটি আমাকে ব্যাখ্যা করার মতো সুন্দর সোজা উপায় হিসাবে আঘাত করেছে যে আমি এখান থেকে এটি লিঙ্ক করতে চাই))


এটি প্রশ্নের উত্তর নয়, সর্বোপরি এটি একটি মন্তব্য হওয়া উচিত।
কিউবজকি

3

দেখে মনে হচ্ছে জাভা 8 এ ইন্টারফেসের স্থির পদ্ধতিটি সমর্থিত হতে পারে , আমার সমাধানটি কেবল তাদের অভ্যন্তরীণ শ্রেণিতে সংজ্ঞায়িত করছে।

interface Foo {
    // ...
    class fn {
        public static void func1(...) {
            // ...
        }
    }
}

একই কৌশলটি টীকাতেও ব্যবহার করা যেতে পারে:

public @interface Foo {
    String value();

    class fn {
        public static String getValue(Object obj) {
            Foo foo = obj.getClass().getAnnotation(Foo.class);
            return foo == null ? null : foo.value();
        }
    }
}

অভ্যন্তরীণ বর্গটি সর্বদা Interface.fn...পরিবর্তে আকারে অ্যাক্সেস করা উচিত Class.fn..., তারপরে, আপনি অস্পষ্ট সমস্যা থেকে মুক্তি পেতে পারেন।


2

পলিমারফিজমের জন্য একটি ইন্টারফেস ব্যবহৃত হয়, যা প্রকারের নয়, অবজেক্টের ক্ষেত্রে প্রযোজ্য। অতএব (যেমন ইতিমধ্যে উল্লিখিত) এটি স্ট্যাটিক ইন্টারফেস সদস্য থাকার কোন মানে হয় না।


কিছু প্রতিফলিত প্রসঙ্গে যদিও প্রায় বুদ্ধিমান মনে হয়
ক্রাঙ্কার

1

জাভা 8 আপনার বিশ্বব্যাপী ইন্টারফেসে স্থির পদ্ধতি থাকতে পারে তবে এটি আপনাকে বাস্তবায়নের জন্য বাধ্য করে।

public interface StaticMethodInterface {
public static int testStaticMethod() {
    return 0;
}

/**
 * Illegal combination of modifiers for the interface method
 * testStaticMethod; only one of abstract, default, or static permitted
 * 
 * @param i
 * @return
 */
// public static abstract int testStaticMethod(float i);

default int testNonStaticMethod() {
    return 1;
}

/**
 * Without implementation.
 * 
 * @param i
 * @return
 */
int testNonStaticMethod(float i);

}


0

সংশোধকদের অবৈধ সংমিশ্রণ: স্থির এবং বিমূর্ত

যদি কোনও শ্রেণির সদস্যকে স্থিতিশীল হিসাবে ঘোষণা করা হয়, তবে এটি তার শ্রেণীর নামের সাথে ব্যবহার করা যেতে পারে যা কোনও বস্তু তৈরি না করে that শ্রেণীর মধ্যে সীমাবদ্ধ।

যদি কোনও শ্রেণির সদস্যকে বিমূর্ত হিসাবে ঘোষণা করা হয়, আপনাকে ক্লাসটিকে বিমূর্ত হিসাবে ঘোষণা করতে হবে এবং আপনাকে তার উত্তরাধিকারসূত্রে প্রাপ্ত শ্রেণীর (সাব-ক্লাস) বিমূর্ত সদস্যের প্রয়োগ সরবরাহ করতে হবে।

আপনাকে সাব-ক্লাসের এমন একটি শ্রেণীর বিমূর্ত সদস্যকে একটি প্রয়োগকরণ সরবরাহ করতে হবে যেখানে আপনি স্থিতিশীল পদ্ধতির আচরণ পরিবর্তন করতে চলেছেন, এটি অ্যাবস্ট্রাক্ট হিসাবেও ঘোষণা করা হয়েছে যা বেস শ্রেণীর মধ্যে সীমাবদ্ধ যা সঠিক নয় is


কিভাবে এই প্রশ্নের উত্তর দেয়? ক্লাস সম্পর্কে লেখার সময় ওপি ইন্টারফেস সম্পর্কে জিজ্ঞাসা করেছিল।
ভাগ্যবান

0

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


স্থির পদ্ধতি সর্বদা উত্তরাধিকার সূত্রে প্রাপ্ত হয় তবে সেগুলি ওভাররাইড করা যায় না।
আক্কি

0

সঙ্গে জাভা 8 , ইন্টারফেসগুলি এখন স্ট্যাটিক পদ্ধতি থাকতে পারে।

উদাহরণস্বরূপ, তুলনাকারীর একটি স্থিতিশীল প্রাকৃতিক অর্ডার () পদ্ধতি রয়েছে।

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


ঈশ্বর! আমাদের কাছে একটি গুরুতর প্রোগ্রামার রয়েছে (এবং আমি, মন্তব্যকারী) 10 বছরের পুরানো প্রশ্নের উত্তর দিচ্ছি (এবং আমি, মন্তব্য করছি)।
মোহাম্মদ আনিস এ

আমি তারিখটি লক্ষ্য করিনি :)
ইশারা

হা হা! সমস্যা নেই!
মোহাম্মদ আনিস এ

-2

সম্ভবত একটি কোড উদাহরণ সাহায্য করবে, আমি সি # ব্যবহার করছি, তবে আপনার পাশাপাশি অনুসরণ করতে সক্ষম হওয়া উচিত।

আইডেয়েবল নামে আমাদের একটি ইন্টারফেস রয়েছে তা ভান করতে দেয়

public interface IPayable
{
    public Pay(double amount);
}

এখন, আমাদের দুটি কংক্রিট ক্লাস রয়েছে যা এই ইন্টারফেসটি প্রয়োগ করে:

public class BusinessAccount : IPayable
{
    public void Pay(double amount)
    {
        //Logic
    }
}

public class CustomerAccount : IPayable
{
    public void Pay(double amount)
    {
        //Logic
    }
}

এখন, আমাদের কাছে বিভিন্ন অ্যাকাউন্টের সংকলন রয়েছে তা ভান করা যাক, এটি করার জন্য আমরা আইপিএল টাইপের জেনেরিক তালিকা ব্যবহার করব

List<IPayable> accountsToPay = new List<IPayable>();
accountsToPay.add(new CustomerAccount());
accountsToPay.add(new BusinessAccount());

এখন, আমরা এই সমস্ত অ্যাকাউন্টগুলিতে .00 50.00 দিতে চাই:

foreach (IPayable account in accountsToPay)
{
    account.Pay(50.00);
}

সুতরাং এখন আপনি কিভাবে ইন্টারফেস অবিশ্বাস্যভাবে দরকারী।

এগুলি কেবল তাত্ক্ষণিক বস্তুগুলিতে ব্যবহৃত হয়। স্থির শ্রেণিতে নয় Not

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


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