Soru Java'da başka bir kurucuyu nasıl arayabilirim?


Bir kurucuyu diğerinden (aynı sınıfta, bir alt sınıftan değil) aramak mümkün mü? Evet ise nasıl? Ve başka bir kurucu çağırmanın en iyi yolu ne olabilir (bunu yapmak için birkaç yol varsa)?


1828
2017-11-12 20:10


Menşei


Bunu da kontrol et: yegor256.com/2015/05/28/one-primary-constructor.html - yegor256
Sorunun öncülünün yanlış olduğuna inanıyorum. Bir kurucu içinde bir kurucu çağırmak yerine, Fabrika modelini kullanın. Statik bir fabrika yöntemi ilk önce tüm alt düzey nesneleri oluşturur. Daha sonra fabrika çağrısından geri dönen üst düzey nesneleri oluşturur. Bu teknik, karmaşıklığı, bakım, netlik ve testlere yardımcı olan modelden kaldırır. - David Medinets


Cevaplar:


Evet mümkün:

public class Foo {
    private int x;

    public Foo() {
        this(1);
    }

    public Foo(int x) {
        this.x = x;
    }
}

Aynı sınıfta bir tanesinin yerine belirli bir süper sınıflandırıcıya zincirleme yapmak için super yerine this. Bunu not et sadece bir kurucuya zincirleme yapabilirsiniz, ve Yapıcı gövdesindeki ilk ifade olmalı.

Ayrıca bakınız bu ilgili soruC # olan ama aynı prensiplerin geçerli olduğu yer.


2468
2017-11-12 20:12



Yani her ikisi de ilk satır olması gerektiğinden, süper bir kurucu ve aynı sınıftan başka bir kurucu çağırmak mümkün değil miydi? - gsingh2011
@ gsingh2011: Gerçekten. Sadece zincirleme yapabilirsiniz bir diğer kurucu. - Jon Skeet
Bu ilk satırda görünmelidir, ancak çağrılmadan önce yapıcıda hesaplamalar yapabilirsiniz: İlk satırda bu () argümanlarında statik yöntemler kullanabilir ve aramadan önce yapılması gereken herhangi bir hesaplamayı kapsülleyebilirsiniz. Bu statik yöntemde diğer kurucuya. (Bunu ayrı bir cevap olarak ekledim). - Christian Fries
@ gsingh2011 Geç olduğunu biliyorum ama bir yol olarak, bu (...) kullanarak aşırı yüklü yapıcıyı çağırabilir ve sonra aşırı yüklü kurucuda, süper (...) kullanarak temel sınıf 'yapıcı bir çağrı yapabilirsiniz - Ali
@JustinTime: Yine, "oluşturma" ile neyi kastettiğinize bağlı olarak değişir - nesne, belleğinin tahsis edildiği ve türün herhangi bir yapıcı gövdesi yürütülmeden önce ayarlandığı "oluşturulur". Oluşturucular yaratılıştan ziyade başlatılıyor. Özellikle, nesnenin türü, başlangıçtan itibaren "nihai" tipidir - bu nedenle, kuruculardan herhangi bir sanal yöntem çağırırsanız, adlandırılan en özel geçersiz kılma elde edersiniz. Bunun C ++ 'dan farklı olduğuna inanıyorum. - Jon Skeet


kullanma this(args). Tercih edilen model, en küçük kurucudan en büyüğe doğru çalışmaktır.

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;
 }
}

Ayrıca, yakın zaman önce değinilen bir değer biçme yaklaşımı veya yalnızca "aşağıdakilerden" birini kullanabilirsiniz:

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;
 }
} 

Bir süper sınıfı aramak için super(asdf). Süper çağrı, yapıcıdaki ilk çağrı olmalı ya da bir derleyici hatası alacaksınız.


198
2018-03-11 20:33



Birçok yapıcı parametresi kullanılıyorsa, bir oluşturucu düşünün. Joshua Bloch tarafından "Etkin Java" nın 2. maddesine bakınız. - koppor
Fabrika yöntemini kullanarak son yaklaşımın uygulanması ile ilgili problem, newCons, bir nesnenin durumunu değiştirmeye çalışıyorsunuz setArg1(...)Bu, büyük olasılıkla kendi alanları final olarak ayarlanmış olmalıdır. Bir nesnenin mümkün olduğu kadar değişmez kalmasını sağladığımızdan, tam olarak olmasa da, bir kurucu model bu sorunu daha doğru bir şekilde ele alacaktır. - YoYo
Bunu yapmak istemez miydiniz :: public Cons () {this (madeUpArg1Value, madeUpArg2Value); } - LordHieros
Başlatma en azdan en büyüğe doğru devam etmelidir - zincirin bir çok parametreli kurucuya çağrılmasını sağlayan varsayılan bir kurucuyu asla kullanmam. Olması gereken şey, tüm kurucuların ya varsayılan ya da daha az parametreli bir yapıcıyı çağırmasıdır. - Rodney P. Barbati
@ RodneyP.Barbati Alt-ariteli kurucular için daha fazla aritmetik kurucular çağırmak için Java'da oldukça yaygındır ve sonra başka hiçbir şey yapmayın. eğer bir K sınıfı varsa, örneğin iki son alan a, b, sonra "genel kurucu" olurdu K(A a, B b) { this.a = a; this.b = b; }. O zaman eğer b makul bir varsayılan var, tek argüman kurucu olabilir K(A a) { this(a, DEFAULT_B); }ve bir varsayılan varsa a Ayrıca, varsayılan bir kurucu var: K() { this(DEFAULT_A); }. Java'da oldukça yaygın bir kongre. - Joshua Taylor


[Not: Diğer yanıtlarda görmediğim bir yönünü eklemek istiyorum: bu () ilk satırda olması gereken gereksinimin sınırlamalarının nasıl üstesinden gelinmesi).]

Java'da aynı sınıftan başka bir kurucu, bir kurucunun üzerinden çağrılabilir. this(). Ancak şunu unutmayın this ilk satırda olmak zorunda.

public class MyClass {

  public MyClass(double argument1, double argument2) {
    this(argument1, argument2, 0.0);
  }

  public MyClass(double argument1, double argument2, double argument3) {
    this.argument1 = argument1;
    this.argument2 = argument2;
    this.argument3 = argument3;
  }
}

o this İlk satırda görünmesi gereken büyük bir sınırlama gibidir, ancak diğer kurucuların argümanlarını statik yöntemlerle oluşturabilirsiniz. Örneğin:

public class MyClass {

  public MyClass(double argument1, double argument2) {
    this(argument1, argument2, getDefaultArg3(argument1, argument2));
  }

  public MyClass(double argument1, double argument2, double argument3) {
    this.argument1 = argument1;
    this.argument2 = argument2;
    this.argument3 = argument3;
  }

  private static double getDefaultArg3(double argument1, double argument2) {
    double argument3 = 0;

    // Calculate argument3 here if you like.

    return argument3;

  }

}

177
2018-04-23 23:12



Doğru olan argüman değerleri için karmaşık hesaplamalar yapmak için bu şekilde statik yöntemleri çağırabileceğiniz doğrudur. Ancak, eğer kurucu heyetinden önce bu kodun gerekli olduğu hissediliyorsa (this(...)) o zaman korkunç bir hatanın bir yere getirildiğini ve belki de tasarımın biraz yeniden düşünülmesini gerektirdiğini düşünmek mantıklı olurdu. - Engineer Dollery
Buna katılıyorum çok Karmaşık dönüşüm muhtemelen bir tasarım sorununu gösterir. Fakat 1) bunun yararlı olabileceği bazı basit dönüşümler vardır - tüm kurucular başkaları üzerinde sadece doğrusal bir projeksiyon değildir ve 2) bu bilginin eski kodun desteklenmesi gibi ele alınabileceği başka durumlar da olabilir. (Ben senin sonucuna katılıyorum rağmen, neden aşağı bir oy haklı olacağını görmüyorum). - Christian Fries
Bu tam olarak önerdiğim şeyin tersidir - hiçbir parametre yapıcısı tüm değerleri varsayılan değerlere başlamalıdır. 2 parametre yapıcısı, hiçbir param yapıcısını çağırmamalı, ardından aldığı 2 değeri başlatmalıdır. 3 parametre yapıcısı, 2 parametre yapıcısını çağırmalı, ardından 3 değerini aldığı değere başlatmalıdır. Gösterildiği gibi yapmak, başka bir parametre eklemek için çok daha fazla iş yapmanız gerektiği anlamına gelir. - Rodney P. Barbati
@ RodneyP.Barbati: Bunu açıkladığınız şekilde birkaç sorun görüyorum: a) Bu şekilde bir kurucuda statik yöntemin kullanımını göstermek mümkün değildir (ve bu örnekte niyeti); -) ve b) Eğer yolunuzu yaparsanız, alanlar final (son alanlar sadece bir kez başlatılabilir). - Christian Fries
@ RodneyP.Barbati: Diğer iki yön: c) Her zaman nesne başlatmayı en genel kurucu olan tek bir noktada yapman gerektiğine inanıyorum. Nesne başlatması karmaşık bir görev gerektiriyorsa (nesne init olmuyorsa) veya bazı kaynakları (bir dosya gibi) kontrol etmek ya da satın almaksa, bunu yalnızca bir kez yapmaktan hoşlanırsınız. Ve d) Başlangıcın argüman1 değerinin argüman3 değerine bağlı olduğu başka bir argümanı (argüman4) ekleyiniz. Sizin durumunuzda tüm kurucuları değiştirmek zorunda kalacaksınız, oysa burada sadece bir tane eklemeniz ve 3-arg çağrısına izin vermeniz gerekir. -arg kurucu. - Christian Fries


Kodun içinden başka bir kurucu çağırmam gerektiğinde (ilk satırda değil), genellikle şu şekilde bir yardımcı yöntem kullanırım:

class MyClass {
   int field;


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

Ancak çoğu zaman, daha karmaşık kurucuları ilk satırdaki daha basit olanlardan, mümkün olduğu ölçüde çağırarak bunu yapmaya çalışırım. Yukarıdaki örnek için

class MyClass {
   int field;

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

36
2018-05-26 15:09





Bir kurucuda, this Aynı sınıftaki başka bir kurucu çağırmak için anahtar kelime. Bunu yapmak bir açık kurucu çağrısı.

Nesneler bölümünden farklı bir uygulama ile başka bir Dikdörtgen sınıfı.

public class Rectangle {
    private int x, y;
    private int width, height;

    public Rectangle() {
        this(1, 1);
    }
    public Rectangle(int width, int height) {
        this( 0,0,width, height);
    }
    public Rectangle(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

}

Bu sınıf bir dizi kurucu içerir. Her kurucu, dikdörtgenin üye değişkenlerinin bazılarını veya tümünü başlatır.


23
2018-05-07 22:52



neden ikinci kurucuyu aramıyorsun Rectangle(int width, int height) içinde Rectangle() yerine Rectangle(int x, int y, int width, int height) ? - ANjaNA
Varsayılan kurucu, üst düzey kurucular hakkında bilgi sahibi olmamalıdır - bu varsayılan değerdir. Bu kalıbı takiben, yeni bir tane eklediğinizde bir veya daha fazla mevcut kurucuyu değiştirmeniz gerekir. Örneğin, bir lineWidth değeri ekleyin ve ne demek istediğimi görün. Ancak, varsayılan değerlerin tüm değerlerini başlatmasını ve yapıcı zincirini tersine çevirmesini sağlayın, her kurucu öğeyi daha önce görürsünüz ve yalnızca özel olarak desteklediği değerleri başlatırsınız - Mevcut olanları değiştirmeden yeni bir tane ekleyebilirsiniz. Java'da iyi desenler olmayan birçok ortak model vardır. - Rodney P. Barbati


Herkes zaten söylediğine göre this(…)denir açık kurucu çağrısı.

Ancak, unutmayın ki böyle bir açık yapıcı çağırma deyiminde başvurmuyor olabilirsiniz

  • herhangi örnek değişkenler veya
  • herhangi örnek yöntemler veya
  • herhangi iç sınıflar bu sınıfta veya herhangi bir üst sınıfta beyan edilmiş veya
  • this veya
  • super.

JLS'de belirtildiği gibi (§8.8.7.1).


12
2017-11-21 13:14





Sana kolay bir şekilde anlatacağım

Var iki kurucular türleri:

  1. Varsayılan kurucu
  2. Parametreli kurucu

Bir örnekte açıklayacağım

class ConstructorDemo 
{
      ConstructorDemo()//Default Constructor
      {
         System.out.println("D.constructor ");
      }

      ConstructorDemo(int k)//Parameterized constructor
      {
         this();//-------------(1)
         System.out.println("P.Constructor ="+k);       
      }

      public static void main(String[] args) 
      {
         //this(); error because "must be first statement in constructor
         new ConstructorDemo();//-------(2)
         ConstructorDemo g=new ConstructorDemo(3);---(3)    
       }
   }                  

Yukarıdaki örnekte 3 çeşit arama yaptım

  1. this () buna çağrı yapıcıda ilk ifade olmalı
  2. Bu İsim daha az Nesne. Bu otomatik olarak varsayılan yapıcıyı çağırır. 3. Bu, Parametreli yapıcıyı çağırır.

Not: Bu yapıcıdaki ilk ifadedir.


7
2017-11-27 19:01



Ana yöntemde aşağıdakilere sahipsiniz: //bu(); "çünkü kurucunun ilk ifadesi olmalı"  Bu ifade çok anlamlı değil. Bunu söylemeye çalışıyorsan bu() içeriden çağırılamaz ana yöntem, o zaman evet, çünkü ana statik ve referansı olmayacaktır bu() - S R Chaitanya
Bu benim taşıdığım şey .. @SRChaitanya yorumunuzdaki yenilik nedir? - Shivanandam Sirmarigari
onu zayıf bir şekilde taşıyorsunuz - Kevin Van Dyck


"Bu" anahtar sözcüğünü kullanarak aynı sınıftaki başka bir kurucudan bir kurucu yapabilirsiniz. Örnek -

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);
    }
}

Çıktı - arg constructor olarak dizge .. Varsayılan kurucu .. int yapıcı olarak int.


5
2018-03-03 09:27





Başka bir kurucudan kurucu çağırılıyor

class MyConstructorDemo extends ConstructorDemo
{
    MyConstructorDemo()
    {
        this("calling another constructor");
    }
    MyConstructorDemo(String arg)
    {
        System.out.print("This is passed String by another constructor :"+arg);
    }
}

Ayrıca kullanarak ana kurucuyu arayabilirsiniz super() aramak


5
2017-09-13 05:48





Evet, başka bir kurucunun kullanılması ile 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);
   }

5
2017-11-16 16:14



Bu işe yaramıyor. Bu (5) çağrı, kurucudaki ilk satır olmalıdır. - chandsie