siêu () trong Java


Câu trả lời:


267

super() gọi hàm tạo cha mẹ không có đối số.

Nó cũng có thể được sử dụng với các đối số. Tức là super(argument1)và nó sẽ gọi hàm tạo chấp nhận 1 tham số của loại argument1(nếu tồn tại).

Ngoài ra nó có thể được sử dụng để gọi các phương thức từ cha mẹ. I Esuper.aMethod()

Thêm thông tin và hướng dẫn tại đây


9
LƯU Ý: trong trường hợp đầu tiên, lớp cha phải không có hàm tạo đối số không thành công sẽ gây ra lỗi biên dịch.
KNU

Nit: Thuật ngữ phụ huynh / trẻ em không tốt cho phân cấp lớp. (Một đứa trẻ không phải là một người cha.)
aioobe

Có bất kỳ hạn chế về nơi siêu có thể được sử dụng?
Aaron Franke

2
@VivekChavda, chắc chắn một đứa trẻ có thể là cha mẹ, giống như học sinh có thể là giáo viên, v.v. Nhưng tôi nghĩ bạn hiểu sự khác biệt so với Animal - ví dụ như Dog. Một con chó nhất thiết phải là một con vật. Cha mẹ / con cái thường mối quan hệ (" Cha mẹ con") trong khi Động vật / chó là mối quan hệ "là" . Xem aioo.be/2016/06/29/a-child-is-not-always-a-parent.html
aioobe 16/12/17

2
@AaronFranke, "Có bất kỳ hạn chế nào về nơi siêu có thể được sử dụng không?" - Có, super(...)chỉ có thể được sử dụng làm câu lệnh đầu tiên trong hàm tạo.
aioobe

154

Một số sự thật:

  1. super() được sử dụng để gọi cha mẹ ngay lập tức.
  2. super() có thể được sử dụng với các thành viên thể hiện, tức là các biến thể hiện và các phương thức cá thể.
  3. super() có thể được sử dụng trong một hàm tạo để gọi hàm tạo của lớp cha.

OK, bây giờ hãy thực tế thực hiện những điểm này super().

Kiểm tra sự khác biệt giữa chương trình 1 và 2. Ở đây, chương trình 2 chứng minh tuyên bố đầu tiên của chúng tôi về super()Java.

Chương trình 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();
    }
}

Đầu ra:

200
200

Bây giờ hãy kiểm tra chương trình 2 và cố gắng tìm ra sự khác biệt chính.

Chương trình 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();
    }
}

Đầu ra:

100
200

Trong chương trình 1, đầu ra chỉ là của lớp dẫn xuất. Nó không thể in biến của cả lớp cơ sở lẫn lớp cha. Nhưng trong chương trình 2, chúng ta đã sử dụng super()biến atrong khi in đầu ra của nó và thay vì in giá trị của biến acủa lớp dẫn xuất, nó đã in giá trị của biến acủa lớp cơ sở. Vì vậy, nó chứng minh rằng super()được sử dụng để gọi cha mẹ ngay lập tức.

OK, bây giờ hãy kiểm tra sự khác biệt giữa chương trình 3 và chương trình 4.

Chương trình 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();
    }
}

Đầu ra:

200

Ở đây đầu ra là 200. Khi chúng ta gọi Show(), Show()hàm của lớp dẫn xuất được gọi. Nhưng chúng ta nên làm gì nếu chúng ta muốn gọi Show()hàm của lớp cha? Kiểm tra chương trình 4 để biết giải pháp.

Chương trình 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();
    }
}

Đầu ra:

100
200

Ở đây chúng ta nhận được hai đầu ra, 100 và 200. Khi Show()hàm của lớp dẫn xuất được gọi, đầu tiên nó gọi Show()hàm của lớp cha, bởi vì bên trong Show()hàm của lớp dẫn xuất, chúng ta đã gọi Show()hàm của lớp cha bằng cách đặt các supertừ khóa trước tên hàm.


4
Tại sao bạn không thụt lề các ví dụ của bạn? Có một lý do cụ thể?
erikbwork

KHÔNG erikb, tôi muốn biết cách sử dụng super (). Sau đây tôi chỉ đến
Mohan

Trong lớp cơ sở của tôi, tôi quá tải hàm tạo với một, hai, ... đối số
Mohan

nhưng trong lớp dẫn xuất của tôi, tôi sử dụng super () mà không có bất kỳ tranh cãi. sau đó, điều gì sẽ xảy ra cho dù nó tự động gọi một hàm tạo mặc định của lớp cơ sở
Mohan

2
super()không phải là một từ khóa. Nó là một lời mời xây dựng. superlà một từ khóa và # 1 và # 2 chỉ có ý nghĩa với định nghĩa đó.
Hầu tước Lorne

37

Nguồn bài viết: Java: Gọi super ()


Đúng. super(...)sẽ gọi hàm tạo của siêu hạng.

Hình minh họa:

nhập mô tả hình ảnh ở đây


Ví dụ độc lập:

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

Bản in:

Constructing an animal: From Dog constructor
Constructing a dog.

Trong lớp cơ sở của tôi, tôi quá tải hàm tạo với một, hai, ... đối số trong lớp dẫn xuất của tôi, tôi sử dụng super () mà không có bất kỳ đối số nào. sau đó điều gì sẽ xảy ra cho dù nó tự động gọi một hàm tạo mặc định của lớp cơ sở
Mohan

Đúng. Nếu bạn gọi super()nó sẽ gọi hàm tạo của siêu lớp không có đối số. Tương tự, nó sẽ gọi hàm tạo 1 đối số nếu bạn thực hiện super(arg1), v.v.
aioobe

nếu không có hàm tạo mà không có bất kỳ đối số nào trong lớp cơ sở thì điều gì sẽ xảy ra nếu lớp dẫn xuất gọi super ().
Mohan

1
Không có gì. Nó sẽ không biên dịch. Nếu bạn tự cung cấp một hàm tạo, hàm tạo tự động / mặc định / không đối số sẽ không được tạo, do đó super()sẽ không phải là một cuộc gọi hợp lệ.
aioobe

29

Là super () được sử dụng để gọi hàm tạo cha?

Đúng.

Xin giải thích về Super ().

super()là một cách sử dụng đặc biệt của supertừ khóa mà bạn gọi là hàm tạo cha không tham số. Nói chung, supertừ khóa có thể được sử dụng để gọi các phương thức được ghi đè, truy cập các trường ẩn hoặc gọi hàm tạo của lớp cha.

Đây là hướng dẫn chính thức


5
super()được sử dụng để gọi hàm tạo cha, super.myMethod()được sử dụng để gọi một phương thức được ghi đè.
Sean Patrick Floyd

2
@seanizer hoặc bất kỳ phương pháp nào khác của siêu lớp (bao gồm cả số liệu thống kê) nếu trong phạm vi của nó. siêu chỉ là một tài liệu tham khảo cho lớp cơ sở của bạn.
atamanroman

3
Tôi không nghĩ super () được sử dụng để gọi các phương thức lớp cơ sở. Bạn có thể sử dụng super.method () mặc dù.
Dheeraj Joshi

@seanizer, @Dheeraj: Cảm ơn phản hồi của bạn, tôi đã điều chỉnh câu trả lời của mình.
Heinzi

7

Gọi siêu xây dựng không có đối số chỉ là một sự lãng phí không gian màn hình và thời gian lập trình viên. Trình biên dịch tạo chính xác cùng một mã, cho dù bạn có viết nó hay không.

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

class Implicit {
    Implicit() {
    }
}

Tôi tìm thấy nó được sử dụng trong một vài lớp, không chắc mục đích là gì. Câu trả lời của bạn rất hữu ích.
iprashant

6

Có, super()(chữ thường) gọi một hàm tạo của lớp cha. Bạn có thể bao gồm các đối số:super(foo, bar)

Ngoài ra còn có một supertừ khóa, mà bạn có thể sử dụng trong các phương thức để gọi một phương thức của siêu lớp

Google nhanh chóng cho kết quả "siêu Java" trong việc này


4

Đúng rồi. Super được sử dụng để gọi hàm tạo. Vì vậy, giả sử bạn có một khối mã như vậy

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

Sau đó, bạn có thể gán một giá trị cho biến thành viên n.


2

Tôi đã thấy tất cả các câu trả lời. Nhưng mọi người đều quên đề cập đến một điểm rất quan trọng:

super () nên được gọi hoặc sử dụng trong dòng đầu tiên của hàm tạo.


1

Chỉ siêu (); một mình sẽ gọi hàm tạo mặc định, nếu nó tồn tại của lớp cha của lớp. Nhưng bạn phải tự viết công cụ xây dựng mặc định. Nếu bạn không Java sẽ tạo một cái cho bạn mà không cần triển khai, hãy lưu super (); , đề cập đến Đối tượng siêu lớp phổ quát và bạn không thể gọi nó trong một lớp con.

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

}

Không có tranh luận .
Hầu tước Lorne

1

Ví dụ: trong tự động hóa selen, bạn có PageObject có thể sử dụng hàm tạo của cha mẹ như thế này:

public class DeveloperSteps extends ScenarioSteps {

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

1

Tôi muốn chia sẻ với các mã bất cứ điều gì tôi hiểu.

Siêu từ khóa trong java là một biến tham chiếu được sử dụng để tham chiếu các đối tượng lớp cha. Nó được sử dụng chủ yếu trong các bối cảnh sau: -

1. Sử dụng siêu với các biến:

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

Đầu ra: -

Maximum Speed: 120
  1. Sử dụng siêu với các phương pháp:
/* 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(); 
    } 
}

Đầu ra: -

This is student class
This is person class

3. Sử dụng siêu với các nhà xây dựng:

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

Đầu ra: -

Person class Constructor
Student class Constructor

0

Con
constructor Trong một constructor, bạn có thể sử dụng nó mà không có dấu chấm để gọi một constructor khác. supergọi một hàm tạo trong lớp cha; thisgọi một hàm tạo trong lớp này:

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

superlà hữu ích nếu siêu lớp cần tự khởi tạo. thisrất hữu ích khi cho phép bạn viết tất cả các mã khởi tạo cứng chỉ một lần trong một trong các hàm tạo và gọi nó từ tất cả các hàm tạo khác, dễ viết hơn nhiều.

Phương thức
Trong bất kỳ phương thức nào, bạn có thể sử dụng nó với dấu chấm để gọi phương thức khác. super.method()gọi một phương thức trong siêu lớp; this.method()gọi một phương thức trong lớp này:

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

superlà hữu ích trong một kịch bản nhất định: nếu lớp của bạn có cùng phương thức với siêu lớp của bạn, Java sẽ cho rằng bạn muốn cái đó trong lớp của bạn; superthay vào đó, cho phép bạn yêu cầu phương thức của lớp cha. thischỉ hữu ích như một cách để làm cho mã của bạn dễ đọc hơn.


0

Các siêu từ khóa có thể được sử dụng để gọi constructor lớp cha và để đề cập đến một thành viên của lớp cha

Khi bạn gọi super () với các đối số phù hợp, chúng tôi thực sự gọi Hộp xây dựng , khởi tạo các biến chiều rộng , chiều caochiều sâu , gọi nó bằng cách sử dụng các giá trị của các tham số tương ứng. Bạn chỉ còn lại để khởi tạo trọng lượng giá trị gia tăng của nó. Nếu cần, bạn có thể thực hiện bây giờ các biến lớp Box là private . Đặt trong các trường của công cụ sửa đổi riêng của lớp Box và đảm bảo rằng bạn có thể truy cập chúng mà không gặp vấn đề gì.

Tại siêu lớp có thể là một số hàm tạo phiên bản quá tải, vì vậy bạn có thể gọi phương thức super () với các tham số khác nhau. Chương trình sẽ thực hiện hàm tạo phù hợp với các đối số đã chỉ định.

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

siêu là một từ khóa. Nó được sử dụng bên trong một định nghĩa phương thức lớp con để gọi một phương thức được định nghĩa trong lớp cha. Các phương thức riêng của siêu lớp không thể được gọi. Chỉ các phương thức công khai và được bảo vệ có thể được gọi bằng siêu từ khóa. Nó cũng được sử dụng bởi các hàm tạo của lớp để gọi các hàm tạo của lớp cha của nó.

Kiểm tra ở đây để giải thích thêm.


0

Như đã nêu, bên trong hàm tạo mặc định có một siêu ẩn () được gọi trên dòng đầu tiên của hàm tạo.

Super () này tự động gọi một chuỗi các hàm tạo bắt đầu ở đầu phân cấp lớp và di chuyển xuống cấu trúc phân cấp.

Nếu có nhiều hơn hai lớp trong hệ thống phân cấp lớp của chương trình, hàm tạo mặc định của lớp trên cùng sẽ được gọi đầu tiên .

Đây là một ví dụ về điều này:

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

Ở trên sẽ xuất ra:

Constructor A
Constructor B
Constructor C
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.