从另一个类访问具有私有类构造函数的内部子类

问题描述:

我创建SQL数据库和我基于this site. 问题是,我不知道如何访问内部类的方法,而外部类具有私有构造函数。从另一个类访问具有私有类构造函数的内部子类

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; 

     } 
    } 
} 

我想从另一个java文件的onClick(View v)方法访问saveTasks(String title)方法。

我试过某事像这样:

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

但当然,我得到一个“MyDBHandler不是一个封闭类”错误。

OR

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

但同样,Android的工作室一直告诉我: “MyDbHandler有一个私人的访问”

它甚至有可能做到这一点呀?

+0

将您FeedReaderDbHelper全班分成单独的文件 –

+2

为什么你到底是执行它作为一个内部类?在这个例子中,它显然是一个单独的课程。 –

+0

为什么你不能公开构造函数? –

MyDbHandler has a private access 

这不是内部类,它是关于在构造函数类

private MyDBHandler() { 
} 

我想我以前看过这个指南(网站),我不知道他们为什么把它作为内部类加入。我记得他们说要让构造函数是私有的,所以没有人可以创建一个对象。 因此只需将FeedReaderDbHelper移至单独的文件,然后就可以工作。

但是,如果由于某种原因,你要保持它的内部类,然后把它定义为静态

public static class FeedReaderDbHelper 

然后调用相同的代码,它应该工作

+0

问题是,当我将FeedReaderDbHelper移动到单独的文件时,它只是无法访问变量,如SQL_DELETE_ENTRIES。我将不得不创建getters来解决它。它会是一个最佳解决方案吗? – Mike

+0

ofcourse它有访问他们是decalered公共静态,所以你可以访问它们像这样CLASS_NAME.STATIC_PUBLIC_VARS,否则getters只会是最佳的一个是的 –

+0

是啊,我只是想尽可能多地坚持它只是可能的这个Android开发指南,那里的私人物品。无论如何,我只会使用getters。 – Mike

如果你真的想保持你内心的类,然后让它静止,并用它如下:

new MyDBHandler.FeedReaderDbHelper(getContext())

内部类是只是一种干净分离出真正属于原始外部类的一些功能。他们的目的是用来当你有2个要求:

  1. 部分的一些功能在外部类,如果它是在一个单独的类中实现的将是最明显的 。
  2. 尽管它在一个单独的类中,但它的功能与 非常紧密地联系到外部类的工作方式。

鉴于这些要求,内部类可以完全访问其外部类。由于他们基本上外部类中的一员,这是有道理的,他们可以访问方法和外部类的属性 - 包括私处

以下的方式:

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"); 
     } 
    } 

可以使内部类的静态使用它

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; 

    } 
    } 
} 

我们得到FeedReaderDbHelper的实例可以

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

,并调用方法

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