Тип преобразования полиморфных объектов Java <Br /> Преобразование типа объекта, упомянутое здесь, относится к объекту с отношениями наследования, а не объектом любого типа. При отработке объекта, который не имеет отношения наследования, время выполнения Java бросает исключение Java.lang.classcastException.
В цепочке наследования мы называем конверсию подкласса в родительский класс «преобразование восходящего воспитания» и преобразование родительского класса в детском классе «преобразование вниз».
Много раз мы определяем переменные как тип родительского класса, но ссылаемся на объект ребенка. Когда программа работает, она использует динамическую привязку, чтобы реализовать призыв к методам подкласса, то есть полиморфизм.
Однако иногда для выполнения функций, которых нет у некоторых родительских классов, нам нужно преобразовать подкласные объекты, преобразованные вверх, в подклассы и вызвать методы подкласса, что является трансформацией вниз.
ПРИМЕЧАНИЕ. Объект родительского класса не может быть непосредственно подключить к типу подкласса, а объект подкласса после восходящего преобразования может быть снова преобразован в тип подкласса. Другими словами, объекты подкласса должны быть преобразованы вверх, прежде чем они смогут преобразовать вниз. Пожалуйста, смотрите следующий код:
Общедоступный класс {public static void main (string args []) {superclass superobj = new superclass (); родительский объект.Удалите комментарий по строке 7, и исключение будет брошено во время выполнения, но компиляция может быть передана.
Поскольку существуют риски при переходе вниз, при получении ссылки на родительский класс, обязательно используйте экземпляр оператора, чтобы определить, является ли объект подклассом, который вы хотите.
Общедоступный класс {public static void main (string args []) {superclass superbj = new superclass (); = (Sonclass) SuperBj; ) SuperBj; Результаты работы:
① не может преобразовать
Резюме: Тип преобразования объекта проверяется при запуске программы.
Полиморфизм Java и динамическое связывание <br /> В Java переменные родительского класса могут ссылаться на экземпляры родительского класса или экземпляры детского класса.
Пожалуйста, сначала прочитайте кусок кода:
Общедоступный класс { .cry (); Call of Cat public void cry () {System.out.println ("meow ~"); }} Результаты работы:
Я не знаю, как называть Meow ~ шерсть ~
Приведенный выше код определяет три класса, а именно на животных, кошка и собака. Переменная OBJ имеет типовое животное, которое может указывать на экземпляры класса животных, а также экземпляры классов кошек и собак, что является правильным. То есть переменные родительского класса могут ссылаться на экземпляры родительского класса или экземпляры детского класса. Обратите внимание, что наоборот - неправильно, потому что все кошки - животные, но не все животные - кошки.
Видно, что OBJ может быть либо человеком, кошкой или собакой. Полиморфизм относится к тому, что имеет разные формы или формы.
Например, «люди» также имеют много разных выражений или реализаций. , учитель или доктор в следующей жизни.
Существует три необходимые условия для существования полиморфизма: наследование, переписать и родительские переменные относятся к объектам подкласса.
При вызове метода с помощью полиморфного метода:
Сначала проверьте, присутствует ли метод в родительском классе.
Если подкласс переопределяет метод, метод подкласса вызывается, в противном случае вызывается метод родительского класса.
Из приведенного выше примера мы видим, что одно преимущество полиморфизма заключается в том, что когда есть много подклассов, нет необходимости определять несколько переменных. Пожалуйста, посмотрите на следующий пример:
Общедоступный класс демо {public static void main (string [] args) {// С помощью полиморфизма владелец может кормить многих животных Master ma = new Master (); ); ) {System.out.println («Я - маленькое животное, еда» + f.getFood ()); Маленькая кошка ест " + f.getFood ());}} Class Dog расширяет Animal {public void eat (еда f) {System.out.println (" Я собака, еда " + f. GetFood ()) ; String getFood () {return "bone"; Результаты работы:
Я маленькое животное, ем вещи, я маленькая кошка, ем рыбу, я собака, ем кости
Метод корма мастера имеет два параметра, а именно тип животного и тип пищи. разные животные.
Динамическое связывание
Чтобы понять природу полиморфизма, давайте поговорим о подробном процессе методов вызова Java ниже.
1) Компилятор проверяет тип объявления и имя метода объекта.
Предположим, что obj.func (param) называется, OBJ является объектом класса CAT. Следует отметить, что может быть несколько методов с именами с функцией, но разными параметрами. Например, могут существовать методы Func (int) и Func (строка). Компилятор перечисляет все методы, названные Func в классе CAT и методах доступа к атрибутам, и назван Func в своем родительском классе.
Таким образом, компилятор получает список всех возможных методов кандидатов, которые будут вызваны.
2) Далее редактор проверит подпись параметра, предоставленную при вызове метода.
Если во всех методах есть метод, который называется Func, который точно соответствует предоставленной подписи параметров, выберите этот метод. Этот процесс называется разрешением перегрузки. Например, если Func ("Hello") называется, компилятор выберет func (string) вместо func (int). Например, из -за существования автоматического преобразования типа может быть преобразована в двойной. Конец или несколько методов соответствуют его, а затем составьте ошибку.
Таким образом, компилятор получает имя метода и подпись параметров, которые необходимо вызвать.
3) Если модификатор метода является частным, статичным, окончательным (статический и конечный будет объяснен позже) или конструктором, то компилятор сможет точно узнать, какой метод следует вызвать. Полем
Соответственно, вызываемый метод зависит от фактического типа объекта и реализует динамическое связывание во время выполнения. Например, при вызове Func («Привет») редактор будет использовать динамическую привязку для генерации директивы, которая вызывает func (строка).
4) Когда программа запускается и использует динамическую привязку для вызова метода, JVM определенно будет вызывать метод класса, который наиболее подходит для фактического типа объекта, на который ссылается OBJ. Мы предположили, что фактический тип OBJ - это кошка, которая является подклассом животного, и его называют, если func (строка) определяется в CAT, в противном случае он будет искать в классе животных и его родительском классе.
Каждый призыв к методу требует поиска, что довольно дорого. Таким образом, когда метод на самом деле называется, виртуальная машина может искать только эту таблицу. В приведенном выше примере JVM ищет таблицу методов класса CAT, чтобы найти метод, который соответствует вызову с func («Привет»). Этот метод может быть либо Cat.func (String), либо Animal.func (String). Обратите внимание, что если Super.func ("Hello") называется, компилятор будет искать таблицу методов родительского класса.
Предполагая, что класс животных содержит три метода: cry (), getName () и getage (), тогда его таблица методов выглядит следующим образом:
Cry () -> Animal.cry ()
getName () -> Animal.getName ()
getage () -> Animal.getage ()
Фактически, у животного также есть объект родительского класса по умолчанию (который будет объяснен позже), который будет унаследовать метод объекта, поэтому перечисленные выше методы не завершены.
Предполагая, что класс CAT переопределяет метод Cry () в классе животных и добавляет новый метод Climbtree (), его список параметров:
cry () -> cat.cry ()
getName () -> Animal.getName ()
getage () -> Animal.getage ()
climbtree () -> cat.climbtree ()
При запуске процесс вызова метода obj.cry () выглядит следующим образом:
JVM сначала обращается к таблице методов фактического типа OBJ, который может быть таблицей методов класса животных или таблицей методов класса CAT и его подклассов.
JVM ищет метод, соответствующий Cry () в таблице методов, и после его поиска вы узнаете, к какому классу он принадлежит.
JVM вызывает этот метод.