super () ใน Java


222

จะถูกsuper()นำมาใช้เพื่อเรียก constructor แม่? super()กรุณาอธิบาย


1
จะต้องมีความเฉพาะเจาะจงมากขึ้นหรือเพียงแค่อ่านเอกสาร ...
มนู

ในการเชื่อมต่อกับการโทร super () ตรวจสอบคำตอบนี้เช่นกัน stackoverflow.com/questions/34349164/…
Vishrant

อธิบายที่นี่: Java: การเรียก super ()
aioobe

คำตอบ:


267

super() เรียกผู้สร้างหลักที่ไม่มีข้อโต้แย้ง

มันสามารถใช้กับข้อโต้แย้ง Ie super(argument1)และมันจะเรียกนวกรรมิกที่ยอมรับ 1 พารามิเตอร์ของประเภทของargument1(ถ้ามี)

นอกจากนี้ยังสามารถใช้เรียกวิธีการจากผู้ปกครอง กล่าวคือsuper.aMethod()

ข้อมูลเพิ่มเติมและการสอนที่นี่


9
หมายเหตุ: ในกรณีแรกคลาสพาเรนต์จะต้องไม่มีคอนสตรัคเตอร์อาร์กิวเมนต์ที่ล้มเหลวซึ่งจะทำให้เกิดข้อผิดพลาดในการคอมไพล์
KNU

นิด: คำศัพท์ผู้ปกครอง / เด็กไม่ดีสำหรับลำดับชั้นของชั้นเรียน (เด็กไม่ใช่พ่อ)
aioobe

มีข้อ จำกัด ใดบ้างที่สามารถใช้ super ได้?
Aaron Franke

2
@VivekChavda แน่ใจว่าเด็ก ๆสามารถเป็นผู้ปกครองได้เช่นเดียวกับนักเรียนที่สามารถเป็นครูเป็นต้น แต่ฉันคิดว่าคุณเข้าใจความแตกต่างเมื่อเทียบกับสัตว์ -> สุนัขเป็นต้น สุนัขจำเป็นต้องเป็นสัตว์ โดยทั่วไปแล้วผู้ปกครอง / เด็กจะมีความสัมพันธ์ ("ผู้ปกครองมีลูก") ในขณะที่สัตว์ / สุนัขคือความสัมพันธ์"คือ" ดูaioo.be/2016/06/29/a-child-is-not-always-a-parent.html
aioobe

2
@AaronFranke "มีข้อ จำกัด ใดบ้างที่สามารถใช้ super ได้หรือไม่" - ใช่super(...)สามารถใช้เป็นคำสั่งแรกใน Constructor เท่านั้น
aioobe

154

ข้อเท็จจริงบางอย่าง:

  1. super() ถูกใช้เพื่อเรียกผู้ปกครองทันที
  2. super() สามารถใช้กับสมาชิกอินสแตนซ์เช่นตัวแปรอินสแตนซ์และวิธีการอินสแตนซ์
  3. super() สามารถใช้ภายใน Constructor เพื่อเรียก Constructor ของคลาส parent

super()ตกลงตอนนี้ขอใช้จริงของจุดเหล่านี้

ตรวจสอบความแตกต่างระหว่างโปรแกรม 1 และ 2 ที่นี่โปรแกรม 2 พิสูจน์ข้อความสั่งแรกของเราsuper()ใน Java

โปรแกรม 1

class Base
{
    int a = 100;
}

class Sup1 extends Base
{
    int a = 200;
    void Show()
    {
        System.out.println(a);
        System.out.println(a);
    }
    public static void main(String[] args)
    {
        new Sup1().Show();
    }
}

เอาท์พุท:

200
200

ตอนนี้ลองดูโปรแกรม 2 และลองหาความแตกต่างที่สำคัญ

โปรแกรม 2

class Base
{
    int a = 100;
}

class Sup2 extends Base
{
    int a = 200;
    void Show()
    {
        System.out.println(super.a);
        System.out.println(a);
    }
    public static void main(String[] args)
    {
        new Sup2().Show();
    }
}

เอาท์พุท:

100
200

ในโปรแกรม 1 เอาต์พุตเป็นคลาสที่ได้รับเท่านั้น ไม่สามารถพิมพ์ตัวแปรของคลาสพื้นฐานหรือคลาสพาเรนต์ แต่ในโปรแกรม 2 เราใช้super()กับตัวแปรaขณะพิมพ์ผลลัพธ์และแทนที่จะพิมพ์ค่าของตัวแปรaของคลาสที่ได้รับมามันพิมพ์ค่าของตัวแปรaของคลาสพื้นฐาน ดังนั้นจึงพิสูจน์ได้ว่าsuper()ใช้เรียกผู้ปกครองทันที

ตกลงตอนนี้ตรวจสอบความแตกต่างระหว่างโปรแกรม 3 และโปรแกรม 4

โปรแกรม 3

class Base
{
    int a = 100;
    void Show()
    {
        System.out.println(a);
    }
}

class Sup3 extends Base
{
    int a = 200;
    void Show()
    {
        System.out.println(a);
    }
    public static void Main(String[] args)
    {
        new Sup3().Show();
    }
}

เอาท์พุท:

200

นี่ออกเป็น 200 เมื่อเราเรียกว่าShow()การShow()ทำงานของชั้นเรียนมาถูกเรียกว่า แต่เราควรทำอย่างไรถ้าเราต้องการเรียกใช้Show()ฟังก์ชันของคลาส parent? ตรวจสอบโปรแกรม 4 สำหรับวิธีแก้ปัญหา

โปรแกรม 4

class Base
{
    int a = 100;
    void Show()
    {
        System.out.println(a);
    }
}

class Sup4 extends Base
{
    int a = 200;
    void Show()
    {
        super.Show();
        System.out.println(a);
    }
    public static void Main(String[] args)
    {
        new Sup4().Show();
    }
}

เอาท์พุท:

100
200

ที่นี่เราได้รับเอาต์พุตสองเอาต์พุตคือ 100 และ 200 เมื่อShow()ฟังก์ชันของคลาสที่ได้รับมาถูกเรียกมันจะเรียกShow()ฟังก์ชั่นของคลาส parent เพราะภายในShow()ฟังก์ชันของคลาสที่ได้รับมาเราเรียกShow()ฟังก์ชันของคลาสพาเรนต์โดยการวางsuperคำหลักก่อนชื่อฟังก์ชัน


4
ทำไมคุณไม่เยื้องตัวอย่างซอร์สโค้ดของคุณ มีเหตุผลที่เฉพาะเจาะจงหรือไม่?
erikbwork

ไม่ erikb ฉันต้องการทราบการใช้ super () ต่อจากนี้เพียงฉันเท่านั้นที่จะ
Mohan

ในชั้นฐานของฉันฉันเกินตัวสร้างด้วยหนึ่ง, สอง, ... ข้อโต้แย้ง
โมฮัน

แต่ในชั้นเรียนที่ฉันได้รับฉันใช้ super () โดยไม่ต้องโต้เถียงใด ๆ อะไรจะเกิดขึ้นไม่ว่าจะเรียกใช้ตัวสร้างเริ่มต้นของคลาสพื้นฐานโดยอัตโนมัติ
Mohan

2
super()ไม่ใช่คำหลัก มันคือการสร้างคอนสตรัค superเป็นคำหลักและ # 1 และ # 2 เหมาะสมกับคำจำกัดความนั้นเท่านั้น
มาร์ควิสแห่ง Lorne

37

บทความที่มา: Java: Calling super ()


ใช่. super(...)จะเรียกใช้ตัวสร้างของซุปเปอร์คลาส

ภาพประกอบ:

ป้อนคำอธิบายรูปภาพที่นี่


ตัวอย่างยืนอยู่คนเดียว:

class Animal {
    public Animal(String arg) {
        System.out.println("Constructing an animal: " + arg);
    }
}

class Dog extends Animal {
    public Dog() {
        super("From Dog constructor");
        System.out.println("Constructing a dog.");
    }
}

public class Test {
    public static void main(String[] a) {
        new Dog();
    }
}

พิมพ์:

Constructing an animal: From Dog constructor
Constructing a dog.

ในคลาสพื้นฐานของฉันฉันโอเวอร์โหลดคอนสตรัคเตอร์ด้วยอาร์กิวเมนต์หนึ่ง, สอง, ... ในคลาสที่ได้รับของฉันฉันใช้ super () โดยไม่ต้องมีอาร์กิวเมนต์ใด ๆ อะไรจะเกิดขึ้นไม่ว่าจะเรียกผู้สร้างเริ่มต้นของคลาสพื้นฐานโดยอัตโนมัติ
Mohan

ใช่. หากคุณเรียกsuper()มันจะเรียกใช้นวกรรมิกของ super-class ที่ไม่มีข้อโต้แย้ง ในทำนองเดียวกันมันจะเรียกใช้คอนสตรัคเตอร์ 1 อาร์กิวเมนต์ถ้าคุณทำเช่นsuper(arg1)นั้นเป็นต้น
aioobe

ถ้าไม่มีคอนสตรัคเตอร์โดยไม่มีการโต้เถียงในคลาสฐานแล้วจะเกิดอะไรขึ้นถ้าคลาสที่ได้รับเรียกซูเปอร์ ()
Mohan

1
ไม่มีอะไร มันจะไม่รวบรวม หากคุณสร้าง Constructor ด้วยตัวเองอัตโนมัติ / default / no-argument-Constructor จะไม่ถูกสร้างขึ้นดังนั้นsuper()จะไม่เป็นการเรียกที่ถูกต้อง
aioobe

29

ใช้ super () ในการเรียกคอนสตรัคเตอร์หลักหรือไม่

ใช่.

กรุณาอธิบายเกี่ยวกับ Super ()

super()เป็นการใช้superคำสำคัญพิเศษซึ่งคุณเรียกใช้ตัวสร้างพาเรนต์แบบไม่มีพารามิเตอร์ โดยทั่วไปแล้วsuperคำสำคัญสามารถใช้เรียกวิธีการแทนที่เข้าถึงฟิลด์ที่ซ่อนอยู่หรือเรียกใช้คอนสตรัคเตอร์ของ superclass

นี่คือการสอนอย่างเป็นทางการ


5
super()จะใช้ในการเรียกผู้สร้างผู้ปกครองsuper.myMethod()จะใช้ในการเรียกวิธีการแทนที่
ฌอนแพทริคฟลอยด์

2
@ seanizer หรือวิธีอื่นใดของ superclass (รวมถึงสถิต) หากอยู่ในขอบเขต super เป็นเพียงการอ้างอิงถึงคลาสพื้นฐานของคุณ
atamanroman

3
ฉันไม่คิดว่า super () ใช้เพื่อเรียกเมธอดคลาสพื้นฐาน คุณสามารถใช้ super.method () ได้
Dheeraj Joshi

@ seanizer, @Deeraj: ขอบคุณสำหรับความคิดเห็นของคุณฉันได้ปรับคำตอบของฉันแล้ว
Heinzi

7

การเรียกว่า no-arguments super constructor เป็นเพียงการเสียพื้นที่หน้าจอและเวลาโปรแกรมเมอร์ คอมไพเลอร์สร้างรหัสเดียวกันทั้งหมดไม่ว่าคุณจะเขียนหรือไม่ก็ตาม

class Explicit() {
    Explicit() {
        super();
    }
}

class Implicit {
    Implicit() {
    }
}

ฉันพบว่ามันใช้ในบางชั้นเรียนไม่แน่ใจว่าจุดประสงค์อะไร คำตอบของคุณมีประโยชน์
iprashant

6

ใช่super()(ตัวพิมพ์เล็ก) เรียกตัวสร้างของคลาสพาเรนต์ คุณสามารถรวมอาร์กิวเมนต์:super(foo, bar)

นอกจากนี้ยังมีsuperคำหลักที่คุณสามารถใช้ในวิธีการที่จะเรียกใช้วิธีการของซูเปอร์คลาส

ของ Google อย่างรวดเร็วสำหรับ "Java super" ผลลัพธ์ในนี้


4

ถูกต้อง. Super ใช้เรียกคอนสตรัคเตอร์หลัก สมมติว่าคุณมีรหัสบล็อกเช่นนั้น

class A{
    int n;
    public A(int x){
        n = x;
    }
}

class B extends A{
    int m;
    public B(int x, int y){
        super(x);
        m = y;
    }
}

จากนั้นคุณสามารถกำหนดค่าให้กับตัวแปรสมาชิก n


2

ฉันได้เห็นคำตอบทั้งหมด แต่ทุกคนลืมพูดถึงจุดสำคัญอย่างหนึ่ง:

ควรเรียกหรือใช้ super () ในบรรทัดแรกของนวกรรมิก


1

Just super (); เพียงอย่างเดียวจะเรียกคอนสตรัคเตอร์เริ่มต้นหากมีซูเปอร์คลาสของคลาสอยู่ แต่คุณต้องเขียน Constructor เริ่มต้นด้วยตัวเองอย่างชัดเจน หากคุณไม่ใช้จาวาจะสร้างให้คุณโดยที่ไม่มีการใช้งานเลยให้บันทึก super (); อ้างถึง Universal Superclass Object และคุณไม่สามารถเรียกมันในคลาสย่อย

public class Alien{
   public Alien(){ //Default constructor is written out by user
   /** Implementation not shown…**/
   }
}

public class WeirdAlien extends Alien{
   public WeirdAlien(){
   super(); //calls the default constructor in Alien.
   }

}

โดยไม่มีข้อโต้แย้ง
มาร์ควิสแห่ง Lorne

1

ตัวอย่างเช่นในซีลีเนียมอัตโนมัติคุณมี PageObject ซึ่งสามารถใช้คอนสตรัคเตอร์ของแม่แบบดังนี้

public class DeveloperSteps extends ScenarioSteps {

public DeveloperSteps(Pages pages) {
    super(pages);
}........

1

ฉันต้องการแบ่งปันกับรหัสทุกอย่างที่ฉันเข้าใจ

คำสำคัญสุดใน java เป็นตัวแปรอ้างอิงที่ใช้ในการอ้างอิงวัตถุระดับผู้ปกครอง มันถูกใช้อย่างมากในบริบทต่อไปนี้: -

1. การใช้ super พร้อมตัวแปร:

class Vehicle 
{ 
    int maxSpeed = 120; 
} 

/* sub class Car extending vehicle */
class Car extends Vehicle 
{ 
    int maxSpeed = 180; 

    void display() 
    { 
        /* print maxSpeed of base class (vehicle) */
        System.out.println("Maximum Speed: " + super.maxSpeed); 
    } 
} 

/* Driver program to test */
class Test 
{ 
    public static void main(String[] args) 
    { 
        Car small = new Car(); 
        small.display(); 
    } 
} 

เอาท์พุท: -

Maximum Speed: 120
  1. ใช้ super ด้วยวิธีการ:
/* Base class Person */
class Person 
{ 
    void message() 
    { 
        System.out.println("This is person class"); 
    } 
} 

/* Subclass Student */
class Student extends Person 
{ 
    void message() 
    { 
        System.out.println("This is student class"); 
    } 

    // Note that display() is only in Student class 
    void display() 
    { 
        // will invoke or call current class message() method 
        message(); 

        // will invoke or call parent class message() method 
        super.message(); 
    } 
} 

/* Driver program to test */
class Test 
{ 
    public static void main(String args[]) 
    { 
        Student s = new Student(); 

        // calling display() of Student 
        s.display(); 
    } 
}

เอาท์พุท: -

This is student class
This is person class

3. การใช้ super กับ constructors:

class Person 
{ 
    Person() 
    { 
        System.out.println("Person class Constructor"); 
    } 
} 

/* subclass Student extending the Person class */
class Student extends Person 
{ 
    Student() 
    { 
        // invoke or call parent class constructor 
        super(); 

        System.out.println("Student class Constructor"); 
    } 
} 

/* Driver program to test*/
class Test 
{ 
    public static void main(String[] args) 
    { 
        Student s = new Student(); 
    } 
} 

เอาท์พุท: -

Person class Constructor
Student class Constructor

0

Constructors
ใน Constructorคุณสามารถใช้มันโดยไม่ต้องมีจุดเพื่อเรียก constructor อื่น superเรียกนวกรรมิกใน superclass thisเรียกนวกรรมิกในคลาสนี้:

public MyClass(int a) {
  this(a, 5);  // Here, I call another one of this class's constructors.
}

public MyClass(int a, int b) {
  super(a, b);  // Then, I call one of the superclass's constructors.
}

superมีประโยชน์ถ้าซูเปอร์คลาสจำเป็นต้องเริ่มต้นเอง thisมีประโยชน์ในการอนุญาตให้คุณเขียนโค้ดการเริ่มต้นฮาร์ดทั้งหมดเพียงครั้งเดียวในตัวสร้างและเรียกมันจากตัวสร้างอื่น ๆ ซึ่งง่ายต่อการเขียนมาก

วิธีการ
ในวิธีใด ๆ คุณสามารถใช้กับจุดเพื่อเรียกวิธีอื่น super.method()เรียกใช้เมธอดในซูเปอร์คลาส this.method()เรียกวิธีการในชั้นนี้:

public String toString() {
  int    hp   = this.hitpoints();  // Calls the hitpoints method in this class
                                   //   for this object.
  String name = super.name();      // Calls the name method in the superclass
                                   //   for this object.

  return "[" + name + ": " + hp + " HP]";
}

superมีประโยชน์ในบางสถานการณ์: หากคลาสของคุณมีวิธีการเดียวกับซูเปอร์คลาสของคุณ Java จะถือว่าคุณต้องการหนึ่งในคลาสของคุณ superอนุญาตให้คุณถามหาวิธีของซูเปอร์คลาสแทน thisมีประโยชน์เป็นเพียงวิธีในการทำให้โค้ดของคุณอ่านง่ายขึ้น


0

ซุปเปอร์คำหลักที่สามารถใช้ในการเรียก constructor superclass และการอ้างถึงสมาชิกของซับคลาส

เมื่อคุณเรียกซุปเปอร์ ()มีข้อโต้แย้งที่เหมาะสมเราจริงเรียกตัวสร้างกล่องซึ่งเริ่มต้นตัวแปรความกว้าง , ความสูงและความลึกเรียกมันโดยใช้ค่าพารามิเตอร์ที่สอดคล้องกัน คุณยังคงเริ่มต้นน้ำหนักที่เพิ่มมูลค่าแล้วเท่านั้น ถ้าจำเป็นคุณสามารถทำได้ตอนนี้ตัวแปรคลาสกล่องเป็นส่วนตัว วางลงในฟิลด์ของตัวดัดแปลงคลาสส่วนตัว Box และตรวจสอบให้แน่ใจว่าคุณสามารถเข้าถึงได้โดยไม่มีปัญหาใด ๆ

ที่ซุปเปอร์คลาสสามารถเป็นตัวสร้างเวอร์ชันที่โอเวอร์โหลดได้หลายตัวดังนั้นคุณสามารถเรียกเมธอดsuper ()ด้วยพารามิเตอร์ที่แตกต่างกัน โปรแกรมจะดำเนินการสร้างที่ตรงกับข้อโต้แย้งที่ระบุ

public class Box {

    int width;
    int height;
    int depth;

    Box(int w, int h, int d) {
        width = w;
        height = h;
        depth = d;
    }

    public static void main(String[] args){
        HeavyBox heavy = new HeavyBox(12, 32, 23, 13);
    }

}

class HeavyBox extends Box {

    int weight;

    HeavyBox(int w, int h, int d, int m) {

        //call the superclass constructor
        super(w, h, d);
        weight = m;
    }

}

0

superเป็นคำหลัก มันถูกใช้ภายในคำนิยามวิธีการเรียนย่อยเพื่อเรียกวิธีการที่กำหนดไว้ในซูเปอร์คลาส วิธีการส่วนตัวของ superclass ไม่สามารถเรียกได้ สาธารณะเท่านั้นและวิธีการป้องกันสามารถเรียกได้โดยคำหลักสุด มันถูกใช้โดยตัวสร้างคลาสเพื่อเรียกใช้ตัวสร้างของคลาสแม่

ตรวจสอบที่นี่สำหรับคำอธิบายเพิ่มเติม


0

ตามที่ระบุไว้ภายใน Constructor เริ่มต้นมีการเรียกsuper () โดยนัย ในบรรทัดแรกของ Constructor

super () นี้เรียกสายโซ่ของคอนสตรัคเตอร์โดยอัตโนมัติโดยเริ่มจากด้านบนของลำดับชั้นของคลาสและเลื่อนลำดับชั้นลง

หากมีมากกว่าสองคลาสในลำดับชั้นของโปรแกรมตัวสร้างเริ่มต้นระดับบนสุดจะได้รับการเรียก ก่อนเป็นครั้งแรก

นี่คือตัวอย่างของสิ่งนี้:

class A {
    A() {
    System.out.println("Constructor A");
    }
}

class B extends A{

    public B() {
    System.out.println("Constructor B");
    }
}

class C extends B{ 

    public C() {
    System.out.println("Constructor C");
    }

    public static void main(String[] args) {
    C c1 = new C();
    }
} 

ข้างต้นจะส่งออก:

Constructor A
Constructor B
Constructor C
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.