Что Вы будете видеть, иногда следующее:
class Abstract1( object ):
"""Some description that tells you it's abstract,
often listing the methods you're expected to supply."""
def aMethod( self ):
raise NotImplementedError( "Should have implemented this" )
, поскольку Python не имеет (и не нуждается) формальный Интерфейсный контракт, различие стиля Java между абстракцией и интерфейсом не существуют. Если кто-то пройдет усилие определить формальный интерфейс, это также будет абстрактный класс. Единственные различия были бы в установленном намерении в docstring.
И различие между кратким обзором и интерфейсом незначительная вещь, когда у Вас есть утиный ввод.
Java использует интерфейсы, потому что он не имеет множественного наследования.
, поскольку Python имеет множественное наследование, можно также видеть что-то вроде этого
class SomeAbstraction( object ):
pass # lots of stuff - but missing something
class Mixin1( object ):
def something( self ):
pass # one implementation
class Mixin2( object ):
def something( self ):
pass # another
class Concrete1( SomeAbstraction, Mixin1 ):
pass
class Concrete2( SomeAbstraction, Mixin2 ):
pass
, Это использует своего рода абстрактный суперкласс с mixins для создания конкретных подклассов, которые являются непересекающимися.
Например,
class R(n: Int, d: Int) {
val (x, y) = {
val g = myfunc
(n/g, d/g)
}
}
Есть несколько способов сделать это. Вы можете объявить такие временные переменные внутри частных определений, которые будут использоваться во время строительства. Вы можете использовать временные переменные внутри блоков, которые возвращают выражения (например, в ответе Алаза). Или, наконец, вы можете использовать такие переменные внутри альтернативных конструкторов.
Аналогично альтернативным конструкторам, вы также можете определить их внутри метода «apply» объекта-компаньона.
Что вы можете ' t do объявляет поле «временным».
Обратите внимание, что любой параметр, полученный первичным конструктором, также является полем. Если вы не хотите, чтобы такие параметры становились полями и не хотите отображать фактические поля в конструкторе, обычное решение - сделать основной конструктор закрытым,
Некоторое обсуждение этой темы, включая комментарии Мартина Одерски, находится здесь
Другой вариант, который у нас есть, это сделать основной конструктор объектов Constructor и использовать метод применения объекта компаньона в качестве строителя. Если мы применим (PAL не предназначен) Этот подход к вашему примеру это будет выглядеть так:
class R private (val x: Int, val y: Int);
object R {
def apply(n: Int, d: Int): R = {
val g = myfunc;
new R(n / g, d / g);
}
}
для создания экземпляра R вместо:
val r = new R(1, 2);
Написать:
val r = R(1, 2);
Это немного многословна, но это может быть Хуже, я думаю :). Будем надеяться, что частные [этот] Vals будут рассматриваться как временные переменные в будущих выбросах SCALA. Мартин сам намекнул это.