ওভাররাইড করার সময় যখন সুপার () পদ্ধতিটি কল করবেন না?


113

আমি যখন আমার নিজের অ্যান্ড্রয়েড কাস্টম ক্লাস করি তখন আমি extendএর নেটিভ ক্লাস করি। তারপর যখন আমি বেস পদ্ধতি ওভাররাইড করতে চাই, আমি সবসময় কল super()পদ্ধতি, ঠিক আমি সবসময় না onCreate, onStopইত্যাদি

এবং আমি ভেবেছিলাম এটি এটি, প্রথম থেকেই অ্যান্ড্রয়েড দল আমাদের সর্বদা superপ্রতিটি পদ্ধতির ওভাররাইডের দিকে কল করার পরামর্শ দেয় ।

তবে, অনেক বইতে আমি দেখতে পাচ্ছি যে বিকাশকারীরা, আমার চেয়ে অভিজ্ঞ, প্রায়শই কল করা বাদ দেয় superএবং আমি সন্দেহ করি যে তারা এটি জ্ঞানের অভাব হিসাবে করেন। উদাহরণস্বরূপ, এটি মৌলিক তাকান SAX পার্সার বর্গ যেখানে superমধ্যে বাদ দেওয়া হয় startElement, charactersএবং endElement:

public class SAXParser extends DefaultHandler{
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if(qName.equalsIgnoreCase("XXY")) {
            //do something
        }
    }

    public void characters(char[] ch, int start, int length) throws SAXException {
        //do something
    }

    public void endElement(String uri, String localName, String qName) throws SAXException {
        if(qName.equalsIgnoreCase("XXY")) {
            //do something
        }else () {
            //do something
        }
    }
}

আপনি যদি Eclipse বা অন্য কোনও IDE এর মাধ্যমে কোনও ওভাররাইড পদ্ধতি তৈরি করার চেষ্টা করেন superতবে সর্বদা স্বয়ংক্রিয় প্রক্রিয়াটির অংশ হিসাবে তৈরি করা হবে।

এটি ছিল একটি সাধারণ উদাহরণ। বই একই ধরণের কোড পূর্ণ

কখন আপনাকে কল করা উচিত superএবং কখন আপনি এটি কলিং বাদ দিতে পারেন তা তারা কীভাবে জানবে ?

পুনশ্চ. এই নির্দিষ্ট উদাহরণকে আবদ্ধ করবেন না। এটি এলোমেলোভাবে অনেক উদাহরণ থেকে বেছে নেওয়া একটি উদাহরণ।

(এটি একটি প্রাথমিক প্রশ্নের মতো মনে হতে পারে তবে আমি সত্যিই বিভ্রান্ত।


3
endElementএর এপিআই ডকটি বলেছেন "ডিফল্টরূপে, কিছুই করবেন না Application অ্যাপ্লিকেশন রাইটাররা এই পদ্ধতিটিকে ওভাররাইড করতে পারে ..." এর অর্থ আপনি নিরাপদে সুপারকে কল করতে পারেন কারণ এটি "কিছুই" করে না তবে আপনার দরকার নেই এবং আপনি সত্যই এটিকে ওভাররাইড করতে পারেন। আপনি প্রায়শই বলতে পারেন যে আপনি যদি সেই পদ্ধতির জন্য ডকটি পড়ে থাকেন তবে এটি করতে / করতে / করা উচিত নয়।
zapl

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

@ স্প্যানডোন এখানে জিজ্ঞাসা করার জন্য দুঃখিত, তবে কীভাবে অ্যাপ্লিকেশন বিলিংয়ের সাথে ভ্যাট ট্যাক্স পরিচালনা করতে হবে এবং কোন দেশগুলি গুগলের মাধ্যমে স্বয়ংক্রিয়ভাবে সম্পন্ন হয় এবং যেগুলি আমাকে ম্যানুয়ালি রিপোর্ট / ভ্যাট ট্যাক্স দিতে হবে তা সম্পর্কে আপনার কোনও অভিজ্ঞতা আছে? স্ট্যাকওভারফ্লো
বিদার ভেষ্টনেস

উত্তর:


144

superপদ্ধতিটি কল করে আপনি পদ্ধতির আচরণকে ওভাররাইড করছেন না , আপনি এটি প্রসারিত করছেন ।

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

public class A { 
    public void save() { 
         // Perform save logic
    }
}

public class B extends A {
    private Object b;
    @Override
    public void save() { 
        super.save(); // Performs the save logic for A
        save(b); // Perform additional save logic
    }
}

একটি কল উভয় এবং এই নির্দিষ্ট ক্রমে যুক্তি B.save()সম্পাদন করবে । আপনাকে কল ছিল না ভিতরে , বলা হয় না হবে। এবং যদি আপনি পরে ডাকে , কার্যকরভাবে পরে প্রদর্শিত হবে ।save()ABsuper.save()B.save()A.save()super.save()save(b)A.save()B.save()

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

ইন SAXParserউদাহরণস্বরূপ আপনি প্রদান বাস্তবায়নের এর DefaultHandlerসেই পদ্ধতি জন্য শুধু খালি রয়েছে, তাই যে উপশ্রেণী তাদের ওভাররাইড করতে ও ঐ পদ্ধতি জন্য একটি আচরণ প্রদান করতে পারেন। ইন javadoc এই পদ্ধতির জন্য এই সরু হয়ে গেছে।

public void startElement (String uri, String localName,
    String qName, Attributes attributes) throws SAXException {
    // no op
}

super()আইডিই দ্বারা উত্পন্ন কোডের ডিফল্ট কল সম্পর্কে , @barsjuতার মন্তব্যে উল্লেখ করা হয়েছে যে প্রতিটি নির্মাত্রে একটি অন্তর্নিহিত কল রয়েছে super()(এমনকি আপনি নিজের কোডটিতে এটি না লিখলেও), যার অর্থ, সেই প্রসঙ্গে, একটি কল super' ডিফল্ট নির্মাতা। IDEশুধু এটা আপনার জন্য নিচে লিখেছে, কিন্তু এটি আপনি এটা মুছে নামক পেতে হবে। এছাড়াও লক্ষ করুন যে কন্সট্রাক্টরগুলি প্রয়োগ করার সময়, super()বা যুক্তিগুলির সাথে এর কোনও কোনও রূপ (যেমন super(x,y,z)) কেবল পদ্ধতির একেবারে শুরুতে ডাকা যেতে পারে ।


14
এছাড়াও মনে রাখবেন না যে নির্মাণকারীদের জন্য super()(সুপার ক্লাসের ডিফল্ট কনস্ট্রাক্টর) সর্বদা ডাকা হয়, এমনকি যদি আপনি এটি নির্দিষ্ট না করেন। সুপার ক্লাসে যদি ডিফল্ট কনস্ট্রাক্টর না থাকে তবে আপনি সুপার ক্লাসের কনস্ট্রাক্টরের একজনকে সাবক্লাস কনস্ট্রাক্টরের আপনার প্রথম বিবৃতি হিসাবে স্পষ্টভাবে কল না করলে আপনি সংকলন ত্রুটি পাবেন।
বারসজু

1
হ্যাঁ, এটি মূলত কেবল অলসতা - যে পদ্ধতিগুলির জন্য আমরা জানি যে
বংশবৃদ্ধির

1
আপনার মূল্যবান মন্তব্যের জন্য ধন্যবাদ, বারবারসু, আমি উত্তরে এই বিবরণগুলি অন্তর্ভুক্ত করেছি।
জাভি লোপেজ

16

আপনি কীভাবে সুপার কল করবেন এবং কখন আপনি এটি কলিং বাদ দিতে পারবেন তা তারা কীভাবে জানবে?

সাধারণত, যদি একটি বিশেষ এপিআই পদ্ধতি অন্তর্নিহিত কাঠামোর প্রেক্ষাপটে জীবনচক্র করার জন্য একটি সমালোচনামূলক অর্থ আছে, এটা সবসময় স্পষ্টভাবে বিবৃত এবং API ডকুমেন্টেশন হাইলাইট, মত হবে Activity.onCreate()এপিআই ডকুমেন্টেশন । তদুপরি, যদি এপিআই একটি শক্ত নকশা অনুসরণ করে তবে প্রকল্প সংকলনকালে গ্রাহক বিকাশকারীকে সতর্ক করতে কিছু ব্যতিক্রম ছুঁড়ে ফেলা উচিত এবং নিশ্চিত হওয়া উচিত যে এটি রান সময়ে কোনও ত্রুটি তৈরি করবে না।

যদি এপিআই ডকুমেন্টেশনে এটি স্পষ্টভাবে বলা না হয় তবে ভোক্তা বিকাশকারীকে এপিআই পদ্ধতিটি ওভাররাইড করার সময় কল করা বাধ্যতামূলক নয় বলে ধরে নেওয়া নিরাপদ। ডিফল্ট আচরণ ( superপদ্ধতিটি কল করুন ) বা এটি সম্পূর্ণরূপে ওভাররাইড করবেন কিনা তা সিদ্ধান্ত নেওয়ার বিষয়টি ভোক্তা বিকাশকারীদের up

যদি শর্তটির অনুমতি দেওয়া হয় (আমি ওপেন সোর্স সফ্টওয়্যার পছন্দ করি), গ্রাহক বিকাশকারী সর্বদা এপিআই উত্স কোডটি পরীক্ষা করে দেখতে পারেন এবং পদ্ধতিটি কীভাবে হুডের নিচে লেখা হয়েছে তা দেখতে পারেন। উদাহরণস্বরূপ Activity.onCreate()উত্স এবং DefaultHandler.startElement()উত্স পরীক্ষা করে দেখুন ।


আমাকে অতিরিক্ত জিনিস ব্যাখ্যা করার জন্য ধন্যবাদ। সোর্স কোডটি যাচাইয়ের জন্য আমাকে মনে করিয়ে দেওয়ার জন্য ধন্যবাদ।
স্যান্ডেলন

7

আপনার মাথায় যা পরীক্ষা করা উচিত তা হ'ল:

"আমি কি এই পদ্ধতির সমস্ত কার্যকারিতা আমার জন্য করতে চাই এবং তারপরে কিছু করব?" যদি হ্যাঁ, তবে আপনি কল করতে চান super()এবং তারপরে আপনার পদ্ধতিটি শেষ করুন। এটি "গুরুত্বপূর্ণ" পদ্ধতির ক্ষেত্রে সত্য হবে যেমন onDraw()পটভূমিতে প্রচুর জিনিস পরিচালনা করে।

যদি আপনি কেবল কিছু কার্যকারিতা চান (বেশিরভাগ পদ্ধতির সাথে যেমন আপনি ওভাররাইড করবেন) তবে আপনি সম্ভবত কল করতে চান না super()


3

ভাল জাভি আরও ভাল উত্তর দিয়েছে .. তবে আপনি সম্ভবত জানেন যে super()একটি ওভাররাইড পদ্ধতিতে যখন ডাকা হয় তখন কী করে ... এটি বিজ্ঞাপন দেয় যে আপনি ডিফল্ট আচরণে কী করেছেন ..

উদাহরণ:

onDraw() 

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

কিন্তু একই সময়ে

onLongClick()

আপনি যখন এটি ওভাররাইড করেন তখন আপনি সুপারকে কল করতে চান না কারণ এটি সম্পাদনা পাঠ্য বা অন্য কোনও অনুরূপ দৃশ্যের বিকল্পগুলির তালিকা সহ একটি কথোপকথন নিয়ে আসে .. এটি মৌলিক পার্থক্যটি রাখে .. আপনার এটি কিছু সময় ছেড়ে দেওয়ার পছন্দ আছে .. তবে জন্য onCreate() , onStop()আপনার মতো অন্যান্য পদ্ধতিগুলি ওএসকে এটি পরিচালনা করতে দেওয়া উচিত ..


2

আমি আপনার প্রশ্নটি পরিষ্কারভাবে পাইনি, তবে আপনি যদি superপদ্ধতিটি কল করছেন না কেন সে সম্পর্কে জিজ্ঞাসা করছেন :

superপদ্ধতিটি কল করার কারণ রয়েছে : পিতামাত্ত শ্রেণিতে যদি শূন্য আর্গুমেন্ট কনস্ট্রাক্টর না থাকে তবে তার জন্য শিশু শ্রেণি তৈরি করা সম্ভব নয়, সুতরাং হয় আপনাকে প্যারেন্ট ক্লাসে কোনও আর্গুমেন্ট কনস্ট্রাক্টর রাখা দরকার বা আপনার প্রয়োজন শিশু শ্রেণীর নির্মাতার শীর্ষে super()কলিং স্টেটমেন্ট সংজ্ঞায়িত করতে argument(how much argument constructor you have used in super class)

আশা করি এটা কাজে লাগবে. যদি না হয়, আমাকে জানান।


2

আমি যেমন একটি সীমাবদ্ধ অ্যারের তালিকা বাস্তবায়ন করেছি

public class ConstraintArrayList<T> extends ArrayList<T> {
  ConstraintArrayList(Constraint<T> cons) {this.cons = cons;}
  @Override
  public boolean add(T element) {
    if (cons.accept(element))
      return super.add(element);
    return false;
  }
}

আপনি যদি কোডটি দেখেন তবে এটি সুপার ক্লাসটিকে তালিকার সাথে উপাদানটির আসল সংযোজন করতে দেওয়ার আগে কিছু প্রাক-চেকিং করে simply এটি পদ্ধতির ওভাররাইডের দুটি ভাড়ার কারণগুলির মধ্যে একটিকে বলে:

  1. এক্সটেনসিবিলিটি যেখানে আপনি সুপার ক্লাসটি কি করতে পারে তা প্রসারিত করতে চান
  2. নির্দিষ্টতা যেখানে আপনি পলিমারফিজমের মাধ্যমে সুনির্দিষ্ট আচরণ যুক্ত করতে চান যেমন সরকারী শব্দার্থের সাধারণ প্রাণী কিংডমের উদাহরণ যেখানে পাখিরা সরানোর উপায় (উড়ে) এবং ব্যাঙগুলি সরানো (হপ) প্রতিটি উপ শ্রেণীর জন্য সুনির্দিষ্ট।

2

অ্যান্ড্রয়েড ফ্রেমওয়ার্ক থেকে কোনটি ওভাররাইড করা পদ্ধতিগুলি superএই প্রশ্নটি কল করে এবং এটি জানতে পেরেছিল তাদের জন্য যারা এই প্রশ্নটি করেছেন - 2019 সালের একটি বর্তমান ইঙ্গিত এখানে রয়েছে - অ্যান্ড্রয়েড স্টুডিও 3+ আপনাকে কখন প্রয়োজন হবে তা বলবে

এখানে চিত্র বর্ণনা লিখুন

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