চূড়ান্ত স্থির পদ্ধতির আচরণ


123

আমি স্ট্যাটিক পদ্ধতিতে মডিফায়ারগুলির সাথে ঘুরে বেড়াচ্ছি এবং একটি অদ্ভুত আচরণ পেয়েছি।

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

সুতরাং আমার যদি নীচের স্নিপেট থাকে তবে তা জরিমানা করে

//Snippet 1 - Compiles fine
public class A {
    static void ts() {
    }
}

class B extends A {
    static void ts() {
    }
}

তবে আমি যদি ক্লাস এ এ স্ট্যাটিক পদ্ধতিতে চূড়ান্ত সংশোধক অন্তর্ভুক্ত করি, তবে সংকলন বিতে ts () কে ব্যর্থ করে টি-তে () এ-তে ওভাররাইড করতে পারে না; ওভাররাইড পদ্ধতিটি স্থির চূড়ান্ত

স্থির পদ্ধতিটি যখন মোটেই ওভাররাইড করা যায় না তখন কেন এমনটি হচ্ছে?


2
প্রশ্নের জন্য এটি অদ্ভুত বলে মনে হয়, তবে এখনও উত্তরগুলির কোনওটি সন্তোষজনক নয়।
রাকেশ জুয়াল

1
এটি ওভাররাইড করা হয়নি। এটি এখনও এটিসে () এ রয়েছে।
অ্যালেক্স ফেইনম্যান

উত্তর:


166

স্থির পদ্ধতিগুলি ওভাররাইড করা যায় না তবে সেগুলি লুকানো যায়। ts()বি এর পদ্ধতিটি এ এর ​​ওভাররাইডিং নয় (বহুসত্ত্বার বিষয় নয়) ts()তবে এটি এটি আড়াল করবে। আপনি যদি ts()বি তে কল করেন (না A.ts()বা B.ts()... কেবল ts()), বি এর একটি কল করা হবে এবং এ। নয়, যেহেতু এটি বহুবর্ষের শিকার হয় না, তাই ts()A এ কলটি কখনই বি- তে প্রেরণ করা হবে না will

কীওয়ার্ডটি finalলুকানো থেকে পদ্ধতিটি অক্ষম করবে। সুতরাং সেগুলি লুকানো যাবে না এবং এটি করার চেষ্টা করার ফলে সংকলক ত্রুটির ফলস্বরূপ।

আশাকরি এটা সাহায্য করবে.


30
আপনার উত্তরটি শেষ করতে সম্ভবত আমি বিশ্বাস করি, এখানে সমস্যাটি মূলত একটি খারাপ সংকলক ত্রুটি বার্তা: এটি বলা উচিত যে বি তে টিএস () লুকিয়ে রাখতে পারে না একটি স্থির পদ্ধতি চূড়ান্ত ঘোষণা করে এটি লুকানো যায় না।
শন ওভেন

2
@ শীন ওওন: আমারও তাই মনে হয়। 'গোপন' শব্দটি এমনকি জাভা স্পেসিফিকেশনে ব্যবহৃত হয় তাই কেন এটি সংকলক বার্তায় ব্যবহার করবেন না।
নওয়ামন

2
কেন এটি এমনকি একটি বৈশিষ্ট্য? কোন প্রসঙ্গে এটি দরকারী হবে?
ব্যবহারকারী 253751

পাবলিক ক্লাস টেস্ট {চূড়ান্ত স্ট্যাটিক পাবলিক অকার্যকর প্রধান (স্ট্রিং ... srik) {System.out.println ("মূল পদ্ধতিতে"); TS (); stat সর্বজনীন স্ট্যাটিক শূন্য ts () {চাইল্ড সি = নতুন চাইল্ড (); c.ts (); System.out.println ("টেস্ট ts"); }} পাবলিক ক্লাস চাইল্ড পরীক্ষার প্রসার করে {পাবলিক স্ট্যাটিক শূন্য টিএস () {System.out.println ("চাইল্ড টিএস"); }} হাই আপনারা প্লিজ আমাকে এই দৃশ্যে কী ঘটে যায় তা ব্যাখ্যা করতে পারেন
শ্রীকান্ত r

@ সিয়ান ওভেন আমি এটিও সঠিক বলে মনে করি না, সংকলকটি বলতে হবে যেহেতু A#tsউত্তরাধিকার সূত্রে প্রাপ্ত এবং এই জাতীয় পদ্ধতি ইতিমধ্যে বিদ্যমান রয়েছে B, কেবল একই স্বাক্ষরযুক্ত দুটি পদ্ধতি থাকা এবং একটি পৃথক পরিবর্তনকারী ( final) অতিরিক্ত চাপ হিসাবে কাজ করবে না .. আমি আশা করি আমি এটির জন্য একটি সাধারণ বার্তাটি ভাবতে পারি, যদিও
ইউজিন

13

স্থিতিশীল পদ্ধতি ওভাররাইড করা যায় না

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


4
এটা ঠিক ঠিক সঠিক নয়। স্থিতিশীল পদ্ধতিগুলি ওভাররাইড করা যায় না তবে আপনি শ্রেণীর নামের পরিবর্তে উদাহরণের রেফারেন্সে তাদের কল দিলে লুকিয়ে রাখা যায়।
জন মার্সিয়ের

1
দুর্ভাগ্যক্রমে আপনার লিঙ্কটি আর কাজ করছে না। এটি ঠিক করা সম্ভব?
ম্যাথিয়াস Bader

জাভরঞ্চ লিঙ্কটি কাজ করছে না, তবে মূল শব্দগুলি গুগলিং এই লিঙ্কটি কোড রঞ্চে পরিণত করেছে
সুন্দীপ

আমি সন্দীপের পোস্ট করা লিঙ্কটি দিয়ে মৃত লিঙ্কটি প্রতিস্থাপন করে পোস্টটি সম্পাদনা করেছি।
এমসির সম্রাট

10

স্থির পদ্ধতি ক্লাসের অন্তর্গত, উদাহরণটি নয় not

A.ts()এবং B.ts()সর্বদা পৃথক পদ্ধতি হতে চলেছে।

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

আপনি ভাববেন যে ত্রুটি বার্তাটি ওভাররাইডের পরিবর্তে লুকানো শব্দটি ব্যবহার করবে ...


6

নীচের বিষয়গুলি বিবেচনা করে আপনি একটি স্থিতিশীল পদ্ধতি চূড়ান্ত করার বিষয়ে চিন্তা করার মতো অবস্থানে থাকতে পারেন:

নিম্নলিখিত ক্লাস হচ্ছে:

class A {
    static void ts() {
        System.out.print("A");
    }
}
class B extends A {
    static void ts() {
        System.out.print("B");
    }
}

এখন এই পদ্ধতিগুলি কল করার 'সঠিক' উপায়টি হবে

A.ts();
B.ts();

যার ফলশ্রুতিতে হবে ABতবে আপনি উদাহরণগুলিতে পদ্ধতিগুলি কল করতে পারেন:

A a = new A();
a.ts();
B b = new B();
b.ts();

যার ফলস্বরূপ হবে AB

এখন নিম্নলিখিত বিবেচনা করুন:

A a = new B();
a.ts();

যে মুদ্রণ হবে A। আপনি অবাক হতে পারে যেহেতু আপনি অবাক হতে পারে B। তবে যেহেতু আপনি এটিকে কোনও প্রকারের উল্লেখ থেকে কল করছেন A, এটি কল করবে A.ts()। আপনি Bনিম্নলিখিত কোড সহ মুদ্রণ করতে পারে :

A a = new B();
((B)a).ts();

উভয় ক্ষেত্রে আপনার কাছে বস্তুটি আসলে শ্রেণীর B। কিন্তু পয়েন্টারটি নির্ভর করে যা বস্তুটির দিকে নির্দেশ করে, আপনি যে পদ্ধতি থেকে Aবা সেখান থেকে কল করবেন B

এখন ধরা যাক আপনি শ্রেণির বিকাশকারী Aএবং আপনি উপ-শ্রেণিবদ্ধকরণের অনুমতি দিতে চান। তবে আপনি সত্যিই পদ্ধতিটি চান ts(), যখনই ডাকা হয় এমনকি একটি উপশ্রেণীর কাছ থেকেও, এটি আপনি যা করতে চান তা করে এবং একটি সাবক্লাস সংস্করণ দ্বারা গোপন করা না হয়। তারপরে আপনি এটিকে তৈরি করতে পারেন finalএবং এটি সাবক্লাসে লুকানো থেকে আটকাতে পারেন। এবং আপনি নিশ্চিত হতে পারেন যে নিম্নলিখিত কোডটি আপনার শ্রেণি থেকে পদ্ধতিটি কল করবে A:

B b = new B();
b.ts();

ঠিক আছে, স্বীকার করে নিন যে এটি একরকম নির্মিত, তবে এটি কিছু ক্ষেত্রে বোধগম্য হতে পারে।

আপনার উদাহরণস্বরূপ স্ট্যাটিক পদ্ধতিগুলি কল করা উচিত নয় সরাসরি ক্লাসগুলিতে - তবে আপনার সমস্যা হবে না won't এছাড়াও উদাহরণস্বরূপ ইন্টেলিজ আইডিইএ আপনাকে একটি সতর্কতা দেখাবে, যদি আপনি কোনও পরিস্থিতিতে কোনও স্ট্যাটিক পদ্ধতি কল করেন এবং পাশাপাশি আপনি যদি কোনও স্ট্যাটিক পদ্ধতি চূড়ান্ত করেন তবে।


0

বি তে টিএস () পদ্ধতিটি এ-তে টিএস () পদ্ধতিকে ওভাররাইড করছে না, এটি কেবল অন্য পদ্ধতি। বি শ্রেণিটি এ-তে টিএস () পদ্ধতিটি দেখতে পাচ্ছে না কারণ এটি স্থিতিশীল, তাই এটি ts () নামে নিজস্ব পদ্ধতিটি ঘোষণা করতে পারে।

তবে, পদ্ধতিটি যদি চূড়ান্ত হয় তবে সংকলকটি বেছে নেবে যে এ-তে একটি ts () পদ্ধতি রয়েছে যা বিতে ওভাররাইড করা উচিত নয় should


আমি মনে করি না কেন এটি হ'ল হ'ল 'চূড়ান্ত' অর্থ হ'ল এই পদ্ধতিগুলি সহাবস্থান করতে পারে না। আপনি যেমনটি বলেছেন, 'চূড়ান্ত' ছাড়া কোনও সমস্যা নেই। আপনি বলছেন যে এটি ওভাররাইড হচ্ছে না, তবে তারপরে বলবেন সমস্যাটি হ'ল বি এ এর ​​পদ্ধতিটিকে ওভাররাইড করতে পারে না।
শন ওভেন

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

0

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


1
সুতরাং আপনি বি এর স্থিতিশীল পদ্ধতি এ এর ​​একটিকে ওভাররাইড বিবেচনা করবেন?
Koray Tugay

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

বালুস আমি মনে করি স্ট্যাক ওভারফ্লোতে এটি আপনার কাছে কেবলমাত্র নিম্নমানের উত্তর। আপনার সমস্ত ব্যতিক্রমী উত্তর বিবেচনা করে, এটি তাদের মধ্যে নেই। @ বালুসসি
টুগে

@ কোরেতুগায়: সেসময় আমার মন্তব্য করার মতো খ্যাতি ছিল না :) আপনি যদি পিছনে পিছনে পড়ে থাকেন তবে আমি উত্তরটি মুছব, কোনও সমস্যা নেই।
বালাসসি

0

স্থিতিশীল পদ্ধতিগুলির বিপরীতে জাভাতে একটি স্থিতিশীল পদ্ধতি ওভাররাইড করা যায় না। তবে তারা স্থায়ী এবং অ-স্থিতিশীল ডেটা সদস্যের মতো উত্তরাধিকার সূত্রে প্রাপ্ত। এ কারণেই অভিভাবক শ্রেণিতে একই নামের একটি অ স্থিত পদ্ধতি তৈরি করা যায় না

class Writer { 
    public static void doo(){
        System.out.println("sth");
    } 
}
class Author extends Writer{ 
    public void doo(){
        System.out.println("ok"); // error overridden method is static
    }
}

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.