Java 当使用接口作为超类时,什么是合适的解决方案来强制执行polymorphysm

Java 当使用接口作为超类时,什么是合适的解决方案来强制执行polymorphysm,java,arraylist,interface,polymorphism,Java,Arraylist,Interface,Polymorphism,我最近开始学习Java编程语言,我想在模拟智能设备的应用程序上测试我的多态性知识 我创建了一个名为Os的接口,该接口的主要任务是向其继承者说明他们应该为自己实现什么 public interface Os { public ArrayList<App> getApps(); public void installApps(Collection<App> apps); } 公共接口操作系统{ 公共ArrayList getApps(); 公共应用程序(集合应

我最近开始学习Java编程语言,我想在模拟智能设备的应用程序上测试我的多态性知识

我创建了一个名为Os的接口,该接口的主要任务是向其继承者说明他们应该为自己实现什么

public interface Os {
   public ArrayList<App> getApps(); 
   public void installApps(Collection<App> apps);
}
公共接口操作系统{
公共ArrayList getApps();
公共应用程序(集合应用程序);
}
然后我创建了两个类,一个用于android,另一个用于ios。 我还创建了一个名为App的接口和两个从中继承的类,分别名为AndroidApp和IosApp

现在我想尽可能多地使用变形术,但我很难理解哪一个会用到哪里。我希望Android操作系统有一个自己的私人集合,它只接受像这样的AndroidApp类型
ArrayList
但是我想既然我想实现接口的getApps方法,我就不能将该方法的返回类型放在接口中,所以我需要层次结构中更高的部分,因此我将android操作系统的私有列表改为
ArrayList

我有一个方法负责在我拥有的Osez上安装应用程序

public class Android implements Os {
    private ArrayList<App> androidApps;
    public void installApps(Collection<App> apps) {
      //I want to only install Android apps(adding them to my private collection
        for (App app : apps) {
            if(app instanceof AndroidApp){
              System.out.println("installing android app ... "   +app.getAppName()+" installed!");
                androidApps.add(app);
            }
            else
                System.out.println(app.getAppName()+" is not an android app!");
        }
    }
}
公共类Android实现操作系统{
私人ArrayList androidApps;
公共应用程序(集合应用程序){
//我只想安装Android应用程序(将它们添加到我的私人收藏中)
用于(应用程序:应用程序){
if(AndroidApp的应用实例){
System.out.println(“安装android应用程序…”+app.getAppName()+“已安装!”);
androidApps.add(app);
}
其他的
System.out.println(app.getAppName()+“不是android应用程序!”);
}
}
}
正如我之前提到的,getApps负责将我选择的任何操作系统上安装的应用程序返还给我

这是一个概念性的问题。我很难弄清楚我是否应该为Android和Ios使用更具体的集合。 像这样

public class AndroidOs{
    private Collection<AndroidApp> androidApps;
}
公共类AndroidOs{
私人收藏安卓利达;
}
而不是使用

public class AndroidOs{
    private Collection<App> androidApps;
}
公共类AndroidOs{
私人收藏安卓利达;
}
但是如果我使用第一个私有集合,我的界面将失去作为两个操作系统通用界面的目的,因为当我尝试为android实现
getApps
时,我无法将
ArrayList
转换为
ArrayList


很抱歉,如果我的问题有点含糊,但我试图尽可能具体。

第一件事:你说你想尽可能多地使用多态性,但在软件开发中,没有一种方法或设计模式被尽可能多地使用;它们在需要时被使用.所以你必须在需要的时候使用所有的技术和材料。但无论如何,我知道你想在这里学习多态性

定义:

多态性是对象具有多种形式的能力 在OOP中,多态性的最常见用法发生在父类 引用用于引用子类对象。 (来源:)

现在有一个来自发展世界的真实例子:你有一个动物“名单”对象,您希望将所有动物保留在缓存列表中,在缓存列表中,您从数据库获取并在某些UI上表示,但在显示它们时,每种动物类型的内容略有不同。因此,在这里,您必须使用多态性将所有对象保留在一个位置,并根据它们的细微变化分配属性

Base interface: Animal-->eat();feet();
Animal1: Elephant :: Animal-->eat(){print "grass"};feet(){print "four feet"};
Animal2: Eagle :: Animal-->eat(){print "meat"};feet(){print "two feet"};
创建对象

List<Animal> animals = new ArrayList<>();
animals.add(new Elephant());
animals.add(new Eagle());
List animals=new ArrayList();
添加(新象());
添加(新鹰());
现在您将大象和老鹰放在一个列表中,并通过检查类型或每个项目仅一个字段来执行任何操作

您的问题详细信息:

Base interface: OS
public interface Os {
   public ArrayList<App> getApps(); 
   public void installApps(Collection<App> apps);
}

os1: Android :: OS
os2: IOs :: OS

Base interface: App
public interface App {
   public int getVersion();
}

app1: AndroidApp :: App
app2: IOsApp:: App
基本接口:操作系统
公共接口操作系统{
公共ArrayList getApps();
公共应用程序(集合应用程序);
}
os1:Android::OS
os2:IOs::OS
基本界面:应用程序
公共界面应用程序{
public int getVersion();
}
app1:AndroidApp::App
app2:IOsApp::App
问题一:这种结构正确吗

答:是的,有一个特定的原因。假设你有一个相当大的应用程序正在由几个开发人员开发。你是开发负责人,决定这个项目的结构和技术,你希望所有操作系统的结构都像你的界面一样:假设我们想添加blackberry,那么我们将从操作系统和Blac派生BlacberryOSkberryApp应用程序来自应用程序。这将为您提供添加到系统中的每个新操作系统的一致性,这是正确的

问题二:有没有更好的办法

答:总是有更好的方法。在这里,你说你是Java PL开发新手,想学习多态性。所以我建议你像我解释的那样尝试:创建一个操作系统列表,并在那里添加AndroidOS、OIS、Blackeryy等。在迭代列表的同时,根据它的类型打印特定的内容,这样你就可以在那里取消理解多态性到底是什么,为什么需要它


通过提供方法覆盖,您将看到打印特定于子类型的属性非常容易,并且具有多态性结构。

第一件事:您说您希望尽可能多地使用多态性,但在软件开发中,没有一种方法或设计模式被尽可能多地使用;它们被使用d“在需要的时候”。所以你必须在需要的时候使用所有的技术和东西。但无论如何,我知道你想在这里学习多态性

定义:

多态性是对象具有多种形式的能力 在OOP中,多态性的最常见用法发生在父类 引用用于引用子类对象。 (来源:)

public interface Os<A extends App> {
   List<A> getApps(); 
   void installApps(Collection<A> apps);
}

public class Android implements Os<AndroidApp> {
    private ArrayList<AndroidApp> androidApps;

    @Override
    public void installApps(Collection<AndroidApp> apps) {
        for (AndroidApp app : apps) {
            System.out.println("installing android app ... "   +app.getAppName()+" installed!");
            androidApps.add(app);
        }
    }
}