С помощью GeckoDriver v0.20.0 и Firefox Quantum v59.0.2 (64-бит) ваш кодовый блок выглядит хорошо, а трассировка стека журнала выглядит одинаково хорошо, g10] log message :
Promise rejected while context is inactive: Message manager disconnected
В соответствии с обсуждением в форуме поддержки Mozilla эта ошибка выглядит как Privacy Badger. Короче говоря, эта проблема вызвана расширением, которое не загружается / работает должным образом.
@Test
. Не разрешенные обещания, отклоненные до окна. [hr>
Хорошо, как я упоминал в своем ответе трассировку стека был fair достаточно в соответствии с текущими реализациями. Но лично я не видел этого следа на моем localhost :
Promise rejected while context is inactive: Message manager disconnected
Грубые некоторые трассы могут зависеть от базовой ОС . Теперь просматривается все обсуждение . Неразрешенные обещания, отклоненные до события window.unload? , выглядит в нижней строке:
Проблема обещаний с разгрузки страниц (или действительно, вызов скрипта на незагруженных страницах вообще), не уточняется очень хорошо и не реализуется взаимоисключаемо, очень реально. См. Также https://bugzilla.mozilla.org/show_bug.cgi?id=1058695 , где мы закончили некоторые смягчения в Gecko, которые технически не следуют спецификации, потому что технически следуя спецификации требует утечки мира в обычных случаях .... Проблема в том, что сейчас нет спецификации для этого события цикла событий, а спецификация для Promise является частью ES6, которая на самом деле не допускает возможности Realms нужно уйти в каком-то смысле, поэтому нечего даже поднимать такие проблемы против.
blockquote>Следовательно, вывод: вы хорошо гонитесь вперед
OverRiding Concept в Java Функции будут переопределяться, зависит от типа объекта, а переменные будут доступны по ссылочному типу.
Например:
Parent parent=new Child();
parent.behaviour();
Здесь parent
является ссылкой Родительский класс, но содержит объект Child Class, поэтому в этом случае будет вызываться функция класса Child.
Child child=new Child();
child.behaviour();
Здесь child
хранится объект Child Class, поэтому функция класса Child будет .
Parent parent=new Parent();
parent.behaviour();
Здесь parent
хранится объект родительского класса, поэтому будет вызываться функция класса родителя.
Когда вы пытаетесь получить доступ к переменной, это зависит от объекта ссылочного типа, а не от типа объекта.
Например:
Parent parent=new Child();
System.out.println(parent.state);
Тип ссылки является родительским, поэтому доступна переменная класса родителя, а не переменная класса Child.
Child child=new Child();
System.out.println(child.state);
Здесь ссылочный тип - это Child , поэтому к переменной класса Child обращается не переменная класса родителя.
Parent parent=new Parent();
System.out.println(parent.state);
Здесь ссылочный тип является родительским, поэтому доступна переменная класса родителя.
Полиморфизм полей в Java отсутствует.
Variables
решение происходит во время компиляции, поэтому всегда будут доступны переменные базового класса (а не дочерние наследуемые переменные).
Поэтому всякий раз, когда происходит оживление, всегда помните
1) Доступ к переменным базового класса.
2) Будут вызываться методы подкласса (переопределенные методы, если переопределение произошло иначе, унаследованные методы, как и от родителя).
В соответствии с спецификациями Java переменные экземпляра не переопределяются из суперкласса подклассным классом при его расширении.
Следовательно, переменную в подклассе можно рассматривать только как разделяющую то же имя.
Также, когда конструктор A вызывается во время создания экземпляра B, переменная (intVal) инициализируется и, следовательно, выводится.
Ну, надеюсь, у тебя есть ответ. Если нет, вы можете попробовать посмотреть в режиме отладки. подкласс B имеет доступ как к intVal. Они не являются полиморфными, поэтому они не переоцениваются.
Если вы используете ссылку B, вы получите intVal B. Если вы используете ссылку A, вы получите intVal. Это так просто.
Java имеет перо инкапсуляции, что означает, что он тесно связывает свойство и поведение объекта. поэтому только с помощью ссылки на класс мы можем назвать его поведение, чтобы изменить его свойство.
, а в режиме наследования только метод переопределяет, так что он может влиять только на его свойство.
Когда вы делаете переменную с тем же именем в подклассе, это называется скрытием. В результате подкласс теперь будет иметь оба свойства. Вы можете получить доступ к одному из суперкласса с помощью super.var
или ((SuperClass)this).var
. Переменные не обязательно должны быть одного типа; это всего лишь две переменные, разделяющие имя, подобно двум перегруженным методам.
Переменные не являются полиморфными в Java; они не переопределяют друг друга.
Переменные разрешены во время компиляции, времени выполнения методов. ARef имеет тип A, поэтому aRef.Intvalue является временем компиляции, равным 1.
Из JLS Java SE 7 Edition §15.11.1:
Отсутствие динамического поиска для доступа к полям позволяет программам эффективно запускаться с помощью простых реализаций. Возможность позднего связывания и переопределения доступна, но только при использовании методов экземпляра.
blockquote>Ответы Оливера Чарльворта и Марко Топольника верны, я хотел бы подробнее рассказать о почему часть вопроса:
В Java члены класса являются доступными в соответствии с типом ссылки, а не типом фактического объекта. По той же причине, если у вас есть
someOtherMethodInB()
в классеB
, вы не сможете получить к нему доступ изaRef
после запускаaRef = b
. Идентификаторы (т. Е. Имена классов, переменных и т. Д.) Разрешаются во время компиляции, и поэтому компилятор полагается на ссылочный тип для этого.Теперь в вашем примере при запуске
System.out.println(aRef.intVal);
он печатает значениеintVal
, определенный вA
, потому что это тип ссылки, которую вы используете для доступа к ней. Компилятор видит, чтоaRef
имеет типA
, и этоintVal
, к которому он будет обращаться. Не забывайте, что у вас есть оба поля в экземплярахB
. JLS также имеет пример, похожий на ваш, «15.11.1-1. Статическая привязка для доступа к полям», если вы хотите взглянуть.Но почему методы ведут себя по-другому? Ответ заключается в том, что для методов Java использует позднюю привязку. Это означает, что во время компиляции он находит наиболее подходящий метод для поиска во время выполнения. Поиск включает случай переопределения метода в некотором классе.
Надеюсь, это поможет
public class B extends A {
// public int intVal = 2;
public B() {
super();
super.intVal = 2;
}
public void identifyClass() {
System.out.println("I am class B");
}
}