问题描述
由于我们无法从抽象类创建对象,这是如何工作的?
在这个类中,我声明了一个 Alien
数组,而 Alien
类是一个抽象类。
在构造函数中创建是如何工作的?
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
的具体类的任何实例。
关键区别在于您创建了一个 Alien[]
类型的变量。将此视为存储您可能创建的任何外星人的地方。您还没有尝试使用以下内容创建任何内容来存储:
1. Alien a = new Alien();
2. aliens[0] = a;
这是抛出错误的地方。 =
的右侧是对象在第 1 行“创建”的地方。(虽然它不能被创建,因为它是抽象的)左侧是创建引用变量 a
的地方存储一个 Alien.which 本身就可以了,就像你的情况一样。抽象/接口类型变量本身就可以,然后我们可以将这些抽象/接口类型的具体实现存储在这些变量中。
正如其他人所说,您创建了一个空数组,能够保存对从 Alien
类扩展的类的对象的引用。但是您还没有实例化任何此类对象。因此该数组保持为空。
下一步是创建抽象 Alien
的具体子类。
public class Martian extends Alien { … }
public class Saturnian extends Alien { … }
为这些具体类的对象创建一个空的持有人。还没有 Alien 实例,也没有调用 Alien 和两个子类的构造函数。创建这个没有 Alien
对象的空数组就像建造一个没有书的书柜。将空书架准备好装书并不能创造书籍。
Alien[] aliens = new Alien[3] ; // Empty container. Three slots holding `null`. No `Alien`,`Martian`,or `Saturnian` objects exist yet.
然后您可以实例化这些不同子类的对象,同时将它们称为 Alien
对象。这就是polymorphism在起作用。
当我们创建同时也是 Martian
对象的每个 Saturnian
或 Alien
对象时,我们将对该对象的引用放入数组的一个槽中。
aliens[0] = new Martian( … ) ;
aliens[1] = new Martian ( … ),aliens[2] = new Saturnian( … ) ;
此时,我们有一个包含 3 个 Alien
对象(2 个 Martian
对象和 1 个 Saturnian
对象)的数组。实际上,我们有一个包含三个对这三个对象的引用的数组。对象位于内存中的其他位置。
接下来我们使用 List
而不是数组来收集三个外星人。效果相同,但 Java Collections 比数组更方便和灵活。
List< Alien > aliens =
List.of(
new Martian( … ),new Martian ( … ),new Saturnian( … ) ;
)
;