【问题标题】:How to pass a class as a parameter to a method as if it were a dynamic variable?如何将类作为参数传递给方法,就好像它是动态变量一样?
【发布时间】:2016-05-02 09:23:50
【问题描述】:

我正在尝试根据调用方法的某些条件来传递类。如果在 Albums 中调用方法,则使用类“album”,但如果在 Artists 中调用,则使用类“artist”。

我还是 Java 新手,似乎无法掌握这一点。

这是假设调用这些不同类的方法。

private int songCounter;
    public ArrayList getSongs(Context context, String type, int max, Class cls){

        String select;

        switch (type) {
            case "albums": {
                select = IS_MUSIC + " != 0 AND ALBUM NOT NULL) GROUP BY (ALBUM";
                break;
            }
            case "artists": {
                 select = IS_MUSIC + " != 0 AND ARTIST NOT NULL) GROUP BY (ARTIST";
                break;
            }
            default: {
                 select = IS_MUSIC + " != 0";
                break;
            }
        }

        ArrayList songList          = new ArrayList();

        Cursor c                    = context.getContentResolver().query(EXTERNAL_CONTENT_URI,null,select,null,null);
        if(c!= null && c.moveToFirst()){
            do {
                long    id          = c.getLong(c.getColumnIndex(_ID));
                long    albumId     = c.getLong(c.getColumnIndex(ALBUM_ID));
                String  artist      = c.getString(c.getColumnIndex(ARTIST));
                String  album       = c.getString(c.getColumnIndex(ALBUM));
                String  title       = c.getString(c.getColumnIndex(TITLE));

                songCounter++;

                if (songCounter < max) {
/////// I'm having a problem here, how do I call "cls"?
                        songList.add(new cls(id, album, artist, title, getArt(context, albumId)));
                }
            }
            while (c.moveToNext());
        }
        if (c != null) {
            c.close();
        }
        return songList;
    }

下面是一个类“Album”,是需要调用的类的一个例子。

public class Album {
    private long    id;
    private String  title;
    private String  artist;
    private String  album;
    private String  year;
    private String  genre;
    private String  duration;
    private BitmapDrawable art;

    public Album(long songID, String songTitle, String songArtist, String songAlbum, BitmapDrawable songArt) {
        id          = songID;
        title       = songTitle;
        artist      = songArtist;
        album       = songAlbum;
        art     = songArt;
    }

    public long getID(){
        return id;
    }

    public String getTitle(){
        return title;
    }

    public String getArtist(){
        return artist;
    }

    public String getAlbum(){
        return album;
    }

    public String getDuration(){
        return duration;
    }

    public BitmapDrawable getArt(){
        return art;
    }

}

以及我是如何尝试调用“getSongs”方法的。

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        super.onCreateView(inflater,container,savedInstanceState);

        View rootView       = inflater.inflate(R.layout.library_albums, container, false);
        this.mView          = rootView;
        songView            = (ListView) mView.findViewById(R.id.album_list);
        songList            = new ArrayList<Album>();
        this.music          = new Music();

This is where I don't know what to do also/////

        songList            = music.getSongs(mView.getContext(), "albums", 200, "album/artist/song class here);

        AlbumAdapter songAdt = new AlbumAdapter(mView.getContext(), songList);
        songView.setAdapter(songAdt);
        return rootView;
    }

也许我只是需要一种新的架构来解决这个问题?

【问题讨论】:

  • 你使用的是哪个版本的java?
  • @kakurala 版本 7。
  • IS_MUSIC 中有什么?还有,你为什么要通过这门课?我想这取决于你所处的观点,对吧?就像如果您在艺术家的视图中,它将显示所有艺术家的歌曲,如果您在特定专辑的视图中,它将显示专辑的所有歌曲?
  • IS_MUSIC 是我用来检查返回的行是否是音乐而不是铃声或其他内容的列。

标签: java class methods reflection mediastore


【解决方案1】:

你可以做

Album extends SongCollection

Artist extends SongCollection

SongCollection 你将拥有

abstract List<Song> getSongs();

ArtistAlbum 中,您将覆盖getSongs(),返回正确的查询结果。

对于查询,您可能希望有一个单例类MusicDatabase,方法为List&lt;Song&gt; query(String queryText, String... params)

【讨论】:

  • 应该已经展示了getSongs方法所在的类的结构。该类是“音乐”,然后使用一些和其他方法和 getSongs 作为另一种方法。
  • 什么是“SongCollection”? getSongs 的父类?
  • SongCollection 是一个抽象类,具有抽象方法 getSongs() 然后 Artist 将 getSong 覆盖为 MusicDatabase.query('artist=' + artistName());和专辑不同
【解决方案2】:

忽略您的代码存在的许多替代设计,只关注您的问题标题,您可以执行以下操作: (这出乎我的意料,未经测试的代码直接写入浏览器,因此可能需要调整才能编译)

    public <T extends BaseSongs> ArrayList<T> getSongs(Context context, int max, Class<T> cls){
           String select;

            switch (cls. getName()) {
                case "Albums": {
                    select = IS_MUSIC + " != 0 AND ALBUM NOT NULL) GROUP BY (ALBUM";
                    break;
                }
                case "Artists": {
                     select = IS_MUSIC + " != 0 AND ARTIST NOT NULL) GROUP BY (ARTIST";
                    break;
                }
                default: {
                     select = IS_MUSIC + " != 0";
                    break;
                }
            }

       ArrayList<BaseSongs> songList = new ArrayList<>();  // java 7

      if (songCounter < max) {
          /////// Use Reflection
          Constructor ctr = cls.getConstructor(<list the types for ctr args here>);
          songList.add(ctr.newInstance(id, album, artist, title, getArt(context, albumId)));
       }

       return songList;

您调用 getSongs() 的方式是:

songList = music.getSongs(mView.getContext(), 200, Albums.class);

【讨论】:

  • 好的,那么 BaseSongs 是什么?
  • 专辑、艺术家或任何您想要返回 songList 的基类
  • 我在想,是否可以将我提出的问题中的“专辑”类收缩为“音乐”类(“getSongs”的父类)的方法,以便 getSongs调用本地方法而不是外部类?
  • 如果你问我,将Albums 混入Music 将是一个糟糕的设计。分离清晰且概念上正确。
猜你喜欢
  • 2020-05-25
  • 2013-06-05
  • 2018-09-05
  • 2012-03-15
  • 2018-09-03
  • 2015-04-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多