Scala: Могу ли я воспроизвести создание анонимного класса фабричным методом? - PullRequest
4 голосов
/ 02 октября 2011

Насколько я понимаю, Scala создает анонимный класс, если я создаю класс с помощью ключевого слова new и следую за именем класса с помощью конструктора:

class MyClass {
  def doStuff() { 
    // ... 
  }
}

val mc = new MyClass {
  doStuff()
}

Приятно то, что весь код в конструкторе находится в области видимости нового объекта.

Есть ли способ воспроизвести этот синтаксис, когда класс создается методом фабрики, а не ключевым словом new? то есть заставить работать следующий код:

val mf = new MyFactory

val mc = mf.MyClass { 
  doStuff() 
}

Я не могу найти способ сделать это, но в Scala так много всего, что это может быть довольно легко!

Используя import, как предложено @Ricky ниже, я могу получить:

val mf = MyFactory;
val mc = mf.MyClass

{
  import mc._
  doStuff()
}

(где необходима пустая строка перед блоком), но этот блок кода не является конструктором.

Ответы [ 3 ]

2 голосов
/ 02 октября 2011

Вы можете сделать это, но вам все равно нужно сохранить ключевое слово new и создать вложенный класс как тип, зависящий от пути:

class Bippy(x: Int) {
  class Bop {
    def getIt = x
  }
}

val bip = new Bippy(7)
val bop = new bip.Bop

bop.getIt // yields 7

val bop2 = new bip.Bop{ override def getIt = 42 }

bop2.getIt // yields 42
1 голос
/ 02 октября 2011

Я не думаю, что это возможно.Тем не менее, общий шаблон заключается в добавлении параметра к фабричным методам, который принимает функцию, изменяющую созданный объект:

trait MyClass {
  var name = ""
  def doStuff():Unit
}

class Foo extends MyClass {
  def doStuff() { println("FOO: " + name) }
}

trait MyClassFactory {
  def make: MyClass
  def apply( body: MyClass => Unit ) = {
    val mc = make
    body(mc)
    mc
  }
}

object FooFactory extends MyClassFactory {
  def make = new Foo
}

Затем можно создать и изменить экземпляр с синтаксисом, близким к вашему примеру:

val foo = FooFactory { f=>
  f.name = "Joe"
  f.doStuff
}
0 голосов
/ 02 октября 2011

Звучит так, будто вы просто хотите смешать черту. Вместо вызова myFactoryMethod (classOf [Foo]], что в идеале будет делать (если Scala это разрешит):

new T {
  override def toString = "My implementation here."
}

вместо этого вы можете написать

trait MyImplementation {
  override def toString = "My implementation here."
}

new Foo with MyImplementation

Однако, если вы просто хотите получить доступ к членам нового объекта без квалификации, помните, что вы можете импортировать из любого стабильного идентификатора:

val foo = new Bar
import foo._
println(baz) //where baz is a member of foo.
...