Политизм и массивы подтипов
Computer[] labComputers = new Computer[10];
с
public class Computer {
...
void toString(){
// print computer specs
}
}
public class Notebook extends Computer{
...
void toString(){
// print computer specs + laptop color
}
}
каждая индексированная переменная labComputers[i]
может ссылаться либо на объект Computer
, либо на объект Notebook
, потому что Notebook
является подклассом Computer
. Для вызова метода labComputers[i].toString()
, полиморфизм гарантирует, что вызывается правильный метод toString
.
Интересно, что если мы делаем
Notebook[] labComputers = new Notebook[10];
какой тип или ошибка я получу, если ссылаюсь на объект Computer
и объект Notebook
Ответы
Ответ 1
Поскольку вопрос конкретно задает вопрос о kind of error
, я объясню их ниже сценариями
Если вы делаете ниже
Notebook[] labComputers = new Notebook[10];
Теперь вы можете устанавливать объекты Notebook только в массиве.
labComputers[0] = new Notebook(); // Fine
labComputers[1] = new Computer(); // Compilation error
Теперь, если вы делаете
Computer[] notebooks = new Notebook[10];
notebooks[0] = new Notebook();
notebooks[1] = new Computer(); // <--- ArrayStoreException
Поскольку массивы covarant
, reified
в природе, т.е. если Sub
является подтипом Super
, тогда тип массива Sub[]
является подтипом Super[]
, а массивы применяют их типы элементов во время выполнения, это вызовет ArrayStoreException
Вы можете прочитать документацию oacle о Polymorphism, чтобы узнать больше о том, как это работает.
Ответ 2
Я думаю, вам нужно понять, как работает полиморфизм.
Полиморфизм - это функция, которая позволяет мультиплетным типам данных вести себя одинаково с помощью общего интерфейса.
Например,
Computer // Base class
| |
Notebook Desktop // Both inherits of Computer
Полиморфизм позволит вам управлять массивом компьютеров, независимо от того, являются ли они ноутбуком или рабочим столом.
Computer[] computerArray = new Computer[2];
computerArray[0] = new Notebook();
computerArray[1] = new Desktop();
Преимущество этого заключается в том, что вам не нужно знать, какой подтип компьютера, с которым вы работаете. Они будут вести себя как компьютер.
Теперь возникает большая разница, в вашем классе Computer вы могли бы:
public Class Computer
{
abstract void MoveMouse();
}
Это даст вам возможность переопределить этот метод по-разному в ноутбуках и на рабочем столе. Теперь MoveMouse() будет доступен для computeArray, потому что мы определили его на компьютере.
Если вы это сделаете:
computerArray[0].MoveMouse(); // which contains a Notebook
computerArray[1].MoveMouse(); // which contains a Desktop
который вызовет функцию, которая реализована в Notebook
или Desktop
.
Пример реализации этих функций:
public Class Notebook extends Computer
{
void MoveMouse();
{
MousePad.Move();
}
}
public Class Desktop extends Computer
{
void MoveMouse();
{
USBMouse.Move();
}
}
Ответ 3
Каждая индексированная переменная labComputers[i]
может ссылаться либо на объект Computer
, либо на объект Notebook
.
Это технически верно, но вы должны помнить, что каждый Notebook
является объектом Computer
, но не каждый Computer
является Notebook
.
Следовательно, если у вас
Notebook[] labComputers = new Notebook[10];
вы не сможете разместить экземпляры Computer
в массиве, потому что не каждый Computer
является Notebook
- и ваш массив может содержать только Notebook
s.