Java 如何调用子类';如果我没有';我不知道我';我必须这么做吗?

Java 如何调用子类';如果我没有';我不知道我';我必须这么做吗?,java,collections,map,polymorphism,Java,Collections,Map,Polymorphism,如果我有一个类来描述例如people,named Person,然后它有6个子类,比如Child,成年男子,成年女子等。它们都有ID,头发颜色,眼睛颜色等。只是它们的外观不同,所以我的所有子类都包含它们自己的paint()方法。每个人都有两个坐标来告诉程序在框架上绘制它们的位置,所有子类都得到这些坐标,如下所示: class AdultMan extends Person { AdultMan(int x, int y) { super(x,y);

如果我有一个类来描述例如people,named Person,然后它有6个子类,比如Child,成年男子,成年女子等。它们都有ID,头发颜色,眼睛颜色等。只是它们的外观不同,所以我的所有子类都包含它们自己的paint()方法。每个人都有两个坐标来告诉程序在框架上绘制它们的位置,所有子类都得到这些坐标,如下所示:

class AdultMan extends Person
{
    AdultMan(int x, int y) {
        super(x,y); 
            // I haven't yet worked with the hair color, eye color...
            // only the coordinates to test my idea out
    }

    public void paint(Graphics g) {
            int x = getX();
            int y = getY();
            // The drawing of an adult man from basic shapes 
            // based on the given coordinates (and colors later)
    }
}
for (Person person : persons) 
{
  // (persons is the name of my collection)
  if(person.typeName.equals("adultMan"))
  {
     person = new AdultMan(person.x,person.y);
     person.paint(g);
  }
}
因此,在另一个类中,我处理给定的数据,我将它们都放在一个像
map
(整数是ID) 然后在一个扩展Jframe的类中,我将映射的值放入一个集合中,并按如下方式迭代它们:

class AdultMan extends Person
{
    AdultMan(int x, int y) {
        super(x,y); 
            // I haven't yet worked with the hair color, eye color...
            // only the coordinates to test my idea out
    }

    public void paint(Graphics g) {
            int x = getX();
            int y = getY();
            // The drawing of an adult man from basic shapes 
            // based on the given coordinates (and colors later)
    }
}
for (Person person : persons) 
{
  // (persons is the name of my collection)
  if(person.typeName.equals("adultMan"))
  {
     person = new AdultMan(person.x,person.y);
     person.paint(g);
  }
}

我有6种类型的人,所以我想对每种类型的人都这样做问题是,如果我的地图上最多有40人,那么可能会有30个成年人,这只会在框架上画出第一个成年人,然后跳到下一个不同的类型。

这并不能完全解决您的问题,但您似乎误解了继承在Java中的工作原理

如果您有一个类
Person
和一个类
AdultMan
继承它,这意味着您应该能够在任何可以使用
Person
的地方使用AdultMan的实例。这是我们的本质。因此,如果方法具有以下签名:

public void tickle(Person p)
然后,您可以使用成人(或其类继承人的任何其他对象)调用该方法。同样在Java中,如果子类定义了与超类相同的方法签名,则称其覆盖该方法。下面的代码说明了这一点:

class Person {
   public void laugh() {
       System.out.pring("Tihi");
   }
}  

class AdultMan extends Person {
   public void laugh() {
       System.out.pring("Hahaha");
   }
}

class AdultWoman extends Person {
   public void laugh() {
       System.out.pring("Hihihi");
   }
}

class Child extends Person { }
AdultMan
adultwomen
覆盖
laugh
方法,因此每当对这些类的实例调用
laugh
方法时,都将调用该类的方法。持有对象的变量类型是否为
,这无关紧要。如果有一个方法覆盖了laugh方法,则该方法就是获取调用的方法。在
子类
的情况下,它没有定义自己的
look
方法,因此只是从Person继承该方法。说明这一点的可运行示例如下:

public class App {
    public static void main(String[] args) {
        Person person = new Person();
        Person man = new AdultMan();
        Person woman = new AdultWoman();
        Person child = new Child();
        List<Person> persons = new ArrayList();
        persons.add(person);
        persons.add(man);
        persons.add(woman);
        persons.add(child);

        for(Person p : persons) {
            System.out.print("Laugh: ");
            p.laugh();
        }
        // This will print:
        // Laugh: Tihi
        // Laugh: Hahaha
        // Laugh: Hihihi
        // Laugh: Tihi
    }
}
公共类应用程序{
公共静态void main(字符串[]args){
Person=新人();
个人男子=新成年男子();
个人女性=新成年女性();
个人子女=新子女();
List persons=new ArrayList();
人。添加(人);
人。加上(人);
增加(女性);
增加(儿童);
用于(人员p:人员){
系统输出打印(“笑:”);
p、 笑();
}
//这将打印:
//笑:蒂希
//笑:哈哈哈
//笑:嗨嗨
//笑:蒂希
}
}

等等。。。您只需在
.paint()
之前检查类型即可。这看起来更像是
.paint()
中的一个问题。即使您迭代
Person
对象,调用
.paint()
也将调用实际实例的
.paint()
方法,即对人的正确实现,如果一个人是AdultMan的实例,那么您不需要创建新的AdultMan对象,只需对从集合中获得的人调用paint方法即可。这将从AdultMan调用正确的paint方法(您应该在类Person中定义一个抽象的paint方法来执行此操作)。我不知道你为什么说油漆只会在第一次进行。您迭代所有对象,所有对象都将被绘制。并且使用字段
typeName
存储类的名称也不好-尤其是当您可以只使用
instanceof
…--虽然在这种情况下,您不需要任何
实例
——只需根据上面的注释调用它即可在我的Person类中,但我真的不知道如何以及在何处决定调用哪个子类的paint()方法。除了围绕OOPLs的明显混乱之外,为什么它不在列表中不断迭代?它不会停止在第一个“成人”@user1927323您不需要决定调用哪个类的方法,这是在Java中执行OOP的要点之一。