我们可以从抽象 class 创建一个对象吗?

Can we create an object from an abstract class?

既然我们无法从抽象中创建对象,那么这是如何工作的 class? 在这个class中我声明了一个Alien数组,Alienclass是一个抽象class。 构造函数中的创建是如何工作的?

public class AlienPack {

    private  Alien[] aliens;  //composition 

    //cons with para of array size 
    public AlienPack(int numAliens) {
        aliens = new Alien [numAliens]; //how can we create objects from AC????????????
    }

    public void addAlien(Alien newAlien, int index) {
        aliens[index] = newAlien;
    }

    public Alien[] getAliens() {
        return aliens;
    }

    public int calculateDamage() {
        int damage = 0;
        for (int i=0; i<aliens.length; i++)            // Call getDamage() from each alien to
            damage += aliens[i].getDamage();             // calculate total damage??????????????????????????
        return damage;
    }
}

您没有创建 Alien 的任何实例。您正在创建一个 数组 ,其中每个元素都是 null,并且可能包含扩展 Alien.[=13= 的具体 class 的任何实例]

关键区别在于您创建了一个类型为 Alien[]变量。将此视为存储您可能创建的任何外星人的地方。您还没有尝试创建任何东西存储在那里:

1. Alien a = new Alien();
2. aliens[0] = a;

这是抛出错误的地方。 = 的右侧是第 1 行“创建”对象的位置。(虽然它不能创建,因为它是抽象的)左侧是创建引用变量 a 的位置像你的情况一样,单独存储 Alien.Which 就可以了。抽象/接口类型变量本身很好,然后我们可以在这些变量中存储这些抽象/接口类型的具体实现。

正如其他人所说,您已经创建了一个空数组,该数组能够保存对从 Alien class 扩展的 classes 对象的引用。但是您还没有实例化任何此类对象。因此该数组保持为空。

您的下一步是创建抽象 Alien 的具体子class。

public class Martian extends Alien { … }
public class Saturnian extends Alien { … }

为这些具体 classes 的对象创建一个空容器。还没有 Alien 实例,也没有调用 Alien 和两个 subclasses 的构造函数。创建这个没有 Alien 对象的空数组就像构建一个没有书的书架。准备好放书的空书架并不会创造出书。

Alien[] aliens = new Alien[3] ;  // Empty container. Three slots holding `null`. No `Alien`, `Martian`, or `Saturnian` objects exist yet.

然后您可以实例化这些不同子class 的对象,同时将它们称为Alien 对象。那就是 polymorphism 在行动。

当我们创建每个同时也是 Alien 对象的 MartianSaturnian 对象时,我们将对所述对象的引用放入数组的槽中。

aliens[0] = new Martian( … ) ;
aliens[1] = new Martian ( … ) ,
aliens[2] = new Saturnian( … ) ;

此时,我们有一个包含 3 个 Alien 个对象(2 个 Martian 个对象和 1 个 Saturnian 个对象)的数组。实际上,我们有一个包含对这三个对象的三个 引用 的数组。这些对象位于内存中的其他位置。

接下来我们用一个List rather than an array to collect three aliens. Same effect, but the Java Collections比数组更方便灵活

List< Alien > aliens =
    List.of(
        new Martian( … ) ,
        new Martian ( … ) ,
        new Saturnian( … ) ;
    )
;