Для этого есть декоратор @abstractproperty :
from abc import ABCMeta, abstractmethod, abstractproperty
class A:
__metaclass__ = ABCMeta
def __init__(self):
# ...
pass
@abstractproperty
def a(self):
pass
@abstractmethod
def b(self):
pass
class B(A):
a = 1
def b(self):
pass
Невозможно объявить a
или b
в производный класс B
поднимет значение TypeError
, например:
TypeError
: не может создать абстрактный классB
с абстрактными методамиa
Python 3.3 +
Устаревший с версии 3.3: теперь можно использовать
property
,property.getter()
,property.setter()
иproperty.deleter()
сabstractmethod()
, что делает этот декоратор избыточным.Вышеприведенный пример является следующим:
from abc import ABCMeta, abstractmethod class A(metaclass=ABCMeta): def __init__(self): # ... pass @property @abstractmethod def a(self): pass @abstractmethod def b(self): pass class B(A): a = 1 def b(self): pass
Когда я смотрю на Stacktrace, я обнаруживаю, что он не жалуется на создание контроллера.
Он жалуется, что не может загрузить файл FXML. Это как-то не может найти это. Таким образом, он прерывается - еще до того, как он достигнет строки, в которую вы хотите загрузить контроллер (эта строка выглядит нормально):
Исключение в потоке «Поток приложения JavaFX» java.lang.IllegalStateException: Местоположение не задавать. в javafx.fxml.FXMLLoader.loadImpl (FXMLLoader.java:2428) в javafx.fxml.FXMLLoader.load (FXMLLoader.java:2403)
blockquote>Возможно, вы захотите посмотреть на значение "FxmlViews.MainScreen.mainSc". Это очень вероятно указывает на какой-то неправильный путь.
Пример загрузки контроллера дважды:
String filename = "yourfxm.fxml"; FXMLLoader loader = new FXMLLoader(FXMLLoader.class.getResource(filename)); var node = loader.load(); var controller = loader.getController(); loader = new FXMLLoader(FXMLLoader.class.getResource(filename)); node = loader.load(); controller = loader.getController();
JavaFX API позволяет получать ссылки на контроллеры только через метод FXMLLoader.load (). С экземпляром FXMLLoader вы можете сделать что-то вроде этого (как вы уже делаете :-)):
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("MainForm.fxml"));
Parent root = (Parent) loader.load();
// as soon as the load() method has been invoked, the scene graph and the
// controller instance are availlable:
MainFormController controller = loader.getController();
Это означает:
Лучше хранить ссылки на контроллеры на время строительства / время загрузки, если они понадобятся вам позже.
Еще лучше: подумайте дважды, если вам нужен доступ к родительскому контроллеру из дочернего контроллера. Это может быть предупреждением о том, что с архитектурой приложения что-то не так.
Если вам действительно нужна связь между дочерним контроллером и родительским контроллером, лучше сделайте это «управляемым событиями», то есть создайте наблюдаемые свойства в дочернем контроллере и попросите родительский контроллер прослушивать изменения.
Надеюсь, это поможет ...