2012-02-09 21 views
5

Tôi biết, tôi biết, có rất nhiều câu trả lời đơn giản bao gồm hầu hết các trường hợp để tránh điều này.Khai báo biến bên trong câu lệnh `if` trong Java là một kiểu khác tùy theo điều kiện

Trong trường hợp của tôi, tôi muốn sử dụng thông tin người dùng nhập để tạo người chơi CPU trong trò chơi. Nếu người dùng chọn chế độ dễ, thì tôi muốn khai báo và khởi tạo một thể hiện của lớp EasyPlayer. Nếu không, tôi muốn khai báo và khởi tạo một thể hiện của lớp HardPlayer. Dù bằng cách nào, tên cụ thể của biến cần phải là "cpu" và phần còn lại của mã hoạt động trên "cpu" bừa bãi. Đó là, tất cả những khác biệt trong cách thức các hoạt động này được xây dựng trong các lớp khác nhau của chúng, phân lớp lớp CpuPlayer.

Vì vậy, đây là các mã:

// Set the opponent. 
if (difficulty == 0){ 
    EasyPlayer cpu = new EasyPlayer(num_rounds); 
} 
else{ 
    HardPlayer cpu = new HardPlayer(num_rounds); 
} 

này mang lại cho tôi những cannot find symbol lỗi luôn gây phiền nhiễu. Từ những gì tôi có thể đọc, mọi người nói rằng bạn không thể khai báo bên trong một điều kiện như thế này do vấn đề phạm vi và khả năng nó không bao giờ xảy ra.

Nếu có, cách nào đúng để khai báo thay thế một biến duy nhất là một trong hai lớp khác nhau dựa trên đầu vào của người dùng?

+1

+1 để nhận ra rằng giải pháp bạn có ở đây không đủ và đến với SO để được trợ giúp. –

Trả lời

10
CpuPlayer cpu; 

if (difficulty == 0){ 
    cpu = new EasyPlayer(num_rounds); 
} 
else{ 
    cpu = new HardPlayer(num_rounds); 
} 
+0

Ah. Khoảnh khắc đầu tát lớn. Cảm ơn bạn. – ely

0

Khai báo trước, sau đó gán nó.

// Set the opponent. 
CpuPlayer cpu = null; 
if (difficulty == 0){ 
    cpu = new EasyPlayer(num_rounds); 
} 
else{ 
    cpu = new HardPlayer(num_rounds); 
} 
if(cpu == null) throw new IllegalStateException(); 
+0

Việc gán null lúc đầu có vẻ không cần thiết, vì có một ELSE cho IF có điều kiện. Miễn là HardPlayer kế thừa từ CpuPlayer và HardPlayer không ném bất kỳ ngoại lệ nào trong quá trình xây dựng, có vẻ như dòng đầu tiên và cuối cùng của chương trình là không cần thiết. Tui bỏ lỡ điều gì vậy? – eternaln00b

+0

@SiddharthaShankar Đó là một thói quen - thường là thời gian, bạn sẽ kết thúc với "biến này có thể chưa được gán" lỗi. – corsiKa

+2

Việc chuyển nhượng null và kiểm tra tiếp theo không chỉ là không cần thiết, chúng có hại trong việc họ biến kiểm tra thời gian biên dịch thành kiểm tra thời gian chạy. Không có phép gán ban đầu, bất kỳ nỗ lực nào sử dụng 'cpu' sau mệnh đề' else' sẽ dẫn đến lỗi biên dịch trừ khi 'cpu' được gán một giá trị (trong trường hợp này, một trong hai trường hợp' mới') trong tất cả mã chi nhánh. Nói cách khác, nếu có một chi nhánh mã mà quên đặt giá trị, trình biên dịch sẽ cho bạn biết (thay vì phải ném một ngoại lệ thời gian chạy). – yshavit

0
// Set the opponent. 
CpuPlayer cpu; 
if (difficulty == 0){ 
    cpu = new EasyPlayer(num_rounds); 
} else{ 
    cpu = new HardPlayer(num_rounds); 
} 
1
CpuPlayer cpu; 
// Set the opponent. 
if (difficulty == 0){ 
    cpu = new EasyPlayer(num_rounds); 
} else{ 
    cpu = new HardPlayer(num_rounds); 
} 
2

Nếu mục đích của bạn là để chỉ gọi phương pháp có sẵn để lớp CpuPlayer, sau đó có lẽ là một mẫu thiết kế tốt hơn để sử dụng là Strategy Pattern. Trong trường hợp của bạn, bạn có lẽ sẽ thêm một lớp mới gọi là CpuStrategy, và sửa đổi constructor CpuPlayer của bạn để một cái gì đó như:

public CpuPlayer(CpuStrategy strategy, int num_rounds) 

Điều này làm cho phần còn lại của mã của bạn dễ đọc hơn và có lẽ dễ dàng hơn để duy trì quá. Dưới đây là đoạn mã gốc của bạn trông như thế nào:

CpuPlayer cpu = new CpuPlayer(new CpuStrategy(difficulty), num_rounds); 

Chúng tôi đã loại bỏ if/else vì lớp CpuStrategy sẽ xử lý sự khác biệt giữa các mức độ khó. Điều này cũng có ý nghĩa vì bạn có thể tóm tắt khái niệm "mức độ khó khăn" từ thịt của chương trình của bạn, mà tôi giả định là phần chơi trò chơi.

+0

Cảm ơn mẹo và các chi tiết bổ sung. Đây thực sự là một ý tưởng thiết kế lại tốt. – ely

0

Bạn có thể tinh chỉnh thiết kế cấu trúc lớp học của mình. Tạo một lớp cha có tên là Level và mở rộng hai lớp con có tên là EasyLevel và HardLevel.

class EasyLevel : public Level 
{ 

    //implementation specific to easy level 
} 

class HardLevel : public Level 
{ 
    //implementation specific to hard level 
} 

trong lớp người chơi của bạn, thêm sửa đổi hàm tạo để nhận tham số loại cấp.

class Player 
{ 
    Level level; 
    int rounds; 

    public: 
    Player (Level level, int num_rounds) 
    { 
     this.level = level; 
     this.rounds = num_rounds; 
    } 

    play() 
    { 
     // use level variable to invoke implementation specific to the set level, hard or easy. 
    } 
} 

Điều này sẽ làm cho cấu trúc lớp học của bạn dễ mở rộng hơn. Ví dụ nếu bạn cần thêm một mức 'trung bình' khác trong tương lai, chỉ cần mở rộng từ cấp lớp cha.

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