2013-10-18 7 views
11

मैं निम्नलिखित वर्ग जो मैं अपने प्रोजेक्ट में सभी मॉडलों के आधार के रूप में उपयोग कर रहा हूँ:जावा: अभिभावक वर्ग के स्थिर चर को ओवरराइड करना?

public abstract class BaseModel 
{ 
    static String table; 
    static String idField = "id";  

    public static boolean exists(long id) throws Exception 
    { 
     Db db = Util.getDb(); 
     Query q = db.query(); 
     q.select(idField).whereLong(idField, id).limit(1).get(table); 

     return q.hasResults(); 
    } 

    //snip.. 
} 

मैं तो निम्नलिखित तरीके से इसे से विस्तार करने के लिए, कोशिश कर रहा हूँ:

public class User extends BaseModel 
{ 
    static String table = "user"; 
    //snip 
} 

हालांकि, अगर मैं निम्नलिखित करने की कोशिश: क्वेरी उत्पादन "SELECT id FROM user WHERE id = ?", यह है: बल्कि क्वेरी से फिर

if (User.exists(4)) 
    //do something 

, "शून्य से आईडी का चयन करें जहां आईडी = ? "। तो, User कक्षा में table फ़ील्ड को ओवरराइड करने का कोई प्रभाव नहीं प्रतीत होता है।

मैं इसे कैसे दूर कर सकता हूं? अगर मैंने विधि को बेसमोडेल में जोड़ा है, और User के निर्माता में setTable() कहा जाता है, तो table का नया मान User कक्षा के सभी तरीकों के लिए भी उपलब्ध होगा?

+1

क्लिक वोट दें भी। – UDPLover

उत्तर

12

आप जावा में किसी भी प्रकार की स्थिर विधियों या फ़ील्ड को ओवरराइड नहीं कर सकते हैं।

public class User extends BaseModel 
{ 
    static String table = "user"; 
    //snip 
} 

यह एक नया क्षेत्र User#table कि सिर्फ BaseModel#table के वही नाम हैं करने के लिए होता बनाता है। अधिकांश आईडीई आपको इसके बारे में चेतावनी देंगे।

यदि आप बेसमोडेल में फ़ील्ड का मान बदलते हैं, तो यह अन्य सभी मॉडल वर्गों पर भी लागू होगा।

एक तरह से सामान्य आधार तरीकों

protected static boolean exists(String table, long id) throws Exception 
{ 
    Db db = Util.getDb(); 
    Query q = db.query(); 
    q.select(idField).whereLong(idField, id).limit(1).get(table); 

    return q.hasResults(); 
} 

है और उपवर्ग

public static boolean exists(long id) 
{ 
    return exists("user", id); 
} 

में इसका इस्तेमाल आप क्षेत्र दृष्टिकोण का उपयोग करना चाहते हैं तो एक BaseDAO वर्ग बनाने के लिए, आप की है, और है UserDAO (प्रत्येक मॉडल वर्ग के लिए एक) है जो तदनुसार फ़ील्ड सेट करता है। फिर आप सभी दास के सिंगलटन उदाहरण बनाते हैं।

+1

एक आईडीई डेटा छिपाने के बारे में चेतावनी क्यों देगा? –

+0

@ क्लिक करें: मैंने अपना जवाब बढ़ाया। – Cephalopod

+0

'मौजूद है()' केवल एक उदाहरण है, मेरे पास 10-20 ऐसे सहायक तरीके हैं। मैं उन सभी को अधिभारित नहीं करना चाहता, मैं सिर्फ टेबल नाम संपत्ति को बदलना चाहता हूं ताकि वे सभी काम कर सकें। –

2

जो कुछ आप करना चाहते हैं, उसे करने के लिए BaseModel में table स्थिर बनाएं। फिर BaseModel से प्राप्त अन्य कक्षाओं में, आप जो भी चाहें डिफ़ॉल्ट डिज़ाइनर में table सेट कर सकते हैं।

static { 
    table = "user"; 
} 
+1

फिर मैं एक स्थिर विधि के रूप में 'User.exists()' को कॉल नहीं कर सकता। –

+0

@ClickUpvote यह एक संकेत हो सकता है कि आप 'स्थिर 'कीवर्ड का दुरुपयोग कर रहे हैं। मैं आपके डिजाइन को देखने और इसे 'स्थिर' की आवश्यकता से छुटकारा पाने के लिए पुन: कार्य करने की अनुशंसा करता हूं() विधि – StormeHawke

+0

@StormeHawke मेरे डिजाइन में क्या गलत है? क्या यह स्पष्ट होगा अगर मैंने अपने उपयोगकर्ता मॉडल का उदाहरण दिया है कि यह जांचने के लिए कि क्या दिया गया उपयोगकर्ता आईडी वैध है या नहीं? –

8

क्योंकि जावा आप static सदस्यों ओवरराइड करने की अनुमति नहीं है, आप मूल रूप से थोड़ा अधिक वर्बोज़ लेकिन कुल मिलाकर अच्छे singleton pattern का सहारा लेना, की जरूरत है जिसमें आप अभी भी धारणात्मक लिख रहे हैं "स्थिर" कोड, लेकिन आप कर रहे हैं तकनीकी रूप से (ग्लोबल/सिंगलटन/"स्थिर") उदाहरणों का उपयोग करते हुए, इसलिए आप static की सीमाओं से प्रतिबंधित नहीं हैं।

(ध्यान दें कि आप भी तरीकों का उपयोग करने के लिए है, क्योंकि खेतों बहुरूपता में भाग नहीं लेते, और इस प्रकार ओवरराइड नहीं किया जा सकता है की जरूरत है)

public abstract class BaseTable { 
    public abstract String table(); 
    public String idField() { return "id"; } 

    public boolean exists(long id) { 
     // don't build queries this way in real life though! 
     System.out.println("SELECT count(*) FROM " + table() + " WHERE " + idField() + " = " + id); 
     return true; 
    } 
} 

public class UserTable extends BaseTable { 
    public static final User INSTANCE = new UserTable(); 
    private UseTabler() {} 

    @Override public String table() { return "user"; } 
} 

public class PostTable extends BaseTable { 
    public static final Post INSTANCE = new PostTable(); 
    private PostTable() {} 

    @Override public String table() { return "post"; } 
} 

public static void main(String[] args) { 
    UserTable.INSTANCE.exists(123); 
    PostTable.INSTANCE.exists(456); 
} 

आउटपुट: जवाब में,

SELECT count(*) FROM user WHERE id = 123 
SELECT count(*) FROM post WHERE id = 456 
+0

यहां सिंगलटन बॉयलरप्लेट के बिना, कुछ बेवकूफ प्रतिबिंब के साथ स्कैला में कैसा दिखता है: http://pastebin.com/3iujwygZ –

संबंधित मुद्दे