Khi nào tôi sử dụng super ()?


80

Tôi hiện đang tìm hiểu về kế thừa lớp trong khóa học Java của mình và tôi không hiểu khi nào thì sử dụng lệnh super()gọi?

Chỉnh sửa:
Tôi đã tìm thấy ví dụ này về mã được sử dụng:super.variable

class A
{
    int k = 10;
}

class Test extends A
{
    public void m() {
        System.out.println(super.k);
    }
}

Vì vậy, tôi hiểu rằng ở đây, bạn phải sử dụng superđể truy cập kbiến trong lớp siêu. Tuy nhiên, trong mọi trường hợp khác, super();làm gì? Của riêng mình?


30
Trên thực tế, trong ví dụ supernày không bắt buộc phải tham chiếu k. kcó thể được tham chiếu trực tiếp. supersẽ chỉ được yêu cầu để truy cập A.knếu bạn khai báo một trường khác có tên ktrong Test( Test.k).
Mark Peters

Câu trả lời:


143

Gọi chính xác luônsuper() là thừa. Nó làm rõ ràng những gì sẽ được thực hiện một cách ngầm định nếu không. Đó là bởi vì nếu bạn bỏ qua một lệnh gọi tới hàm tạo siêu, thì dù sao thì siêu hàm tạo không đối số sẽ được gọi tự động. Không phải nói rằng đó là phong cách tồi; một số người thích rõ ràng.

Tuy nhiên, nơi nó trở nên hữu ích là khi hàm tạo siêu nhận các đối số mà bạn muốn chuyển vào từ lớp con.

public class Animal {
   private final String noise;
   protected Animal(String noise) {
      this.noise = noise;
   }

   public void makeNoise() {
      System.out.println(noise);
   }
}

public class Pig extends Animal {
    public Pig() {
       super("Oink");
    }
}

2
Giả sử một phương thức được ghi đè trong một lớp con và sau đó lại bị ghi đè trong lớp con của nó. (Kế thừa đa cấp) Điều gì sẽ xảy ra nếu chúng ta phải gọi một phương thức của ông bà và cha mẹ đồng thời vào lớp cháu. Siêu sẽ được sử dụng như thế nào?
h8pathak

1
@ h8pathak: Nếu bạn đang hỏi làm cách nào một lớp con có thể bỏ qua việc triển khai của lớp cha của nó nhưng lại gọi là grandparent, thì điều đó là không thể trong Java.
Mark Peters

44

superlà sử dụng để gọi constructor, methodspropertiescác tầng lớp phụ huynh.


22

Bạn cũng có thể sử dụng supertừ khóa trong lớp con khi bạn muốn gọi một phương thức từ lớp cha khi bạn đã ghi đè nó trong lớp con.

Thí dụ:

public class CellPhone {
    public void print() {
        System.out.println("I'm a cellphone");
    }
}

public class TouchPhone extends CellPhone {
    @Override
    public void print() {
        super.print();
        System.out.println("I'm a touch screen cellphone");
    }
    public static void main (strings[] args) {
        TouchPhone p = new TouchPhone();
        p.print();
    }
}

Ở đây, dòng super.print()gọi print()phương thức của lớp cha CellPhone. Đầu ra sẽ là:

I'm a cellphone
I'm a touch screen cellphone

1
có phải nó (String [] args) trong dòng khai báo phương thức chính của bạn không? Cảm ơn rất nhiều!
Toán Appalachian

9

Khi bạn muốn gọi hàm tạo siêu lớp - để khởi tạo các trường bên trong nó. Hãy xem bài viết này để biết khi nào sử dụng nó:

http://download.oracle.com/javase/tutorial/java/IandI/super.html


4
Như nó nói trong liên kết, bạn không bao giờ phải gọi super(), vì Java sẽ ngầm thêm nó. Nhưng bạn phải gọi super(args)nếu bạn cần một phương thức khởi tạo mẹ không phải mặc định.
Michael Brewer-Davis

9

Bạn sẽ sử dụng nó như dòng đầu tiên của một hàm tạo lớp con để gọi hàm tạo của lớp cha của nó.

Ví dụ:

public class TheSuper{
    public TheSuper(){
        eatCake();
    }
}

public class TheSub extends TheSuper{
    public TheSub(){
        super();
        eatMoreCake();
    }
}

Việc xây dựng một phiên bản của TheSubsẽ gọi cả eatCake()eatMoreCake()


1

Bạn có thể sử dụng nó để gọi phương thức của lớp cha (chẳng hạn như khi bạn đang ghi đè phương thức như vậy, super.foo (), v.v.) - điều này sẽ cho phép bạn giữ chức năng đó và thêm vào nó bằng bất kỳ thứ gì khác mà bạn có trong phần ghi đè phương pháp.



1

Bạn gọi super()để chạy cụ thể một phương thức khởi tạo của lớp cha của bạn. Cho rằng một lớp có thể có nhiều hàm tạo, bạn có thể gọi một hàm tạo cụ thể bằng cách sử dụng super()hoặc super(param,param)oder, bạn có thể để Java xử lý điều đó và gọi hàm tạo chuẩn. Hãy nhớ rằng các lớp tuân theo hệ thống phân cấp lớp tuân theo mối quan hệ "là một".


0

Dòng đầu tiên của phương thức khởi tạo lớp con của bạn phải là một lời gọi super()để đảm bảo rằng phương thức khởi tạo của lớp cha được gọi.


Không đúng. Nó sẽ tự động xảy ra.
Mark Peters

Ngay cả khi không có hàm tạo mặc định? Làm thế nào nó sẽ biết những gì để vượt qua?
robev

Nếu không có hàm tạo mặc định, bạn cần gọi super(some args), không phải super(). Nhưng vấn đề là, "phải" là sai. Một trong các hàm tạo của lớp siêu được đảm bảo sẽ được gọi miễn là lớp biên dịch.
Mark Peters

Tôi đã không nói rõ rằng khi tôi viết super (), tôi không có nghĩa là một hàm tạo không có tham số, tôi chỉ cảm thấy không thích viết bất kỳ. Và có, tôi có nghĩa là bạn cần phải gọi nó hoặc nó sẽ không biên dịch, đó là lý do tại sao tôi nói phải.
robev

1
Một lần nữa, bạn KHÔNG cần một lệnh gọi rõ ràng đến một hàm tạo siêu nếu tồn tại một hàm tạo no-arg trong lớp cha. Một phương thức siêu khởi tạo sẽ luôn được gọi, trong khi cách viết của bạn khiến nó giống như bạn đang gặp nguy cơ một siêu phương thức xây dựng không được gọi nếu bạn không đưa super(...)vào. Hoàn toàn không có nguy cơ nào về điều đó; chỉ nguy hiểm rằng nó sẽ không biên dịch.
Mark Peters

0

Mình mới làm thử, bình luận siêu (); làm điều tương tự mà không cần bình luận như @Mark Peters đã nói

package javaapplication6;

/**
 *
 * @author sborusu
 */
public class Super_Test {
    Super_Test(){
        System.out.println("This is super class, no object is created");
    }
}
class Super_sub extends Super_Test{
    Super_sub(){
       super();
       System.out.println("This is sub class, object is created");
    }
    public static void main(String args[]){
        new Super_sub();
    }
}

0

Từ trang tài liệu oracle :

Nếu phương thức của bạn ghi đè một trong các phương thức của lớp cha của nó, bạn có thể gọi phương thức được ghi đè thông qua việc sử dụng từ khóa super.

Bạn cũng có thể sử dụng superđể tham chiếu đến một trường ẩn (mặc dù không khuyến khích các trường ẩn).

Sử dụng supertrong hàm tạo của các lớp con:

Lời gọi hàm tạo lớp cha phải là dòng đầu tiên trong hàm tạo lớp con.

Cú pháp để gọi một hàm tạo lớp cha là

super();  

hoặc là:

super(parameter list);

Với super(), hàm tạo không đối số của lớp cha được gọi. Với super(parameter list), hàm tạo lớp cha với danh sách tham số phù hợp được gọi.

Lưu ý: Nếu một phương thức khởi tạo không gọi một cách rõ ràng một phương thức khởi tạo lớp cha, trình biên dịch Java sẽ tự động chèn một lệnh gọi đến phương thức khởi tạo không đối số của lớp cha . Nếu siêu lớp không có hàm tạo không đối số, bạn sẽ gặp lỗi thời gian biên dịch.

Bài liên quan:

Đa hình so với Ghi đè so với Quá tải

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.