Меня заинтерисовал Scala. Прочитал Scala by Examples и Scala Tutorial. Но у всех текстов по Scala, что мне встретились есть один общий недостаток: нет общего последовательного изложения всего языка. Все тексты построены в стиле у нас это, то, а еще есть такая фишка. Есть конечно ScalaReference, но там мало примеров кода и много формул и теорем. В результате я застрял на паре вопросов, когда начал писать небольшой проект на Scala.
1. Как вызвать конструктор суперкласса?
Как такой код переложить в Scala:
public class MainFrame extends JFrame{
public MainFrame(String s) {
super(s);
//code
pack();
setResizable(false);
setVisible(true);
}
}
2. В Java можно написать:
static{
//code
}
А как это написать в Scala?
3. В Java можно константу назначать в конструкторе. А как это сделать в Scala?
Пример:
public class Box{
public final int W, H;
Box(int w, int h){
W = w;
H = h;
// еще какой-то код
}
}
Компилятор Scala пишет: "присвоение к не var-переменной".
Больше ничего в голову не приходит.
А>2. В Java можно написать: А>
А>static{
А> //code
А>}
А>
А>А как это написать в Scala?
Кажется, в Scala нет static initializers.
А>3. В Java можно константу назначать в конструкторе. А как это сделать в Scala? А>Пример: А>
А>public class Box{
А>public final int W, H;
А>Box(int w, int h){
А> W = w;
А> H = h;
А> // еще какой-то код
А>}
А>}
А>
class Box(final val w: int, final val h: int) {
def weight() = w
def height() = h
}
Оно?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: [Scala]static{...} и конструктор суперкласса
От:
Аноним
Дата:
18.04.07 11:32
Оценка:
Здравствуйте, lomeo.
Я и сам подумал, поискал.
Оказывается если код написать просто в теле класса, то он исполняется при создании объекта.
class MainFrame(s: String, l: Lando) extends JFrame(s){
val compLando=new CompLando(l);
val status: JPanel = new JPanel();
private val cp=getContentPane().asInstanceOf[JPanel];
cp.add(status, BorderLayout.WEST);
cp.add(compLando,BorderLayout.CENTER);
status.setBackground(Color.GRAY);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setResizable(false);
setVisible(true);
//далее определения методов и прочее
}
Здесь же и определяются константы. Только вот приходиться писать private перед вспомогательными переменными.
Если же код написать просто в теле объекта, то он исполняется при первом обращении к объекту.
object Dekoracio{
private val m = new scala.collection.mutable.HashMap[String, Array[Array[Tajlo]]]
private val x = scala.xml.XML.loadFile("data\\dekoracio\\dekoracio.xml");
for(val dekor <- x\\"dekoracio"){
// ...
}
Один конструктор суперкласса можно вызвать написав:
class MainFrame(s: String, l: Lando) extends JFrame(s){
1. А как вызвать другой?
2. Как вызывать определенный конструктор суперкласса в зависимости от конструктора?
3. Как назначать константы в зависимости от от конструктора?
Или проще:
class B extends A{
final String TEXT;
B(String s){
super(s)
TEXT="Вызвали String-конструктор"
}
B(int i){
super(i)
TEXT="Вызвали int-конструктор"
}
}
как повторить?
Re[3]: [Scala]static{...} и конструктор суперкласса
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте, lomeo.
А>Я и сам подумал, поискал.
А>Оказывается если код написать просто в теле класса, то он исполняется при создании объекта.
А>Если же код написать просто в теле объекта, то он исполняется при первом обращении к объекту.
Жестко. А есть ли уже наработаные практикой Scala coding guidelines? Было бы просто любопытно почитать...
Лично мне кажется, что такие возможности ничего кроме ухудшения читабельности не принесут (по крайней мере первая). Вторую надо обдумать, но на первый взгляд тоже кажется сомнительной
... << RSDN@Home 1.2.0 alpha rev. 648>>
Re[3]: [Scala]static{...} и конструктор суперкласса
А>1. А как вызвать другой? А>2. Как вызывать определенный конструктор суперкласса в зависимости от конструктора? А>3. Как назначать константы в зависимости от от конструктора?
А>Или проще:
Все конструкторы должны в конечном итоге вызывать первичный конструктор (primary constructor) (то есть в случае с =MainFrame= это =MainFrame(String, Lando)=). Это делается с помощью =this(бла-бла-бла)=:
class LinkedList[a]() {
var head = _
var tail = null
def isEmpty = tail != null
def this(head: a) = { this(); this.head = head }
def this(head: a, tail: List[a]) = { this(head); this.tail = tail }
}
If there are auxiliary constructors of a class C, they form together with C’s primary
($5.3) an overloaded constructor definition.
// (scala reference)
Если подумать, то это ограничение не ограничивает общности, зато делает классы более униформными плюс гарантированное отсутствие зацикливания в конструкторах.
У класса =A= поэтому при наследовании от него нужно выбрать какой-то конструктор, который будет первичным для =B=, скажем =A(Int)=, тогда всё становится прозрачным:
class A (s : String, i : Int) {
def this(i : Int) = { this("_", i) }
}
class B(s : String, i : Int) extends A(i) {
final var text = "primary constructor this(\""+s+"\", "+i+")"
def this(s : String) = { this(s, 0); text = "non-primary this(\""+s+"\")" }
def this(i : Int) = { this("_", i); text = "non-primary this("+i+")" }
}
// homework :-)new B("#").text
new B(5).text
new B("*", 9).text
Кстати, в Скале нет =static= мемберов. Это сделано намеренно, поскольку =static= декларации нерасширяемы и не допускают полиморфное поведение. Если что-то нужно сделать общим для всех инстансов класса =X=, то это нужно выносить в =object X=.