Sök…


Introduktion

Även om det inte krävs är konstruktörer i Java metoder som erkänns av kompilatorn för att instansera specifika värden för klassen som kan vara avgörande för objektets roll. Detta ämne visar korrekt användning av Java-klasskonstruktörer.

Anmärkningar

Java Language Specification talar långt om den exakta karaktären av konstruktørsemantik. De finns i JLS §8.8

Standardkonstruktör

"Standard" för konstruktörer är att de inte har några argument. Om du inte anger någon konstruktör genererar kompilatorn en standardkonstruktör åt dig.
Detta innebär att följande två utdrag är semantiskt likvärdiga:

public class TestClass {
    private String test;
}
public class TestClass {
    private String test;
    public TestClass() {

    }
}

Synligheten för standardkonstruktören är densamma som klassens synlighet. Således har ett klassdefinierat paket-privat en paket-privat standardkonstruktör

Men om du har en icke-standardkonstruktor genererar kompilatorn inte en standardkonstruktör åt dig. Så dessa är inte likvärdiga:

public class TestClass {
    private String test;
    public TestClass(String arg) {
    }
}
public class TestClass {
    private String test;
    public TestClass() {
    }
    public TestClass(String arg) {
    }
}

Se upp för att den genererade konstruktören inte utför någon standardisering som inte är standard. Detta innebär att alla fält i din klass har sitt standardvärde, såvida de inte har en initialisering.

public class TestClass {

    private String testData;

    public TestClass() {
        testData = "Test"
    }
}

Konstruktörer kallas så här:

TestClass testClass = new TestClass();

Konstruktör med argument

Konstruktörer kan skapas med alla typer av argument.

public class TestClass {

    private String testData;

    public TestClass(String testData) {
        this.testData = testData;
    }
}

Kallade så här:

TestClass testClass = new TestClass("Test Data");

En klass kan ha flera konstruktörer med olika signaturer. För att kedja konstruktörssamtal (ring en annan konstruktör av samma klass när du instigerar) använd this() .

public class TestClass {

    private String testData;

    public TestClass(String testData) {
        this.testData = testData;
    }

    public TestClass() {
        this("Test"); // testData defaults to "Test"
    }
}

Kallade så här:

TestClass testClass1 = new TestClass("Test Data");
TestClass testClass2 = new TestClass();

Ring föräldrakonstruktör

Säg att du har en föräldraklass och en barnklass. För att konstruera en Child-instans krävs det alltid att någon föräldrakonstruktör körs i början av Child-konstruktören. Vi kan välja den föräldrakonstruktör vi vill genom att uttryckligen kalla super(...) med lämpliga argument som vårt första uttalande av barnkonstruktörer. Genom att göra detta sparar vi tid genom att återanvända förälderklassens konstruktör istället för att skriva om samma kod i barnklassens konstruktör.

Utan super(...) metod:

(implicit, no-args version super() kallas osynligt)

class Parent {
    private String name;
    private int age;
    
    public Parent() {} // necessary because we call super() without arguments
    
    public Parent(String tName, int tAge) {
        name = tName;
        age = tAge;
    }
}

// This does not even compile, because name and age are private,
// making them invisible even to the child class.
class Child extends Parent {
    public Child() {
        // compiler implicitly calls super() here
        name = "John";
        age = 42;
    }
}

Med super() -metod:

class Parent {
    private String name;
    private int age;
    public Parent(String tName, int tAge) {
        name = tName;
        age = tAge;
    }
}

class Child extends Parent {
    public Child() {
        super("John", 42);   // explicit super-call
    }
}

Obs: Samtal till en annan konstruktör (kedja) eller superkonstruktören MÅSTE vara det första uttalandet inuti konstruktören.

Om du uttryckligen kallar super(...) måste en matchande föräldrakonstruktör existera (det är enkelt, eller hur?).

Om du inte kallar någon super(...) konstruktör uttryckligen måste din förälderklass ha en no-args-konstruktör - och detta kan antingen skrivas uttryckligen eller skapas som standard av kompilatorn om förälderklassen inte tillhandahåller alla konstruktörer.

class Parent{
    public Parent(String tName, int tAge) {}
}

class Child extends Parent{
    public Child(){}
}

Klassen förälder har ingen standardkonstruktör, så kompilatorn kan inte lägga till super i barnkonstruktören. Denna kod kommer inte att sammanställas. Du måste byta konstruktörer så att de passar båda sidor, eller skriva ditt eget super , så:

class Child extends Parent{
    public Child(){
          super("",0);
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow