Подтвердить что ты не робот

Политизм и массивы подтипов

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

4b9b3361

Ответ 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.