简体   繁体   English

如何在不同情况下使用不同的子类?

[英]How can I use different subclass in different situation?

I have a dilemma like this: 我有这样的困境:

I have parent class MediaPlayer , then some subclass extends from it, let's say they are MediaPlayerSub1 MediaPlayerSub2 MediaPlayerSub3 , all of they extend some differnt methods. 我有一个父类MediaPlayer ,然后从它继承了一些子类,假设它们是MediaPlayerSub1 MediaPlayerSub2 MediaPlayerSub3 ,它们都扩展了一些不同的方法。

In my client, I want use different subclass in different situation, so I am faced with difficulties: when I use MediaPlayer I always need to judge which subclass it is, for example: 在我的客户端中,我想在不同的情况下使用不同的子类,因此遇到了很多困难:当我使用MediaPlayer我总是需要判断它是哪个子类,例如:

MediaPlayer mMediaPlayer = initPlayer()
// ... do some operation from MediaPlayer

// ... do operation from sub class
if (mMediaPlayer instanceof MediaPlayerSub1) {
    mMediaPlayer = (MediaPlayerSub1)mMediaPlayer;
    // ... do operation from MediaPlayerSub1
} else if (mMediaPlayer instanceof MediaPlayerSub2) {
    mMediaPlayer = (MediaPlayerSub2)mMediaPlayer;
    // ... do operation from MediaPlayerSub2
} else if (mMediaPlayer instanceof MediaPlayerSub3) {
    mMediaPlayer = (MediaPlayerSub3)mMediaPlayer;
    // ... do operation from MediaPlayerSub3
}

Do I have better choice to refactor the code to reduce the coupling? 我是否有更好的选择来重构代码以减少耦合?

If you are the author of MediaPlayer you can just write an abstract method in MediaPlayer 如果您是MediaPlayer的作者,则可以在MediaPlayer中编写一个抽象方法

abstract void action();

and override it in each of the subclasses, like this: 并在每个子类中覆盖它,如下所示:

@Override
void action() {
   // do something
}

Then you just need to call mMediaPlayer.action() . 然后,您只需要调用mMediaPlayer.action()

If you are not the author of MediaPlayer you can do the same thing but using wrapper classes, like this 如果您不是MediaPlayer的作者,则可以执行相同的操作,但可以使用包装器类,如下所示

abstract class MediaPlayerWrapper {

    private final MediaPlayer mediaPlayer;

    MediaPlayerWrapper(MediaPlayer mediaPlayer) {
       this.mediaPlayer = mediaPlayer;
    }

    MediaPlayer getMediaPlayer() {
        return mediaPlayer;
    }

    abstract void action();
}

Then you create subclasses for each subclass of MediaPlayer. 然后,为MediaPlayer的每个子类创建子类。 Like this: 像这样:

final class MediaPlayerWrapper1 extends MediaPlayerWrapper {       

    MediaPlayerWrapper1(MediaPlayerSub1 mediaPlayer) {
        super(mediaPlayer);
    }

    @Override 
    public void action() {
        // do stuff with the MediaPlayer. You will need to call getMediaPlayer() first.
    }
}

Then you just need to use a MediaPlayerWrapper instead of a MediaPlayer . 然后,您只需要使用MediaPlayerWrapper而不是MediaPlayer

The solution is to refactor using famous FACTORY pattern. 解决方案是使用著名的FACTORY模式进行重构。

Factory pattern in short is a creational pattern where you dynamically load classes based on Input. 简而言之,工厂模式是一种创建模式,您可以在其中基于Input动态加载类。 The client has no information whatsoever on the implementation or sub classes. 客户端没有关于实现或子类的任何信息。

In your case , the code you posted above is client and ideally it should not be aware of subclasses. 在您的情况下,上面发布的代码是客户端,理想情况下,它应该不知道子类。 Rather it should be aware of a Factory class who is responsible to provide client with desired subclass. 而是应该知道有一个Factory类负责向客户提供所需的子类。

public enum MediaType {
   MEDIA1  ,MEDIA2 , MEDIA3, NULL ;
}

public class MediaFactory {

     public static MediaPlayer getMediaInstance(MediaType mediaType) { 
          if( mediaType == MediaType.MEDIA1) return new MediaPlayerSub1(mediaType);
          if( mediaType == MediaType.MEDIA2) return new MediaPlayerSub2(mediaType);
          if( mediaType == MediaType.MEDIA3) return new MediaPlayerSub3(mediaType);  
          return new MediaPlayer();
    }
 }
  // client code
  MediaPlayer mediaPlayer = MediaFactory.getMediaInstance(MediaType.NULL); 
  MediaPlayer mediaPlayer = MediaFactory.getMediaInstance(MediaType.MEDIA1);
  MediaPlayer mediaPlayer = MediaFactory.getMediaInstance(MediaType.MEDIA2);
  MediaPlayer mediaPlayer = MediaFactory.getMediaInstance(MediaType.MEDIA3);

  if (mediaPlayer.getMediaType() ==MediaType.MEDIA1) // do mediaSub1 operations
  if (mediaPlayer.getMediaType() ==MediaType.MEDIA2) // do mediaSub2 operations
  if (mediaPlayer.getMediaType() ==MediaType.MEDIA3) // do mediaSub3 operations

You might seem round about way, but idea is client should not know about subclasses and its kind of loose coupling, making code more modular. 您可能看起来很绕道,但是想法是客户不应该知道子类及其松散耦合的种类,从而使代码更具模块化。 Hope this answered your question. 希望这回答了您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何根据公共标识符(java)实例化不同的子类 - How can i instantiate a different subclass based on common identifier (java) 如何在不同的类中使用特定于子类的方法? - how to use a subclass specific method in a different class? 如何在其他类中使用方法? - How can I use a method in a different class? 如何将“ for”用于变量和不同的数字? - How I can use the “for” with a variable and different numbers? 如何在一个子类中的不同方法中调用超类的几个对象? - How can I call few objects of superclass inside different methods in one subclass? 在我的情况下,如何在 springboot 的不同 url 中指定不同的身份验证? - How to specific different authentications in different urls in springboot in my situation? 如何在子类中访问超类的“protected static”变量,其中子类位于不同的包中..? - How can ‘protected static’ variable of superclass be accessed in the subclass, where subclass resides in different package..? 我如何正确使用布尔值来使用方法的不同部分 - How can i correctly use boolean to use different parts of a method Java不同情况划分 - Java different situation division 在哪种情况下可以在DatagramSocket中使用getPort()? - In which situation can I use getPort() in a DatagramSocket?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM