كيف يمكنني استدعاء مُنشئ واحد من آخر في Java؟


Answers

باستخدام this(args) . النمط المفضل هو العمل من أصغر مُنشئ إلى الأكبر.

public class Cons {

 public Cons() {
  // A no arguments constructor that sends default values to the largest
  this(madeUpArg1Value,madeUpArg2Value,madeUpArg3Value);
 }

 public Cons(int arg1, int arg2) {
  // An example of a partial constructor that uses the passed in arguments
  // and sends a hidden default value to the largest
  this(arg1,arg2, madeUpArg3Value);
 }

 // Largest constructor that does the work
 public Cons(int arg1, int arg2, int arg3) {
  this.arg1 = arg1;
  this.arg2 = arg2;
  this.arg3 = arg3;
 }
}

يمكنك أيضًا استخدام طريقة مؤيدة حديثًا للقيمة أو فقط "من":

public class Cons {
 public static Cons newCons(int arg1,...) {
  // This function is commonly called valueOf, like Integer.valueOf(..)
  // More recently called "of", like EnumSet.of(..)
  Cons c = new Cons(...);
  c.setArg1(....);
  return c;
 }
} 

للاتصال بفئة ممتازة ، استخدم super(asdf) . يجب أن تكون المكالمة إلى السوبر هي المكالمة الأولى في المُنشئ أو ستحصل على خطأ في التحويل البرمجي.

Question

هل من الممكن استدعاء مُنشئ من آخر (ضمن نفس الفئة ، وليس من فئة فرعية)؟ إذا نعم كيف؟ وماذا يمكن أن يكون أفضل طريقة لاستدعاء منشئ آخر (إذا كان هناك العديد من الطرق للقيام بذلك)؟




عندما أحتاج إلى استدعاء مُنشئ آخر من داخل التعليمة البرمجية (وليس في السطر الأول) ، عادةً ما استخدم طريقة مساعد مثل هذه:

class MyClass {
   int field;


   MyClass() {
      init(0);
   } 
   MyClass(int value) {
      if (value<0) {
          init(0);
      } 
      else { 
          init(value);
      }
   }
   void init(int x) {
      field = x;
   }
}

ولكن في معظم الأحيان أحاول القيام بذلك في الاتجاه الآخر عن طريق استدعاء الصانعين الأكثر تعقيدًا من الأبسطين في السطور الأولى ، إلى أقصى حد ممكن. على سبيل المثال أعلاه

class MyClass {
   int field;

   MyClass(int value) {
      if (value<0)
         field = 0;
      else
         field = value;
   }
   MyClass() {
      this(0);
   }
}



هناك أنماط تصميم تغطي الحاجة إلى البناء المعقد - إذا لم يكن بالإمكان القيام به بإيجاز ، أو إنشاء طريقة مصنع أو فصل مصنع.

مع أحدث java وإضافة lambdas ، من السهل إنشاء مُنشئ يمكنه قبول أي رمز تهيئة تريده.

class LambdaInitedClass {

   public LamdaInitedClass(Consumer<LambdaInitedClass> init) {
       init.accept(this);
   }
}

اتصل بها ...

 new LambdaInitedClass(l -> { // init l any way you want });



أعرف أن هناك الكثير من الأمثلة على هذا السؤال ولكن ما وجدته أضعه هنا لمشاركة الفكرة. هناك طريقتان لسلسلة منشئ. في نفس الفصل ، يمكنك استخدام هذه الكلمة. في الوراثة ، تحتاج إلى استخدام الكلمة الرئيسية الفائقة.

    import java.util.*;
    import java.lang.*;

    class Test
    {  
        public static void main(String args[])
        {
            Dog d = new Dog(); // Both Calling Same Constructor of Parent Class i.e. 0 args Constructor.
            Dog cs = new Dog("Bite"); // Both Calling Same Constructor of Parent Class i.e. 0 args Constructor.

            // You need to Explicitly tell the java compiler to use Argument constructor so you need to use "super" key word
            System.out.println("------------------------------");
            Cat c = new Cat();
            Cat caty = new Cat("10");

            System.out.println("------------------------------");
            // Self s = new Self();
            Self ss = new Self("self");
        }
    }

    class Animal
    {
        String i;

        public Animal()
        {
            i = "10";
            System.out.println("Animal Constructor :" +i);
        }
        public Animal(String h)
        {
            i = "20";
            System.out.println("Animal Constructor Habit :"+ i);
        }
    }

    class Dog extends Animal
    {
        public Dog()
        {
            System.out.println("Dog Constructor");
        }
        public Dog(String h)
        {
            System.out.println("Dog Constructor with habit");
        }
    }

    class Cat extends Animal
    {
        public Cat()
        {
            System.out.println("Cat Constructor");
        }
        public Cat(String i)
        {
            super(i); // Calling Super Class Paremetrize Constructor.
            System.out.println("Cat Constructor with habit");
        }
    }

    class Self
    {
        public Self()
        {
            System.out.println("Self Constructor");
        }
        public Self(String h)
        {
            this(); // Explicitly calling 0 args constructor. 
            System.out.println("Slef Constructor with value");
        }
    }



يمكنك إنشاء منشئ آخر من نفس الفئة باستخدام الكلمة الأساسية "هذه". مثال -

class This1
{
    This1()
    {
        this("Hello");
        System.out.println("Default constructor..");
    }
    This1(int a)
    {
        this();
        System.out.println("int as arg constructor.."); 
    }
    This1(String s)
    {
        System.out.println("string as arg constructor..");  
    }

    public static void main(String args[])
    {
        new This1(100);
    }
}

الإخراج - سلسلة كما هو مُنشئ arg .. المُنشئ الافتراضي .. int كـ arg مُنشئ.




يمكن استخدام الكلمة الأساسية هذا لاستدعاء مُنشئ من مُنشئ ، عند كتابة عدة مُنشئ لفئة ، هناك أوقات تريد فيها استدعاء مُنشئ من آخر لتفادي تكرار التعليمات البرمجية.

رفع الصوت عاليا هو الرابط الذي أشرح موضوع آخر حول منشئ و getters () و setters () واستخدمت فئة مع اثنين من الصانعين. آمل أن تكون التوضيحات والأمثلة مفيدة لك.

طرق الضبط أو المنشئات




كما قال الجميع بالفعل ، يمكنك استخدام this(…) ، والذي يسمى استدعاء صريح منشئ .

ومع ذلك ، ضع في اعتبارك أنه ضمن بيان الاستدعاء صريح منشئ قد لا تشير إلى

  • أي متغيرات الحالة أو
  • أي طرق سبيل المثال أو
  • أي فصول داخلية معلن عنها في هذه الفئة أو أي طبقة متميزة ، أو
  • this أو
  • super .

كما ورد في JLS (§8.8.7.1).




نعم ، من الممكن الاتصال بمنشئ من آخر باستخدام this()

class Example{
   private int a = 1;
   Example(){
        this(5); //here another constructor called based on constructor argument
        System.out.println("number a is "+a);   
   }
   Example(int b){
        System.out.println("number b is "+b);
   }



Links