ওভাররাইড পদ্ধতিগুলি কি রিটার্নের ধরণের মধ্যে পৃথক হতে পারে?


134

ওভাররাইড পদ্ধতিতে কি আলাদা ফেরতের ধরণ থাকতে পারে ?


2
আপনার যদি একই বা সংকীর্ণ রিটার্নের ধরণ না থাকে তবে আপনি পাবেন ::error: method() in subclass cannot override method() in superclass
কাজী ইরফান

উত্তর:


176

জাভা ওভাররাইড পদ্ধতিগুলির জন্য * কোভারিয়েন্ট রিটার্নের ধরণগুলিকে সমর্থন করে। এর অর্থ একটি ওভাররাইড হওয়া পদ্ধতিতে আরও নির্দিষ্ট রিটার্নের ধরণ থাকতে পারে । এটি হ'ল যতক্ষণ না আপনি নতুন পদ্ধতিটি ওভাররাইড করছেন সেই পদ্ধতির রিটার্ন টাইপের ক্ষেত্রে নতুন রিটার্ন টাইপটি অনুমোদিত হবে it's

উদাহরণ স্বরূপ:

class ShapeBuilder {
    ...
    public Shape build() {
    ....
}

class CircleBuilder extends ShapeBuilder{
    ...
    @Override
    public Circle build() {
    ....
}

এটি জাভা ভাষা নির্দিষ্টকরণের 8.4.5 বিভাগে নির্দিষ্ট করা হয়েছে :

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

রিটার্ন টাইপ আর 1 সহ একটি পদ্ধতি ঘোষণার ডি 1 হ'ল রিটার্ন টাইপ আর 2 সহ অন্য পদ্ধতি ডি 2 এর জন্য রিটার্ন-টাইপ-সাবস্টিটিউটেবল, যদি এবং কেবল নিম্নলিখিত শর্তগুলি ধরে থাকে:

  • আর 1 যদি শূন্য হয় তবে আর 2 শূন্য হয়।

  • আর 1 যদি আদিম ধরণের হয় তবে আর 2 আর 1 এর সাথে সমান।

  • আর 1 যদি রেফারেন্স টাইপ হয় তবে:

    • আর 1 হয় হয় আর 2 এর একটি উপ টাইপ বা আর 1 কে চেক না করা রূপান্তর (§5.1.9) দ্বারা আর 2 এর উপ-টাইপে রূপান্তর করা যেতে পারে, বা

    • আর 1 = | আর 2 |

("| আর 2 |" জেএলএস এর §4.6 এ সংজ্ঞায়িত হিসাবে, আর 2 এর ক্ষয়কে বোঝায় ))


* জাভা 5 এর পূর্বে জাভাতে ইনগ্রান্ট রিটার্নের ধরণ ছিল যার অর্থ পদ্ধতিটির ওভাররাইডের সাথে মেলে সঠিকভাবে মেলে একটি মেথড ওভাররাইডের রিটার্ন টাইপটি।


26

হ্যাঁ এটি পৃথক হতে পারে তবে সেগুলির কিছু সীমাবদ্ধতা।

জাভা 5.0 এর আগে, আপনি যখন কোনও পদ্ধতি ওভাররাইড করবেন, প্যারামিটার এবং রিটার্ন টাইপ উভয়ই ঠিক মিলবে। জাভা ৫.০-তে এটি কোভেরিয়েন্ট রিটার্ন টাইপ নামে একটি নতুন সুবিধা চালু করেছে। আপনি একই স্বাক্ষর সহ একটি পদ্ধতি ওভাররাইড করতে পারেন তবে প্রত্যাবর্তিত অবজেক্টের একটি সাবক্লাস প্রদান করে। অন্য কথায়, সাবক্লাসের একটি পদ্ধতি এমন কোনও বস্তুকে প্রত্যাবর্তন করতে পারে যার ধরণটি সুপারক্লাসের একই স্বাক্ষর সহ পদ্ধতিতে ফেরত পাঠানো টাইপের একটি সাবক্লাস।


20

হ্যাঁ, যদি তারা একটি সাব টাইপ ফেরত দেয়। এখানে একটি উদাহরণ:

package com.sandbox;

public class Sandbox {

    private static class Parent {
        public ParentReturnType run() {
            return new ParentReturnType();
        }
    }

    private static class ParentReturnType {

    }

    private static class Child extends Parent {
        @Override
        public ChildReturnType run() {
            return new ChildReturnType();
        }
    }

    private static class ChildReturnType extends ParentReturnType {
    }
}

এই কোডটি সংকলন করে চলে।


9

হ্যাঁ রিটার্নের ধরণটি ব্যাপকভাবে বলতে গেলে ওভাররাইডের পদ্ধতিটি আলাদা হতে পারে। তবে এর সাথে সরাসরি জড়িত কিছু মামলা জড়িত না।

কেস 1: রিটার্ন টাইপটি যদি কোনও আদিম ডেটা টাইপ বা অকার্যকর হয়।

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

কেস 2: যদি রিটার্নের ধরণটি ডেটা প্রকার থেকে প্রাপ্ত হয়:

আউটপুট: পিতামাত্ত শ্রেণীর পদ্ধতির রিটার্ন টাইপটি যদি উত্পন্ন ধরণের হয় তবে ওভাররাইডিং পদ্ধতির রিটার্ন টাইপ হ'ল উপজাতের ধরণের উপাত্তের জাতীয় উপাত্তের ধরণের একই রকম। উদাহরণস্বরূপ ধরুন আমার A এর একটি শ্রেণি আছে, B A এর একটি উপক্লাস, C হল B এর সাথে একটি সাবক্লাস এবং D হ'ল subclass; তারপরে যদি সুপার ক্লাসটি A টাইপ করে ফিরে আসে তবে ওভাররাইডিং পদ্ধতিটি সাবক্লাসটি এ, বি, সি বা ডি টাইপ অর্থাৎ তার উপ প্রকারগুলি ফিরিয়ে দিতে পারে। একে কোভারিয়েন্স নামেও ডাকা হয়।


আপনার এই মন্তব্যটি দ্ব্যর্থক, আমার কাছে ক্লাস এবি, এসিতে সাবক্লাস বিডি-তে সাবক্লাস, এর অর্থ ক্লাস এবি হ'ল এসি বা এ-এর
উপক্লাস

5

হ্যাঁ এটি সম্ভব .. পিতামাত্ত শ্রেণীর পদ্ধতি রিটার্নের ধরণটি
শিশু শ্রেণির পদ্ধতি রিটার্নের ধরণের একটি দুর্দান্ত ধরণের হলেই রিটার্নের ধরণটি আলাদা হতে পারে
means

class ParentClass {
    public Circle() method1() {
        return new Cirlce();
    }
}

class ChildClass extends ParentClass {
    public Square method1() {
        return new Square();
    }
}

Class Circle {

}

class Square extends Circle {

}


যদি এটি হয় তবে ভিন্ন ভিন্ন রিটার্নের অনুমতি দেওয়া যেতে পারে ...


2

ঠিক আছে, উত্তর হ্যাঁ ... এবং না।

প্রশ্নের উপর নির্ভর করে। এখানে প্রত্যেকে জাভা> = 5 সম্পর্কিত উত্তর দিয়েছে এবং কেউ কেউ উল্লেখ করেছেন যে জাভা <5 কোভেরিয়েন্ট রিটার্নের ধরণের বৈশিষ্ট্যযুক্ত না।

আসলে, জাভা ভাষার স্পেস> = 5 এটিকে সমর্থন করে তবে জাভা রানটাইম তা সমর্থন করে না। বিশেষত, সমবায় রিটার্নের ধরণগুলি সমর্থন করতে JVM আপডেট করা হয়নি updated

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

এবং কোভেরিয়েন্ট রিটার্নের ধরণগুলি জাভাক দ্বারা যুক্ত আরও সিনট্যাকটিক চিনি।

উদাহরণস্বরূপ, এটি সংকলন করার সময়:

class Base {
  Object get() { return null; }
}

class Derived extends Base {
  @Override
  @SomeAnnotation
  Integer get() { return null; }
}

জাভাক দুটি উত্পন্ন শ্রেণিতে পদ্ধতি অর্জন করবে:

Integer Integer:Derived:get() { return null; }
synthetic bridge Object Object:Derived:get() { return Integer:Derived:get(); }

উত্পন্ন সেতু পদ্ধতি (চিহ্নিত syntheticএবং bridgeবাইটোকোডে) আসলে এটিই ওভাররাইড হয় Object:Base:get()কারণ, জেভিএমের কাছে, বিভিন্ন রিটার্নের ধরণের পদ্ধতিগুলি সম্পূর্ণ স্বাধীন এবং একে অপরকে ওভাররাইড করতে পারে না। প্রত্যাশিত আচরণ সরবরাহ করতে, ব্রিজটি কেবল আপনার "আসল" পদ্ধতিটিকে কল করে। উপরের উদাহরণে, জাভ্যাক @ সোমো অ্যানোটেশন দিয়ে ডেরিভডে ব্রিজ এবং আসল পদ্ধতি উভয়ই বর্ননা দেবে।

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

(বিটিডাব্লু, ক্ষেত্রের প্রকারগুলি একইভাবে বাইটোকোডে ক্ষেত্রের স্বাক্ষরের অংশ, সুতরাং বিভিন্ন ধরণের বিভিন্ন ক্ষেত্র থাকা বৈধ তবে একক বাইটকোড শ্রেণীর মধ্যে একই নামকরণ করা হয়েছে))

সুতরাং আপনার প্রশ্নের সম্পূর্ণরূপে জবাব দিতে: জেভিএম কোভারিয়েন্ট রিটার্নের ধরণগুলিকে সমর্থন করে না, তবে জাভ্যাক> = 5 মিষ্টি সিনট্যাকটিক চিনির আবরণ দিয়ে সংকলন সময়ে এটি জাল করে।


1

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

কোডের উদাহরণ


                                                                                                            class Alpha {
          Alpha doStuff(char c) {
                  return new Alpha();
              }
           }
             class Beta extends Alpha {
                    Beta doStuff(char c) { // legal override in Java 1.5
                    return new Beta();
                    }
             } } 
জাভা 5, এই কোডটি সংকলন করবে। আপনি যদি এই কোডটি একটি 1.4 সংকলক দিয়ে সংকলন করার চেষ্টা করছেন তবে বলবেন যে বেমানান রিটার্ন টাইপ ব্যবহার করার চেষ্টা করা হচ্ছে - Sandeep1987 1 min ago


1

অন্যান্য উত্তরগুলি সমস্ত সঠিক, তবে আশ্চর্যরূপে সমস্ত এখানে তাত্ত্বিক দিকটি ছেড়ে চলেছে: রিটার্নের ধরণগুলি আলাদা হতে পারে তবে লিসকভ সাবস্টিটিউশন নীতিমালার কারণে তারা কেবল সুপার ক্লাসে ব্যবহৃত ধরণের সীমাবদ্ধ করতে পারে ।

এটি অত্যন্ত সহজ: যখন আপনার কাছে "ক্লায়েন্ট" কোড থাকে যা কিছু পদ্ধতি কল করে:

int foo = someBar.bar();

তারপরে উপরেরগুলিকে কাজ করতে হবে (এবং এমন কিছু প্রত্যাবর্তন করতে হবে intযা বাস্তবায়নের জন্য অনুরোধ bar()করা উচিত ।

অর্থ: যদি কোনও বার সাবক্লাস থাকে যা ওভাররাইড করে bar()তবে আপনাকে এখনও এমন কিছু ফিরিয়ে দিতে হবে যা "কলার কোড" ভঙ্গ করে না।

অন্য কথায়: ধরুন যে বেসটি bar()পূর্বাবস্থায় ফিরে আসার কথা। তারপরে একটি সাবক্লাস ফিরে আসতে পারে short- তবে এটি নয় longকারণ কলকারীরা একটি shortমানের সাথে জরিমানা করবে , তবে একটি নয় long!


0

রিটার্নের ধরণটি সুপারক্লাসে মূল ওভাররাইড পদ্ধতিতে ঘোষিত রিটার্ন টাইপের মতো বা একটি উপ-টাইপের মতো হতে হবে।


5
আপনার দুটি উত্তর একত্রিত করা উচিত।
theblang

0

হ্যাঁ এটা সম্ভব হতে পারে

class base {

 base show(){

System.out.println("base class");

return new base();

}
}

class sub extends base{

sub show(){

    System.out.println("sub class");

    return new sub();

 }
}

class inheritance{

 public static void main(String []args) {

        sub obj=new sub();

            obj.show();
 }
}

0

হ্যাঁ. ওভাররাইড পদ্ধতিগুলির জন্য পৃথক ফেরতের ধরণ থাকা সম্ভব।

তবে সীমাবদ্ধতা হ'ল ওভাররাইড হওয়া পদ্ধতিতে অবশ্যই একটি রিটার্ন টাইপ থাকতে হবে যা আসল পদ্ধতির রিটার্ন টাইপের আরও নির্দিষ্ট ধরণের।

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

উদাহরণ স্বরূপ :

public class Foo{

   //method which returns Foo
  Foo getFoo(){
      //your code         
  }

}

 public class subFoo extends Foo{

  //Overridden method which returns subclass of Foo
  @Override
  subFoo getFoo(){
      //your code         
  }

}

তবে এটি কেবল সাবক্লাসের মধ্যেই সীমাবদ্ধ নয় ven যে ইন্টারফেস প্রয়োগ করে এমন প্রতিটি ক্লাসই ইন্টারফেসের একটি নির্দিষ্ট ধরণের এবং সুতরাং ইন্টারফেসটি প্রত্যাশিত যেখানে প্রত্যাবর্তন টাইপ হতে পারে।

উদাহরণ স্বরূপ :

public interface Foo{

   //method which returns Foo
  Foo getFoo();

}

 public class Fizz implements Foo{

  //Overridden method which returns Fizz(as it implements Foo)
  @Override
  Fizz getFoo(){
      //your code         
  }

}

0
class Phone {
    public Phone getMsg() {
        System.out.println("phone...");
        return new Phone();
    }
}

class Samsung extends Phone{
    @Override
    public Samsung getMsg() {
        System.out.println("samsung...");
        return new Samsung();
    }
    
    public static void main(String[] args) {
        Phone p=new Samsung();
        p.getMsg();
    }
}

কিভাবে এই প্রশ্নের উত্তর দেয়?
আনব্র্যান্ডযুক্ত ম্যানচেস্টার

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