জাভাতে প্রশ্নটি আমি কেন একটি বিমূর্ত স্থির পদ্ধতি সংজ্ঞায়িত করতে পারি না? উদাহরণ স্বরূপ
abstract class foo {
abstract void bar( ); // <-- this is ok
abstract static void bar2(); //<-- this isn't why?
}
জাভাতে প্রশ্নটি আমি কেন একটি বিমূর্ত স্থির পদ্ধতি সংজ্ঞায়িত করতে পারি না? উদাহরণ স্বরূপ
abstract class foo {
abstract void bar( ); // <-- this is ok
abstract static void bar2(); //<-- this isn't why?
}
উত্তর:
কারণ "বিমূর্ত" এর অর্থ: "কোনও কার্যকারিতা কার্যকর করে না", এবং "স্ট্যাটিক" এর অর্থ: "আপনার কোনও বস্তুর উদাহরণ না থাকলেও কার্যকারিতা রয়েছে"। এবং এটি একটি যৌক্তিক দ্বন্দ্ব।
abstract static
নিখুঁত ধারণা তৈরি করতে পারে। এটি শ্রেণি অবজেক্টের নিজেই একটি পদ্ধতি হতে পারে যা সাবক্লাস অবজেক্টগুলি প্রয়োগ করতে হবে। অবশ্যই ভাষা সম্পর্কে আমার আঁকড়ে থাকা সত্ত্বেও যেভাবে বিষয়গুলির উত্তর আপনার পক্ষে দাঁড়িয়েছে তা সঠিক।
abstract static
: একটি ফাংশন হল x যে "উপশ্রেণী বাস্তবায়িত" করতে পারবে না একই সময়ে "শ্রেণী মৃত্যুদন্ড কার্যকর" করা - শুধুমাত্র উপর উপশ্রেণী । যেখানে এটি আর বিমূর্ত হয় না।
static
"খালি নয়" - এর অর্থ জাভা স্থির পদ্ধতিগুলি বিমূর্ত হতে দেয় না এটি কেবলমাত্র একটি পরিণতি। এর অর্থ "ক্লাসে কল করা"। (এর অর্থ " কেবলমাত্র ক্লাসে কলযোগ্য" হওয়া উচিত তবে এটি অন্য সমস্যা abstract static
। কিছু পদ্ধতি কেবল উদাহরণ পদ্ধতি হিসাবে বোঝায় না। দুর্ভাগ্যক্রমে জাভা আপনাকে কোনও বিমূর্ত বেস ক্লাস (বা একটি ইন্টারফেস) তৈরি করার সময় নির্দিষ্ট করতে দেয় না।
দরিদ্র ভাষার নকশা। কেবলমাত্র এটি বিমূর্ত পদ্ধতিটি ব্যবহারের জন্য উদাহরণ তৈরি করার চেয়ে সরাসরি কোনও স্থিতিশীল বিমূর্ত পদ্ধতি কল করা আরও কার্যকর হবে। বিশেষত সত্য যখন এনব্র্যাক্ট ক্লাসটি এনামের প্রসারিত করতে অক্ষমতার জন্য একটি কার্যকরী হিসাবে ব্যবহার করা হয় যা এটি অন্য একটি দুর্বল নকশার উদাহরণ। আশা করি তারা পরবর্তী প্রকাশে এই সীমাবদ্ধতাগুলি সমাধান করবে।
static
ইতিমধ্যে লঙ্ঘন ....
আপনি একটি স্থিতিশীল পদ্ধতি ওভাররাইড করতে পারবেন না, সুতরাং এটি বিমূর্ত করা অর্থহীন হবে। তদুপরি, একটি বিমূর্ত শ্রেণীর একটি স্থিতিশীল পদ্ধতি সেই শ্রেণীর অন্তর্ভুক্ত হবে, এবং ওভাররাইডিং ক্লাস নয়, তাই যাইহোক ব্যবহার করা যায়নি।
abstract
একটি পদ্ধতি টীকা ইঙ্গিত করে যে পদ্ধতি উপশ্রেণী মধ্যে ওভাররাইড করা আবশ্যক।
জাভা, একটি static
সদস্য (পদ্ধতি বা ক্ষেত্র) উপশ্রেণী দ্বারা অধিলিখিত হতে পারে না (এই অগত্যা সত্য নয় অন্যান্য অবজেক্ট ওরিয়েন্টেড ভাষায়, স্মলটক দেখুন।) একজন static
সদস্য হতে পারে লুকানো , কিন্তু যে চেয়ে মৌলিকভাবে ভিন্ন উপেক্ষিত ।
যেহেতু স্থিতিশীল সদস্যগুলিকে সাবক্লাসে ওভাররাইড করা যায় না, তাই abstract
টীকা তাদের জন্য প্রয়োগ করা যায় না।
অন্যদিকে - অন্য ভাষা যেমন স্থায়ী উত্তরাধিকারের মতো স্থির উত্তরাধিকারকে সমর্থন করে। বাক্য বিন্যাসের দৃষ্টিভঙ্গি থেকে, সেই ভাষাগুলির সাধারণত বিবৃতিতে শ্রেণীর নাম অন্তর্ভুক্ত করা প্রয়োজন। উদাহরণস্বরূপ, জাভাতে, ধরে নেওয়া যে আপনি ক্লাসএ তে কোড লিখছেন, এগুলি সমতুল্য বিবৃতি (যদি পদ্ধতিএ () একটি স্থির পদ্ধতি, এবং একই স্বাক্ষরের সাথে কোনও উদাহরণ পদ্ধতি নেই):
ClassA.methodA();
এবং
methodA();
স্মলটাল্কে, শ্রেণীর নামটি alচ্ছিক নয়, সুতরাং বাক্য গঠনটি (নোট করুন যে স্মলটালক "বিষয়" এবং "ক্রিয়া" পৃথক করতে ব্যবহার করে না, পরিবর্তে এটি রাষ্ট্রীয় পরিসমাপ্তি হিসাবে ব্যবহার করে):
ClassA methodA.
শ্রেণীর নাম সর্বদা প্রয়োজনীয় বলে, পদ্ধতির সঠিক "সংস্করণ" সর্বদা শ্রেণিবিন্যাসকে অনুসরণ করে নির্ধারণ করা যেতে পারে। এটির মূল্যের জন্য, আমি মাঝে মধ্যে static
উত্তরাধিকার মিস করি এবং জাভাতে স্থির উত্তরাধিকারের অভাবের দ্বারা আমি প্রথম যখন এটি শুরু করেছি bit অতিরিক্তভাবে, স্মলটাল্ক হাঁস-টাইপযুক্ত (এবং এটি প্রোগ্রাম দ্বারা চুক্তি সমর্থন করে না)) সুতরাং abstract
শ্রেণীর সদস্যদের জন্য এটির কোনও পরিবর্তনকারী নেই ।
আমি একই প্রশ্ন জিজ্ঞাসা, এখানে কেন
যেহেতু বিমূর্ত শ্রেণি বলছে, এটি বাস্তবায়ন দেয় না এবং সাবক্লাসটি এটি দেওয়ার অনুমতি দেয় না
সুতরাং সাবক্লাসকে সুপারক্লাসের পদ্ধতিগুলি ওভাররাইড করতে হবে,
নিয়ম সংখ্যা 1 - একটি স্থিতিশীল পদ্ধতি ওভাররাইড করা যায় না
স্থিতিশীল সদস্য এবং পদ্ধতিগুলি হ'ল সংঘবদ্ধ সময় উপাদান, এজন্য স্থির পদ্ধতিগুলির ওভারলোডিং (কমপ্লাই টাইম পলিমারফিজম) এর পরিবর্তে ওভাররাইডিং (রানটাইম পলিমারফিজম) অনুমোদিত
সুতরাং, তারা বিমূর্ত হতে পারে।
মত জিনিস আছে বিমূর্ত স্ট্যাটিক <--- জাভা ইউনিভার্স মঞ্জুরিপ্রাপ্ত নয়
abstract static
দেখুন স্থিতিশীল টাইপ-চেকিং অবশ্যই সম্ভব । জাভা স্থির পদ্ধতিগুলিকে ওভাররাইড করার অনুমতি দেয় না এর আসল কারণ হ'ল জাভা স্থির পদ্ধতিগুলিকে ওভাররাইড করার অনুমতি দেয় না।
foo(String)
তেমনটি নয় foo(Integer)
- এটাই সব।
এটি একটি ভয়াবহ ভাষার নকশা এবং কেন এটি সম্ভব হতে পারে তা নিয়ে আসলেই কোনও কারণ নেই।
আসলে, এখানে কিভাবে এটি একটি বাস্তবায়ন করতে পারেন মধ্যে সম্পন্ন করা জাভা :
public class Main {
public static void main(String[] args) {
// This is done once in your application, usually at startup
Request.setRequest(new RequestImplementationOther());
Request.doSomething();
}
public static final class RequestImplementationDefault extends Request {
@Override
void doSomethingImpl() {
System.out.println("I am doing something AAAAAA");
}
}
public static final class RequestImplementaionOther extends Request {
@Override
void doSomethingImpl() {
System.out.println("I am doing something BBBBBB");
}
}
// Static methods in here can be overriden
public static abstract class Request {
abstract void doSomethingImpl();
// Static method
public static void doSomething() {
getRequest().doSomethingImpl();
}
private static Request request;
private static Request getRequest() {
// If setRequest is never called prior, it will default to a default implementation. Of course you could ignore that too.
if ( request == null ) {
return request = new RequestImplementationDefault();
}
return request;
}
public static Request setRequest(Request r){
return request = r;
}
}
}
================= নীচের পুরানো উদাহরণ ===================
GetRequest সন্ধান করুন এবং getRequestImpl ... setInstance কল করার আগে বাস্তবায়ন পরিবর্তন করতে বলা যেতে পারে।
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
* @author Mo. Joseph
* @date 16 mar 2012
**/
public abstract class Core {
// ---------------------------------------------------------------
private static Core singleton;
private static Core getInstance() {
if ( singleton == null )
setInstance( new Core.CoreDefaultImpl() ); // See bottom for CoreDefaultImpl
return singleton;
}
public static void setInstance(Core core) {
Core.singleton = core;
}
// ---------------------------------------------------------------
// Static public method
public static HttpServletRequest getRequest() {
return getInstance().getRequestImpl();
}
// A new implementation would override this one and call setInstance above with that implementation instance
protected abstract HttpServletRequest getRequestImpl();
// ============================ CLASSES =================================
// ======================================================================
// == Two example implementations, to alter getRequest() call behaviour
// == getInstance() have to be called in all static methods for this to work
// == static method getRequest is altered through implementation of getRequestImpl
// ======================================================================
/** Static inner class CoreDefaultImpl */
public static class CoreDefaultImpl extends Core {
protected HttpServletRequest getRequestImpl() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
}
/** Static inner class CoreTestImpl : Alternative implementation */
public static class CoreTestImpl extends Core {
protected HttpServletRequest getRequestImpl() {
return new MockedRequest();
}
}
}
অনুসরণ হিসাবে ব্যবহৃত:
static {
Core.setSingleton(new Core.CoreDefaultImpl());
// Or
Core.setSingleton(new Core.CoreTestImpl());
// Later in the application you might use
Core.getRequest();
}
abstract static
প্রশ্নে জিজ্ঞাসা করা হয়নি আপনি কোথায় কোনও পদ্ধতির উদাহরণ দিয়েছেন এবং আপনি জাভাতে সাহসী হতে পারেন তা লিখে গেছেন । এটি সম্পূর্ণ বিভ্রান্তিকর।
একটি বিমূর্ত পদ্ধতিটি কেবলমাত্র তাই সংজ্ঞায়িত করা হয় যাতে এটি একটি সাবক্লাসে ওভাররাইড করা যায়। তবে স্থির পদ্ধতিগুলি ওভাররাইড করা যায় না। অতএব, এটি একটি বিমূর্ত, স্থির পদ্ধতি থাকা একটি সংকলন-সময় ত্রুটি।
এখন পরের প্রশ্নটি হল স্ট্যাটিক পদ্ধতিগুলি কেন ওভাররাইড করা যায় না ??
এটি কারণ স্থির পদ্ধতিগুলি একটি নির্দিষ্ট শ্রেণীর অন্তর্গত এবং তার উদাহরণের সাথে নয়। আপনি যদি কোনও স্ট্যাটিক পদ্ধতি ওভাররাইড করার চেষ্টা করেন তবে আপনি কোনও সংকলন বা রানটাইম ত্রুটি পাবেন না তবে সংকলক কেবল সুপারক্লাসের স্থির পদ্ধতিটি আড়াল করবে।
একটি স্থিতিশীল পদ্ধতি, সংজ্ঞা অনুসারে, এটি জানার দরকার নেই this
। সুতরাং, এটি কোনও ভার্চুয়াল পদ্ধতি হতে পারে না (এটি উপলব্ধ গতিশীল সাবক্লাসের তথ্য অনুযায়ী ওভারলোড হয় this
); পরিবর্তে, একটি স্ট্যাটিক পদ্ধতি ওভারলোড সম্পূর্ণরূপে সংকলনের সময় উপলব্ধ তথ্যের উপর ভিত্তি করে থাকে (এর অর্থ: আপনি একবার সুপারক্লাসের একটি স্ট্যাটিক পদ্ধতিটি উল্লেখ করলে, আপনি সুপারক্লাস পদ্ধতিটি কল করেন তবে কোনও সাবক্লাস পদ্ধতি কখনও নয়)।
এই অনুসারে, বিমূর্ত স্ট্যাটিক পদ্ধতিগুলি যথেষ্ট অকেজো হবে কারণ আপনার কোনও সংজ্ঞায়িত বডি দ্বারা এর রেফারেন্সটি কখনও পাওয়া যাবে না।
আমি দেখতে পাচ্ছি যে ইতিমধ্যে একটি গড-জিলিয়ন উত্তর রয়েছে তবে আমি কোনও ব্যবহারিক সমাধান দেখতে পাচ্ছি না। অবশ্যই এটি একটি আসল সমস্যা এবং জাভাতে এই বাক্য গঠনটি বাদ দেওয়ার কোনও ভাল কারণ নেই। যেহেতু মূল প্রশ্নের একটি প্রসঙ্গের অভাব রয়েছে যেখানে এটি প্রয়োজন হতে পারে, তাই আমি একটি প্রসঙ্গ এবং সমাধান উভয়ই সরবরাহ করি:
ধরুন আপনার কাছে ক্লাসগুলির একগুচ্ছ অভিন্ন একটি স্থিতিশীল পদ্ধতি রয়েছে। এই পদ্ধতিগুলি শ্রেণিবদ্ধ একটি স্থিতিশীল পদ্ধতি কল করে:
class C1 {
static void doWork() {
...
for (int k: list)
doMoreWork(k);
...
}
private static void doMoreWork(int k) {
// code specific to class C1
}
}
class C2 {
static void doWork() {
...
for (int k: list)
doMoreWork(k);
...
}
private static void doMoreWork(int k) {
// code specific to class C2
}
}
doWork()
পদ্ধতি C1
এবং C2
অভিন্ন। এর মধ্যে প্রচুর পরিমাণে কলস থাকতে পারে: C3
C4
ইত্যাদি যদি static abstract
অনুমতি দেওয়া হয় তবে আপনি নকল কোডটি এমন কিছু করে মুছে ফেলতেন :
abstract class C {
static void doWork() {
...
for (int k: list)
doMoreWork(k);
...
}
static abstract void doMoreWork(int k);
}
class C1 extends C {
private static void doMoreWork(int k) {
// code for class C1
}
}
class C2 extends C {
private static void doMoreWork(int k) {
// code for class C2
}
}
তবে এটি সংকলন করবে না কারণ static abstract
সংমিশ্রণ অনুমোদিত নয়। যাইহোক, এটি static class
কনস্ট্রাক্ট দিয়ে সংঘবদ্ধ করা যেতে পারে , যা অনুমোদিত:
abstract class C {
void doWork() {
...
for (int k: list)
doMoreWork(k);
...
}
abstract void doMoreWork(int k);
}
class C1 {
private static final C c = new C(){
@Override void doMoreWork(int k) {
System.out.println("code for C1");
}
};
public static void doWork() {
c.doWork();
}
}
class C2 {
private static final C c = new C() {
@Override void doMoreWork(int k) {
System.out.println("code for C2");
}
};
public static void doWork() {
c.doWork();
}
}
এই সমাধানের সাথে ডুপ্লিকেট করা একমাত্র কোডটি
public static void doWork() {
c.doWork();
}
C1.doWork()
বা C2.doWork()
আপনি কল করতে পারবেন না C.doWork()
। এছাড়াও আপনি যে উদাহরণ সরবরাহ করেছেন, তাতে কোনটি কার্যকর হবে না, ধরুন যদি এটি অনুমোদিত হয় তবে শ্রেণি কীভাবে C
এর বাস্তবায়ন খুঁজে পাবে doMoreWork()
? অবশেষে আমি আপনার প্রসঙ্গ কোডটি একটি খারাপ নকশা বলব। কেন? কারণ আপনি কোড জন্য পৃথক ফাংশন যা পরিবর্তে কোড সাধারণ যে জন্য একটি ফাংশন তৈরি এবং তারপর ক্লাসে একটি স্ট্যাটিক ফাংশন রূপায়ণকারী অনন্য তৈরি করেছেন C
। এটা সহজ !!!
ধরুন এখানে দুটি ক্লাস রয়েছে, Parent
এবং Child
। Parent
হয় abstract
। ঘোষণাগুলি নিম্নরূপ:
abstract class Parent {
abstract void run();
}
class Child extends Parent {
void run() {}
}
এর অর্থ হ'ল যে কোনও উদাহরণ Parent
অবশ্যই run()
নির্বাহ করা হবে।
যাইহোক, এখন এটি Parent
না অনুমান abstract
।
class Parent {
static void run() {}
}
এর অর্থ Parent.run()
এটি স্থির পদ্ধতি কার্যকর করবে will
একটি abstract
পদ্ধতির সংজ্ঞাটি হ'ল "এমন একটি পদ্ধতি যা ঘোষিত হয় তবে বাস্তবায়িত হয় না", যার অর্থ এটি নিজে কিছু দেয় না।
কোনও static
পদ্ধতির সংজ্ঞাটি হ'ল "এমন একটি পদ্ধতি যা একই পরামিতিগুলির জন্য একই মান প্রদান করে যেখানে এটি বলা হয় না কেন"।
abstract
উদাহরণ পরিবর্তনের সাথে সাথে একটি পদ্ধতির রিটার্ন মান পরিবর্তন হবে। একটি static
পদ্ধতি না। একটি static abstract
পদ্ধতি হ'ল এমন একটি পদ্ধতি যেখানে রিটার্নের মান স্থির থাকে তবে কোনও কিছুই ফেরত দেয় না। এটি একটি যৌক্তিক দ্বন্দ্ব।
এছাড়াও, কোনও static abstract
পদ্ধতির জন্য খুব বেশি কারণ নেই ।
একটি বিমূর্ত শ্রেণীর কোনও স্থির পদ্ধতি থাকতে পারে না কারণ ডায়ামামিক বাইন্ডিং অর্জনের জন্য অ্যাবস্ট্রাকশন করা হয় যখন স্থির পদ্ধতিগুলি তাদের কার্যকারিতার সাথে স্থিরভাবে আবদ্ধ থাকে A একটি স্থির পদ্ধতির অর্থ আচরণ এমন একটি আচরণের পরিবর্তনশীলের উপর নির্ভরশীল আচরণ নয়, সুতরাং কোনও উদাহরণ / বস্তুর প্রয়োজন নেই J শ্রেণীর কেবলমাত্র। স্থিতিশীল পদ্ধতি শ্রেণীর অন্তর্ভুক্ত এবং আপত্তি নয়। এগুলি পারমজেন নামে পরিচিত একটি স্মৃতি অঞ্চলে সংরক্ষণ করা হয় যেখানে এটিকে প্রতিটি বস্তুর সাথে ভাগ করা হয়। বিমূর্ত শ্রেণিতে পদ্ধতিগুলি কার্যকরীতার সাথে গতিশীলভাবে আবদ্ধ হয়।
পদ্ধতি হিসেবে ঘোষণা static
উপায়ে আমরা তার বর্গ নামে যে পদ্ধতি কল করতে পারেন এবং যদি যে ক্লাস হয় abstract
পাশাপাশি, এটা কোন ইন্দ্রিয় তোলে একে ডাকতে যেমন কোনো অংশ নেই, তাই আমরা উভয় হিসাবে একটি পদ্ধতি ঘোষণা করতে পারবে না static
এবং abstract
।
যেহেতু বিমূর্ত পদ্ধতি শ্রেণীর অন্তর্ভুক্ত এবং বাস্তবায়নকারী শ্রেণীর দ্বারা ওভাররাইড করা যায় না ven একই সই সহ একটি স্থির পদ্ধতি থাকলেও এটি পদ্ধতিটি আড়াল করে, ওভাররাইড করে না। সুতরাং বিমূর্ত পদ্ধতিটি স্থিতিশীল হিসাবে ঘোষনা করা অবিচ্ছিন্ন কারণ এটি কখনই দেহ পাবে না hus তাই, সময় ত্রুটি সংকলন করুন।
ক্লাসের উদাহরণ ছাড়াই একটি স্ট্যাটিক পদ্ধতি বলা যেতে পারে। আপনার উদাহরণে আপনি foo.bar2 () কল করতে পারেন, তবে foo.bar () না, কারণ বারের জন্য আপনার একটি উদাহরণ প্রয়োজন। নিম্নলিখিত কোড কাজ করবে:
foo var = new ImplementsFoo();
var.bar();
আপনি যদি কোনও স্ট্যাটিক পদ্ধতিতে কল করেন তবে এটি সর্বদা একই কোড কার্যকর করা হবে। উপরের উদাহরণে, আপনি ইমপ্লিমেন্টসফুতে বার 2 পুনরায় সংজ্ঞায়িত করলেও, var.bar2 () এ কল foo.bar2 () চালিত করবে।
যদি বার 2 এর এখন কোনও প্রয়োগণ না থাকে (এটি বিমূর্তির অর্থ) তবে আপনি প্রয়োগ না করে কোনও পদ্ধতিতে কল করতে পারেন। এটা খুব ক্ষতিকারক।
আমার বিশ্বাস আমি কেন এই ইন্টারফেসের পদ্ধতিগুলি (যা পিতামাতার শ্রেণিতে বিমূর্ত পদ্ধতিগুলির মতো কাজ করে) স্থির হতে পারে না সে আকারে এই প্রশ্নের উত্তর পেয়েছি। এখানে সম্পূর্ণ উত্তর (আমার নয়)
মূলত স্থির পদ্ধতিগুলি সংকলনের সময়ে আবদ্ধ হতে পারে, যেহেতু তাদের কল করার জন্য আপনাকে কোনও শ্রেণি নির্দিষ্ট করতে হবে। এটি উদাহরণের পদ্ধতির চেয়ে পৃথক, যার জন্য আপনি যে পদ্ধতিটি থেকে পদ্ধতিটি কল করছেন সেটির ক্লাসটি সংকলনের সময় অজানা হতে পারে (এইভাবে কোন কোড ব্লক বলা হয় কেবল রানটাইমের সময় নির্ধারণ করা যেতে পারে)।
আপনি যদি কোনও স্ট্যাটিক পদ্ধতিতে কল করে থাকেন তবে আপনি ইতিমধ্যে ক্লাসটি প্রয়োগ করেছেন বা এটির কোনও সরাসরি উপশ্রেণী জানেন। আপনি যদি সংজ্ঞা দিন
abstract class Foo {
abstract static void bar();
}
class Foo2 {
@Override
static void bar() {}
}
তারপরে যে কোনও Foo.bar();
কল স্পষ্টতই অবৈধ এবং আপনি সর্বদা ব্যবহার করবেন Foo2.bar();
।
এটি মনে রেখে, একটি স্ট্যাটিক বিমূর্ত পদ্ধতিটির একমাত্র উদ্দেশ্য হ'ল এই জাতীয় পদ্ধতিটি বাস্তবায়নের জন্য সাবক্লাসগুলি প্রয়োগ করা। আপনি প্রথমে মনে হতে পারে এই খুব ভুল, কিন্তু যদি আপনি একটি জেনেরিক টাইপ প্যারামিটার আছে <E extends MySuperClass>
এটা ইন্টারফেসের মাধ্যমে যে গ্যারান্টি চমৎকার হবে E
করতে পারেন .doSomething()
। মনে রাখবেন টাইপ ইরেজরের জেনেরিকগুলি কেবল সংকলনের সময় উপস্থিত রয়েছে।
সুতরাং, এটি দরকারী হবে? হ্যাঁ, এবং সম্ভবত সে কারণেই জাভা 8 ইন্টারফেসগুলিতে স্থির পদ্ধতিগুলির অনুমতি দিচ্ছে (যদিও এটি কেবলমাত্র একটি ডিফল্ট বাস্তবায়ন সহ) with ক্লাসে একটি ডিফল্ট বাস্তবায়ন সহ বিমূর্ত স্থির পদ্ধতিগুলি কেন নয়? কেবলমাত্র কারণ একটি ডিফল্ট বাস্তবায়ন সহ একটি বিমূর্ত পদ্ধতি আসলে একটি কংক্রিট পদ্ধতি।
কোনও ডিফল্ট বাস্তবায়ন ছাড়াই কেন বিমূর্ত / ইন্টারফেস স্ট্যাটিক পদ্ধতিগুলি? স্পষ্টতই, জাভা যে কোডটি ব্লক করে তা কার্যকর করার জন্য (আমার উত্তরের প্রথম অংশ) কেবল এই কারণে চিহ্নিত হয়েছে।
কারণ অ্যাবস্ট্রাক্ট ক্লাসটি একটি ওওপিএস ধারণা এবং স্ট্যাটিক সদস্যরা ওওপিএসের অংশ নয় ....
এখন কথাটি হ'ল আমরা ইন্টারফেসে স্থির সম্পূর্ণ পদ্ধতি ঘোষণা করতে পারি এবং একটি ইন্টারফেসের অভ্যন্তরে মূল পদ্ধতি ঘোষণা করে আমরা ইন্টারফেস চালাতে পারি
interface Demo
{
public static void main(String [] args) {
System.out.println("I am from interface");
}
}
একটি বিমূর্ত স্থির পদ্ধতি থাকার ধারণাটি হ'ল আপনি সরাসরি সেই পদ্ধতির জন্য সেই নির্দিষ্ট বিমূর্ত শ্রেণিটি ব্যবহার করতে পারবেন না, তবে কেবলমাত্র প্রথম ডেরাইভেটিভকে সেই স্থির পদ্ধতিটি প্রয়োগ করার অনুমতি দেওয়া হবে (বা জেনেরিকের জন্য: জেনেরিকের আসল শ্রেণি আপনি ব্যবহার)।
এইভাবে, আপনি উদাহরণস্বরূপ একটি বাছাইযোগ্য অবজেক্ট অ্যাবস্ট্রাক্ট ক্লাস তৈরি করতে পারেন বা এমনকি (স্বয়ংক্রিয়) বিমূর্ত স্থির পদ্ধতিগুলির সাথে ইন্টারফেসও তৈরি করতে পারেন, যা সাজানোর বিকল্পগুলির পরামিতিগুলি সংজ্ঞায়িত করে:
public interface SortableObject {
public [abstract] static String [] getSortableTypes();
public String getSortableValueByType(String type);
}
এখন আপনি একটি বাছাইযোগ্য অবজেক্টের সংজ্ঞা দিতে পারেন যা মূল ধরণের অনুসারে বাছাই করা যায় যা এই সমস্ত বস্তুর জন্য একই:
public class MyDataObject implements SortableObject {
final static String [] SORT_TYPES = {
"Name","Date of Birth"
}
static long newDataIndex = 0L ;
String fullName ;
String sortableDate ;
long dataIndex = -1L ;
public MyDataObject(String name, int year, int month, int day) {
if(name == null || name.length() == 0) throw new IllegalArgumentException("Null/empty name not allowed.");
if(!validateDate(year,month,day)) throw new IllegalArgumentException("Date parameters do not compose a legal date.");
this.fullName = name ;
this.sortableDate = MyUtils.createSortableDate(year,month,day);
this.dataIndex = MyDataObject.newDataIndex++ ;
}
public String toString() {
return ""+this.dataIndex+". "this.fullName+" ("+this.sortableDate+")";
}
// override SortableObject
public static String [] getSortableTypes() { return SORT_TYPES ; }
public String getSortableValueByType(String type) {
int index = MyUtils.getStringArrayIndex(SORT_TYPES, type);
switch(index) {
case 0: return this.name ;
case 1: return this.sortableDate ;
}
return toString(); // in the order they were created when compared
}
}
এখন আপনি একটি তৈরি করতে পারেন
public class SortableList<T extends SortableObject>
যা প্রকারগুলি পুনরুদ্ধার করতে পারে, ধরণের বাছাই করতে কোনও ধরণের পছন্দ করতে একটি পপ-আপ মেনু তৈরি করতে পারে এবং সেই ধরণের থেকে ডেটা পেয়ে তালিকাটি রিসর্ট করতে পারে এবং পাশাপাশি একটি ক্রম সংযোজন করতে পারে, যখন কোনও সাজানোর প্রকারটি নির্বাচন করা হলে, স্বয়ংক্রিয়ভাবে যেতে পারে নতুন আইটেমগুলিকে এতে বাছাই করুন Note
String [] MenuItems = T.getSortableTypes();
একটি উদাহরণ ব্যবহার করার সাথে সমস্যাটি হ'ল সোর্টেবললিস্টে এখনও আইটেম না থাকতে পারে তবে ইতিমধ্যে পছন্দসই বাছাই করা দরকার।
চেরিও, ওলাফ
প্রথমে বিমূর্ত ক্লাস সম্পর্কে একটি মূল বিষয় - একটি বিমূর্ত শ্রেণি ইনস্ট্যান্ট করা যায় না ( উইকি দেখুন )। সুতরাং, আপনি কোনও বিমূর্ত শ্রেণির কোনও উদাহরণ তৈরি করতে পারবেন না ।
এখন, জাভা স্থিতিশীল পদ্ধতিগুলির সাথে যেভাবে আচরণ করে তা হল সেই শ্রেণীর সমস্ত দৃষ্টান্তের সাথে পদ্ধতিটি ভাগ করে নেওয়া ।
সুতরাং, যদি আপনি কোনও শ্রেণি ইনস্ট্যান্ট করতে না পারেন, তবে একটি শ্রেণীর বিমূর্ত পদ্ধতি স্থিতিযুক্ত পদ্ধতিগুলি থাকতে পারে না কারণ একটি বিমূর্ত পদ্ধতিটি প্রসারিত করার জন্য অনুরোধ করে।
গম্ভীর গর্জন।
জাভা ডক অনুসারে :
স্ট্যাটিক পদ্ধতি হ'ল এমন একটি পদ্ধতি যা শ্রেণীর সাথে সম্পর্কিত যেখানে এটি কোনও বস্তুর পরিবর্তে সংজ্ঞায়িত হয়। শ্রেণীর প্রতিটি উদাহরণ তার স্থিতিশীল পদ্ধতিগুলি ভাগ করে দেয়
জাভা 8-এ, একটি ইন্টারফেসে ডিফল্ট পদ্ধতিগুলির সাথে স্থির পদ্ধতিগুলিও অনুমোদিত। এটি আমাদের জন্য আমাদের লাইব্রেরিতে সহায়ক পদ্ধতিগুলি সংগঠিত করা সহজ করে তোলে। আমরা পৃথক শ্রেণীর পরিবর্তে একই ইন্টারফেসের একটি ইন্টারফেসের সাথে নির্দিষ্ট স্ট্যাটিক পদ্ধতি রাখতে পারি।
এর একটি দুর্দান্ত উদাহরণ হ'ল:
list.sort(ordering);
পরিবর্তে
Collections.sort(list, ordering);
স্থির পদ্ধতি ব্যবহারের আরেকটি উদাহরণ ডকটিতেও দেওয়া হয়েছে :
public interface TimeClient {
// ...
static public ZoneId getZoneId (String zoneString) {
try {
return ZoneId.of(zoneString);
} catch (DateTimeException e) {
System.err.println("Invalid time zone: " + zoneString +
"; using default time zone instead.");
return ZoneId.systemDefault();
}
}
default public ZonedDateTime getZonedDateTime(String zoneString) {
return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
}
}
কারণ 'অ্যাবস্ট্রাক্ট' অর্থ পদ্ধতিটি ওভাররাইড করা বোঝায় এবং কেউ 'স্ট্যাটিক' পদ্ধতিগুলিকে ওভাররাইড করতে পারে না।
নিয়মিত পদ্ধতিগুলি বিমূর্ত হতে পারে যখন সেগুলি সাবক্লাস দ্বারা ওভাররাইড করা এবং কার্যকারিতা সহ সরবরাহ করা হয়। ক্লাস ইত্যাদি Foo
দ্বারা প্রসারিত হয়েছে কল্পনা করুন Bar1, Bar2, Bar3
সুতরাং, প্রত্যেকের তাদের প্রয়োজন অনুযায়ী বিমূর্ত শ্রেণির নিজস্ব সংস্করণ থাকবে।
এখন, সংজ্ঞায়িত স্থিতিশীল পদ্ধতিগুলি শ্রেণীর অন্তর্গত, শ্রেণীর অবজেক্টগুলি বা এর উপশ্রেণীগুলির সাথে তাদের কোনও সম্পর্ক নেই nothing এমনকি তাদের অস্তিত্বের প্রয়োজন নেই, তারা ক্লাসগুলি তাত্ক্ষণিক না করে ব্যবহার করা যেতে পারে। সুতরাং, তাদের প্রস্তুত থাকতে হবে এবং তাদের কার্যকারিতা যুক্ত করতে সাবক্লাসগুলির উপর নির্ভর করতে পারে না।
কারণ অ্যাবস্ট্রাক্ট একটি কীওয়ার্ড যা অ্যাবস্ট্রাক্ট পদ্ধতিতে প্রয়োগ করা হয় কোনও শরীর নির্দিষ্ট করে না। এবং যদি আমরা স্থিতিশীল কীওয়ার্ড সম্পর্কে কথা বলি তবে এটি শ্রেণিকক্ষের অন্তর্গত।
আপনি জাভা 8 এ ইন্টারফেসের সাথে এটি করতে পারেন।
এটি সম্পর্কে এটি অফিসিয়াল ডকুমেন্টেশন:
https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
কারণ কোনও শ্রেণি যদি একটি বিমূর্ত শ্রেণি প্রসারিত করে তবে এটি বিমূর্ত পদ্ধতি ওভাররাইড করতে হবে এবং এটি বাধ্যতামূলক। স্থিতিশীল পদ্ধতিগুলি ক্লাইপ পদ্ধতিগুলি সংকলনের সময়ে সমাধান করা হয় যখন ওভাররাইড পদ্ধতিগুলি রানটাইম এবং মেশিনাল পলিমারফিজম অনুসরণের সময় সমাধান পদ্ধতিগুলি।