2010-02-24 31 views
42

Tôi đã tự hỏi nếu mã dưới đây có ý nghĩa gì không, vì trình biên dịch cảnh báo rằng "các đối tượng trường cuối cùng trống có thể chưa được khởi tạo". Có cách nào tốt hơn để làm điều này?Lớp trừu tượng với trường uninitialized cuối cùng

public abstract Test { 
    protected final ArrayList<Object> objects; 
} 

public TestSubA extends Test { 

    public TestSubA() { 
    objects = new ArrayList<Objects>(20); 
    // Other stuff 
    } 
} 

public TestSubB extends Test { 

    public TestSubB() { 
    objects = new ArrayList<Objects>(100); 
    // Other stuff 
    } 
} 
+5

+1: vì lợi ích trong việc làm đúng. – helios

Trả lời

41

tôi sẽ làm cho lĩnh vực này cuối cùng và buộc các nhà thầu để vượt qua giá trị lên:

public abstract class Test { 
    private final ArrayList<Object> objects; 

    protected ArrayList<Object> getObjects() { 
    return objects; 
    } 

    protected Test(ArrayList<Object> objects) { 
    this.objects = objects; 
    } 
} 

public class TestSubA extends Test { 

    public TestSubA() { 
    super(new ArrayList<Object>(20)); 
    // Other stuff 
    } 
} 

public class TestSubB extends Test { 

    public TestSubB() { 
    super(new ArrayList<Object>(100)); 
    // Other stuff 
    } 
} 
+0

+1 Đánh bại tôi với nó - có cùng câu trả lời, với sự khác biệt nhỏ (ví dụ: sử dụng tham số int và gọi super() thay vì()). – MCory

+0

Cảm ơn. Bất kỳ lý do cụ thể nào khiến bạn đặt nó ở chế độ riêng tư thay vì được bảo vệ? Nói rằng tôi muốn truy cập nó trực tiếp trong các lớp con. Và tại sao bạn sử dụng() thay vì super()? – Cantillon

+0

@MCory @Lieven Tôi đoán đây là câu trả lời nhanh từ điện thoại thông minh, nơi không dễ dàng để có được mọi thứ ngay từ lần đầu tiên. –

0

Nói chung, nó có thể là tốt hơn để có một constructor trong lớp cơ sở luôn đặt lĩnh vực này và không có hàm tạo mặc định không được đặt. Các lớp con sau đó có thể truyền một cách rõ ràng tham số trong dòng đầu tiên của hàm tạo của chúng bằng cách sử dụng siêu (giá trị)

+0

Rất tiếc, xin lỗi. Đó là lỗi sao chép/dán. Tôi đã chỉnh sửa mã của mình. – Cantillon

2

Khởi tạo các đối tượng trong hàm tạo lớp trừu tượng và chỉ truyền sự khác biệt cho hàm tạo đó.

5

Vấn đề khởi tạo tham số cuối cùng trực tiếp trong hàm tạo của các lớp con là bạn cần thực hiện tất cả trong một dòng vì super() phải là câu lệnh đầu tiên của hàm tạo. Vì vậy, thay vào đó, tôi muốn đặt hàm tạo không công khai và tạo phương thức dựng hình tĩnh như sau:

public abstract class Test { 
    protected final ArrayList<Object> objects; 

    protected Test(ArrayList<Object> objects) { 
    this.objects = objects; 
    } 
} 

public class TestSubA extends Test { 
    public static TestSubA build() { 
    ArrayList<Object> objects = new ArrayList<Object>(20); 
    objects.put(...); 
    // Other stuff 
    return new TestSubA(objects); 
    } 

    private TestSubA(ArrayList<Object> objects) { 
    super(objects); 
    } 
} 
Các vấn đề liên quan