2012-07-04 59 views
12

tôi đã kịch bản sau đây:Java: Sử dụng phương pháp lớp cha để truy cập lớp con biến

public class A { 

    private int x = 5; 

    public void print() 
    { 
     System.out.println(x); 
    } 
} 


public class B extends A { 

    private int x = 10; 

    /*public void print() 
    { 
     System.out.println(x);  
    }*/ 

    public static void main(String[] args) { 
     B b = new B(); 
     b.print(); 
    } 

} 

On thi mã, đầu ra là: 5.

Làm thế nào để truy cập vào các lớp con (B) biến (x) thông qua phương thức lớp cha?

Điều này có thể được thực hiện mà không cần ghi đè phương thức print() (tức là bỏ ghi chú trong B)?

[này rất quan trọng bởi vì về ghi đè chúng ta sẽ phải viết lại toàn bộ mã cho hàm print() phương pháp một lần nữa]

EDITED

More Làm rõ: -

  • Động cơ của câu hỏi là sử dụng giá trị của một biến riêng tư của lớp con từ phương thức lớp cha của nó. Điều này không yêu cầu thay đổi giá trị của biến riêng tư của lớp cha để đạt được kết quả mong muốn.
  • Câu trả lời được đăng ở đây, mặc dù đã dẫn tôi đến câu trả lời mong muốn của tôi, mà tôi đã đăng bên dưới.

(Cảm ơn tất cả thời gian và giúp đỡ của bạn)

+0

Khi bạn muốn in biến B 'x', bạn có ý định' x' khác với 'x' của A hay chúng giống nhau không? –

+0

@WeiHao từ mã rõ ràng là 'x' trong' A' là 5, một trong 'B' là 10. Anh ta muốn' B.print() 'để xuất 10, bởi vì anh ta không hạnh phúc với một đầu ra của 5. Vì vậy, ông hy vọng họ sẽ khác nhau. –

+0

@Jayant Nó không phải về cha mẹ không có thông tin, nó không. vấn đề là giá trị của 'x' không bị ghi đè trong quá trình tạo' B'. –

Trả lời

8
class A { 
    private int x = 5; 

    protected int getX() { 
     return x; 
    } 

    protected void setX(int x) { 
     this.x = x; 
    } 

    public void print() { 
     // getX() is used such that 
     // subclass overriding getX() can be reflected in print(); 
     System.out.println(getX()); 
    } 
} 

class B extends A { 
    public B() { 
     // setX(10); // perhaps set the X to 10 in constructor or in main 
    } 

    public static void main(String[] args) { 
     B b = new B(); 
     b.setX(10); 
     b.print(); 
    } 
} 

EDITED

Dưới đây là một câu trả lời chung sử dụng lớp trừu tượng và phương pháp để giải quyết tình huống tương tự:

abstract class SuperA { 
    protected abstract Object getObj(); 

    public void print() { 
     System.out.println(getObj()); 
    } 
} 

class A extends SuperA { 
    @Override 
    protected Object getObj() { 
     // Your implementation 
     return null; // return what you want 
    } 
} 

class B extends A { 
    @Override 
    protected Object getObj() { 
     // Your implementation 
     return null; // return what you want 
    } 

    public static void main(String[] args) { 
     B b = new B(); 
     b.print(); 
    } 
} 
+0

Giải pháp toàn diện tuyệt vời. Điều này là khá OOP = D. Ngoài ra, rất nhiều C# giống như. –

+0

@Shingetsu, Cảm ơn, nhưng tôi không biết gì về C#, tôi dự định học nó nhưng công việc của tôi không cho phép ... –

+0

về cơ bản, C# chỉ là một phiên bản Java thanh lịch. Nếu bạn biết Java cũng đã được bạn sẽ không có nhiều khó khăn khi học nó, mặc dù biết .NET và C++ sẽ có ích = D. –

0

Bạn nên tiếp xúc với một getter cho giá trị mà bạn muốn và ghi đè lên rằng trong lớp trẻ.

Giống như vậy:

public class A { 

    private int x = 5; 

    public void print() 
    { 
     System.out.println(getX()); 
    } 

    protected void setX(int x) 
    { 
     this.x = x; 
    } 

    protected int getX() 
    { 
     return x; 
    } 

} 


public class B extends A { 

    /*public void print() 
    { 
     System.out.println(x);  
    }*/ 

    public B() 
    { 
     setX(10); 
    } 

    public static void main(String[] args) { 
     B b = new B(); 
     b.print(); 
    } 

} 
+0

Điều đó cũng hoạt động, mặc dù điều gì sẽ xảy ra nếu x phải được thay đổi tại một thời điểm? Điều này được giới hạn trong ví dụ được đưa ra. –

+0

Thực hiện một setter của X sau đó. –

+0

@VictorWong Đây không phải là một getter thực sự, biến không thực sự ở đó. –

0

Bạn luôn có thể thêm nó vào constructor:

public class B extends A { 

    //this line is unnecessary: private int x = 10; 

    /*public void print() 
    { 
     System.out.println(x);  
    }*/ 

    public B() 
    { 
     x=10; 
    } 


    public static void main(String[] args) { 
     B b = new B(); 
     b.print(); 
    } 

} 

Lý do nó sẽ không làm việc như bạn cố gắng nó là giá trị mặc định chỉ nhận được đánh giá một lần. Vì vậy, khi nó mặc định 5 trong A, nó giữ nguyên: 5 ngay cả khi bạn sử dụng mặc định 10 B.

+0

Thứ nhất, thay đổi x trong hàm tạo của B sẽ không hoạt động nếu khả năng hiển thị của x là riêng tư. Thứ hai, ngay cả khi chúng ta làm cho khả năng hiển thị của x được bảo vệ, nó sẽ thay đổi giá trị của biến x trong lớp cha. Điều được yêu cầu là không thay đổi giá trị của biến trong lớp cha nhưng để sử dụng giá trị của biến lớp con. – Jayant

+0

@Jayant biến lớp con *** KHÔNG TUYỆT VỜI ***. Bạn tạo một biến trong parent, cho nó một giá trị mặc định. Giá trị mặc định được đánh giá một lần. Bạn đưa *** SAME VARIABLE *** một giá trị mặc định khác vào 'B', nhưng giá trị mặc định đã được đánh giá trong' A'. Khi bạn tạo 'B', IL 1st đánh giá giá trị mặc định cho' x' trong 'A', sau đó là' x' trong 'B', nhưng vì' x' đã được đánh giá trong 'A', dòng' private int x = 10; 'hoàn toàn không có gì. –

+0

Tôi không hiểu những gì bạn đang cố gắng nói. Rõ ràng câu lệnh private int x = 10 trong lớp B phân bổ một số bộ nhớ mới cho biến x trong lớp B và nó hoàn toàn độc lập với biến x trong A. – Jayant

6

Sau khi đọc tất cả các câu trả lời được đăng ở đây, tôi nhận được những gì tôi đang tìm kiếm. Sau đây là những gì tôi cảm thấy là câu trả lời tốt nhất cho câu hỏi của tôi:

public class A { 
    private int x = 5;  
    protected int getX(){ 
     return x; 
    }  
    public void print(){ 
     System.out.println(getX()); 
    } 
} 
public class B extends A { 
    private int x = 10; 
    protected int getX(){ 
     return x; 
    } 
    public static void main(String[] args) { 
     B b = new B(); 
     b.print(); 
    } 
} 

Thiết lập một getter bảo vệ và ghi đè là tốt hơn so với trọng phương pháp print() chính nó, vì có thể là bất kỳ phương pháp khổng lồ khác ở vị trí của phương thức in có thể cần truy cập vào giá trị của (các) biến lớp con.

+0

Bạn nên thực sự chọn câu trả lời của @VictorWong là câu trả lời hay nhất ... – kakacii

+0

@kakacii Có, mặc dù câu trả lời của VictorWong không trả lời chính xác câu hỏi, mọi người thấy nó hữu ích hơn. Tôi đã thay đổi lựa chọn của mình. Cảm ơn :) – Jayant

+0

@Jayant Tôi không thể thấy bất kỳ sự khác biệt nào giữa giải pháp chung của tôi (không phải cái đầu tiên, nhưng đã chỉnh sửa) và câu trả lời của bạn ở đây, ngoại trừ bạn thay thế 'obj' bằng' x'. Không có hành vi phạm tội, nhưng tôi muốn biết tại sao giải pháp của tôi không đủ chính xác. –

1

Để giải câu hỏi, bạn phải xác định các trường trong lớp cha A như được bảo vệ (vì vậy nó sẽ được kế thừa trên lớp con) và đặt giá trị trường x bên trong hàm tạo trong lớp con B. Phương thức in cũng được thừa hưởng từ lớp A để bạn có thể gọi trực tiếp từ lớp cha.

Tôi hy vọng điều này có thể giúp bạn.

public class A 
{ 
    // fields declaration 
    protected int x = 5; 

    public void print() 
    { 
     System.out.println(x); 
    } 
} 



public class B extends A 
{ 

    public B() 
    { 
     // set child x value. The field have been defined in the parent class 
     x = 10; 
    } 

    public static void main(String[] args) 
    { 
     A a = new A(); 
     a.print(); // print 5 

     B b = new B(); 
     b.print(); // print 10 
    } 

} 
Các vấn đề liên quan