2017-09-11 8 views
2

Je crée une base de données SQL et je base this site. Le problème est, je ne sais pas comment puis-je accéder aux méthodes de classe interne, alors que la classe externe a un constructeur privé . méthode à partir d'un autre fichier javaAccéder à une sous-classe interne avec un constructeur de classe privée d'une autre classe

public class MyDBHandler { 

    private MyDBHandler() { 
    } 

    public static class FeedEntry implements BaseColumns { 
     public static final String TABLE_NAME = "Tasks"; 
     public static final String COLUMN_NAME_TITLE = "TASK_LABEL"; 
    } 

    public class FeedReaderDbHelper extends SQLiteOpenHelper { 
     public static final int DATABASE_VERSION = 1; 
     public static final String DATABASE_NAME = "myDatabase.db"; 

     public FeedReaderDbHelper(Context context) { 
      super(context, DATABASE_NAME, null, DATABASE_VERSION); 
     } 

     public long saveTasks(String title) { 
      SQLiteDatabase db = this.getWritableDatabase(); 

      ContentValues contentValues = new ContentValues(); 
      contentValues.put(FeedEntry.COLUMN_NAME_TITLE, title); 

      long newRowId = db.insert(FeedEntry.TABLE_NAME, null, contentValues); 
      return newRowId; 

     } 
    } 
} 

J'essaie d'accéder saveTasks méthode (titre String) de onClick (Voir v).

J'ai essayé STH comme ceci:

MyDBHandler.FeedReaderDbHelper dbHelper = new MyDBHandler.FeedReaderDbHelper(v.getContext()); 

mais bien sûr, je reçois une erreur « MyDBHandler n'est pas une classe englobante ».

OU

MyDBHandler.FeedReaderDbHelper dbHelper= new MyDBHandler().new FeedReaderDbHelper(v.getContext()); 

mais encore une fois, studio Android ne cesse de me dire: "MyDbHandler a un accès privé"

Est-il même possible de le faire de cette façon?

+0

Déplacez votre classe FeedReaderDbHelper dans un fichier séparé –

+2

Pourquoi implémentez vous exactement comme une classe interne? Dans l'exemple, il s'agit clairement d'une classe distincte. –

+0

Pourquoi ne pouvez-vous pas rendre le constructeur public? –

Répondre

1
MyDbHandler has a private access 

Ce n'est pas de la classe interne, il est sur le constructeur dans ce Je suppose que j'ai vu ce guide (site Web) avant et je ne savais pas vraiment pourquoi ils l'ont ajouté en tant que classe interne. Je me souviens qu'ils ont dit de rendre le constructeur privé afin que personne ne puisse en créer un objet. Il suffit donc de déplacer le FeedReaderDbHelper dans un fichier séparé, puis cela fonctionnera.

Mais si pour une raison quelconque, vous voulez garder la classe interne définit alors comme statique

public static class FeedReaderDbHelper 

Ensuite, appelez le même code et il devrait fonctionner

+0

Le problème est, quand je déplace FeedReaderDbHelper pour séparer le fichier, il n'a tout simplement pas accès aux variables, comme SQL_DELETE_ENTRIES. Je devrais créer des getters pour le résoudre. Serait-ce une solution optimale? – Mike

+0

bien sûr, il a accès, ils sont décentralisés public statique de sorte que vous pouvez y accéder comme ce CLASS_NAME.STATIC_PUBLIC_VARS, sinon getters seulement sera optimal un oui –

+0

ouais, je voulais simplement coller autant que ce n'est que possible à ce guide de développement android , où les vars sont privés. De toute façon, je vais juste utiliser des getters. – Mike

2

Si vous voulez vraiment garder votre classe interne puis le rendre statique et de l'utiliser comme suit:

new MyDBHandler.FeedReaderDbHelper(getContext())

0

La classe interne est juste une façon de propre séparer certaines fonctionnalités qui appartiennent vraiment à la classe externe d'origine. Ils sont destinés à être utilisés lorsque vous avez 2 exigences:

  1. Certains morceau de fonctionnalité dans votre classe externe serait plus clair si il a été mis en œuvre dans une catégorie distincte.
  2. Bien que ce soit dans une classe distincte, la fonctionnalité est très étroitement liée à pour que la classe externe fonctionne.

Compte tenu de ces exigences, les classes internes ont un accès complet à leur classe externe.Comme ils sont en fait un membre de la classe externe, il est logique qu'ils ont accès à des méthodes et des attributs de la classe externe - y compris privates

Suivants sont la voie:

new MyDBHandler.FeedReaderDbHelper(getContext()) 

I have run your code by following way, Please have a look.

public class MyDBHandler { 

     public static FeedReaderDbHelper feedReaderDbHelper; 
     private MyDBHandler() { 
     } 

     public static FeedReaderDbHelper getFeedReaderDbHelper() 
     { 
      if(feedReaderDbHelper == null) 
       feedReaderDbHelper = new MyDBHandler(). new FeedReaderDbHelper(); 

      return feedReaderDbHelper; 
     } 
     public static class FeedEntry { 
      public static final String TABLE_NAME = "Tasks"; 
      public static final String COLUMN_NAME_TITLE = "TASK_LABEL"; 
     } 

     public class FeedReaderDbHelper { 
      public static final int DATABASE_VERSION = 1; 
      public static final String DATABASE_NAME = "myDatabase.db"; 

      public FeedReaderDbHelper() { 
       //super(context, DATABASE_NAME, null, DATABASE_VERSION); 
      } 

      public long saveTasks(String title) { 
       System.out.println(title); 

       return 1L; 
      } 
     } 


     public static void main(String[] args) { 
      MyDBHandler.getFeedReaderDbHelper().saveTasks("title"); 
     } 
    } 
1

Vous pouvez le faire

public class MyDBHandler { 

private MyDBHandler() { 
} 

public static class FeedEntry implements BaseColumns { 
    public static final String TABLE_NAME = "Tasks"; 
    public static final String COLUMN_NAME_TITLE = "TASK_LABEL"; 
} 

public static class FeedReaderDbHelper extends SQLiteOpenHelper { 
    public static final int DATABASE_VERSION = 1; 
    public static final String DATABASE_NAME = "myDatabase.db"; 

    public FeedReaderDbHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    public long saveTasks(String title) { 
     SQLiteDatabase db = this.getWritableDatabase(); 

     ContentValues contentValues = new ContentValues(); 
     contentValues.put(FeedEntry.COLUMN_NAME_TITLE, title); 

     long newRowId = db.insert(FeedEntry.TABLE_NAME, null, contentValues); 
     return newRowId; 

    } 
    } 
} 
la classe interne statique à utiliser

Maintenant, pour obtenir une instance de FeedReaderDbHelper vous pouvez

MyDBHandler.FeedReaderDbHelper dbHelper = new MyDBHandler.FeedReaderDbHelper(v.getContext()); 

et d'appeler des méthodes

String title = "your title"; 
dbHelper.saveTasks(title)