2015-01-21 25 views
5

Như một ví dụ về não-một giáo sư của tôi đã cho chúng tôi tập thể dục sau đây, để tìm hiểu về thừa kế. Chúng tôi phải tìm ra đầu ra.Gọi phương pháp siêu từ trong phạm vi siêu lớp

//java 
public class A { 
    public void f() { 
     System.out.println("A -> f()"); 
     x = x + 4; 
     if (x < 15) this.f(); //the f-call 
    } 
    public int x = 5; 
} 

public class B extends A { 
    @Override 
    public void f() { 
     System.out.println("B -> f()"); 
     x = x + 3; 
     super.f(); 
    } 
} 

public class Main { 
    public static void 
    main(String[] args) { 
     A a = new B(); 

     System.out.println("a.f()"); 
     a.f(); 
     System.out.println(a.x); 
    } 
} 

Kết quả là, như tôi mong đợi,

  • af()
  • B -> f()
  • A -> f()
  • B -> f ()
  • A -> f()

Tuy nhiên, tôi đã tự hỏi. Có cách nào để gọi f-call trong A gọi phương thức f trong A, ngay cả khi tôi sử dụng nó từ đối tượng B, tương tự như cách tôi gọi f từ A trong B bằng super.f() . Vì vậy, đầu ra sẽ trở thành (tôi nghĩ):

  • af()
  • B -> f()
  • A -> f()
  • A -> f()

Điều này có khả thi không? Và nếu vậy, làm thế nào?

Lưu ý: Tôi không chắc chắn những gì các ứng dụng thực tế điều này sẽ là, tôi chỉ cố gắng tìm hiểu những điều mới mẻ: P

+0

Vì vậy, về cơ bản, bạn muốn có một phương pháp để tự gọi?Tôi không nghĩ rằng bạn có thể làm điều đó –

+0

Vâng, đó là chính xác những gì tôi muốn nó làm. –

+0

@CharlesWhitfield Tất nhiên một phương pháp có thể tự gọi. Nó được gọi là một phương pháp đệ quy. Câu hỏi của OP là liệu có thể chỉ định phiên bản gốc của một phương thức từ bên trong lớp cha. – shmosel

Trả lời

5

Câu trả lời ngắn gọn là "không", bạn không thể làm điều này.

Câu trả lời dài hơn là cho phép điều này sẽ phá vỡ tất cả các loại bảo đảm về thừa kế. Lớp B của bạn về cơ bản đã nói "Bây giờ tôi cung cấp phương pháp kinh điển cho public void f()". Bởi vì B đang cung cấp phương thức được cho phép, nó được phép gọi lại cho phụ huynh để sử dụng phương thức đó (và điều gì đó rất hữu ích để làm).

Nếu A được phép thực hiện tương tự, về cơ bản nó sẽ bỏ qua hành vi mà B muốn ghi đè.

Có nhiều mẫu có sẵn cung cấp cho bạn hành vi tương tự, ví dụ: the Template Pattern

2

Bởi vì đa hình sẽ áp dụng cho tất cả các phương thức của một đối tượng lớp cha, các f đó được gọi là sẽ là kiểu thời gian chạy của đối tượng luôn - trong trường hợp này, B, vì vậy B 's f phương pháp sẽ luôn luôn được gọi. Điều đó không thể thay đổi được trong Java.

Bạn có thể làm việc này bằng cách thực hiện công việc của f phương pháp A 's trong một phương pháp private, nói, foo, để khi f được gọi, foo được gọi là liên tục. Trong A:

public void f() 
{ 
    foo(); 
} 

private void foo() { 
    System.out.println("A -> f()"); // Lie. 
    x = x + 4; 
    if (x < 15) this.foo(); //the "f"-call 
} 
Các vấn đề liên quan