Scala y similares (atributos getter y setter, constructor primario y constructor auxiliar)

Las características de la clase en scala :
1. Los campos de la clase implementan automáticamente los métodos getter y setter
2. Puede implementar métodos getter y setter personalizados
3. Use la anotación @BeanProperty para generar los métodos getXXX y setXXX
4. Cada clase tiene un constructor principal, Declarado con la definición de clase, el parámetro puede convertirse directamente en el campo de clase, y el constructor principal ejecuta todas las declaraciones en el cuerpo de la clase.
5. Puede tener cualquier número de constructores auxiliares, llamado esto.

1. Clase simple y método sin parámetros

class Person {  //Person类
  private var age = 0 //定义私有属性
  def increment(){age += 1}  //定义increment方法,方法默认是公有的
  def current = age //定义current方法
  def act(person:Person): Unit ={  //定义act方法
  
}

En scala, la clase no se declara como pública, y el archivo fuente puede contener múltiples clases, todas las cuales tienen visibilidad pública. Para
usar una clase, simplemente construya un objeto y luego llame a un método

  val person = new Person() //创建Person实例
    person.increment()  //调用person对象的increment方法
    person.increment
    println(person.current)

Al llamar a un método sin parámetros como el incremento, puede agregar () o no.
¿Cuándo debo usar qué método? Use () para el método de cambio de valor (es decir, el método que cambia el estado del objeto), y para el método de cambio de valor (el método que no cambia el estado del objeto) puede descartarse ()

  person.increment()  //对改值器使用()
  println(person.increment)  //对取值器不使用()

Este estilo se puede aplicar declarando el método de incremento sin (). Como arriba

class Person{
...
def current = age //定义中就不带()
}

De esta manera, los usuarios de la clase deben usar person.current sin ()

2. Automáticamente con los atributos getter y setter
En java, nos gusta:

public class Person {
	private int age;
    public int getAge() {return age;}
    public void setAge(int age) {this.age = age;}
}

Un par de getter / setter como este generalmente se llama una propiedad, y decimos que la clase Person tiene una propiedad age. Pero lo bueno de esto es que, como se declara como un campo público, ahora cualquiera puede llamar a set u obtener métodos para cambiarlo, pero la razón por la cual se usan los métodos getter y setter es porque te permiten obtener de simple, Establecer mecanismos para mejorar cuando sea necesario.
Y scala proporciona métodos getter y setter para cada campo, y ahora hay:

class Person {
	var age  = 0
}

Scala genera clases orientadas a JVM, que tienen un campo de edad privado y los correspondientes métodos getter y setter. Estos dos métodos son públicos porque no declaramos la edad como privada (para los campos privados, los métodos getter y setter también son privados )
En scala, getters y setters se llaman age y age_, respectivamente. Como

println(fred.age)  //将调用方法fred.age()
fred.age = 20  //将调用fred.age = (21)

Si desea ver estos dos métodos con sus propios ojos, puede compilar la clase Person y luego ver el archivo bytecode
scalac Person.scala
javap -private Person
puede ver que el compilador creará age y age_ mi q Uno Ley = Ser Dar vuelta Traducir En método eq, (= traducido a eq, no están permitidos porque aparece el nombre del método JVM =). En scala, los métodos getter y setter no se nombran en forma de getXxx y setXxx, pero el significado es el mismo.
En cualquier momento, podemos redefinir los métodos getter y setter, como:

class Person{
	private var privateAge = 0 //私有声明age
	def age = privateAge
	def age_ = (newValue:Int){
		if(newValue > privateAge) privateAge = newValue  //岁月无情,岁数只能增加
	}
}

Ahora los usuarios de la clase Persona aún pueden acceder a fred.age, pero no pueden hacer que fred sea más joven

val fred = new Person
fred.age = 30
fred.age = 20
println(fred.age)

Scala suena horrible para generar métodos getter y setter para cada campo, pero podemos controlar este proceso
1. Si el campo es privado, entonces los métodos getter y setter también son privados
2. Si el campo es val, solo el método getter genera
3. Si no necesita ningún método getter y setter, puede declarar el campo como privado [esto] (ver más abajo)

3. Solo propiedad getter
A veces solo necesitamos una propiedad de solo lectura, hay una propiedad getter pero no setter, si el valor de la propiedad no cambia después de que se construye el objeto, entonces use val para declarar el campo

class Message {
  val timpStamp = new java.util.Date
...
}

Scala generará un campo final privado y un método getter, pero no setter.
Sin embargo, a veces necesitamos dicho atributo: el cliente no puede cambiar el valor de manera casual, pero se puede cambiar de otras maneras, entonces la clase Persona al comienzo del artículo es un ejemplo. La clase Persona tiene un atributo actual, que se actualiza cuando se llama al método de incremento, pero No hay setter correspondiente.
Pero no podemos lograr tal atributo a través de val-val nunca cambia. Debe proporcionar un campo privado y un método de obtención de propiedades, como:

class Counter {
  private var value = 0
  def increment() = {value += 1}
  def current = value //声明中没有()
}
val  n = myCounter.current

Tenga en cuenta que no hay () en la definición del método getter, por lo que no es necesario llamar con ().
Para resumir, tiene las siguientes cuatro opciones al implementar atributos:
1.var foo: scala sintetiza automáticamente un getter y un setter.
2.val foo: scala sintetiza automáticamente un getter.
3. Depende
de usted definir los métodos foo y foo_ = 3. Depende de usted definir los métodos foo
En scala, no puede implementar propiedades de solo escritura, es decir, propiedades con setters y sin getters.
Cuando vea un campo en la clase scala, recuerde que no es lo mismo que el campo en Java y C ++. Es un campo privado, más el método getter (para el campo val) o el método getter y el método setter (para var En términos de)

4. Campos privados de objetos
En scala, los métodos pueden acceder a los campos privados de todos los objetos de esta clase, tales como:

class Counter {
  private var value = 0
  def increment() {value += 1}
  def isLess(other:Counter) = value < other.value  //可以访问另一个对象的私有字段
}

Es accesible porque otro también es un objeto Counter.
Scala nos permite definir restricciones de acceso más restrictivas, implementadas a través del modificador privado [this]

private[this] var value = 0 //这样类似某个对象.value这样的访问将不被允许

Ahora, los métodos de la clase Counter solo pueden acceder al campo de valor del objeto actual, pero no pueden acceder al campo de otros objetos del mismo tipo de Counter. Dicho acceso a veces se denomina objeto privado. Para los campos que son privados para la clase, scala genera métodos getter y setter privados, pero para los campos que son privados para el objeto, scala no genera ningún método getter y setter.
Scala también permite que se asignen derechos de acceso a una clase específica, privado [nombre de clase] puede definir que solo los métodos de la clase especificada pueden acceder al campo dado, donde el nombre de la clase debe ser la clase definida actualmente, o un externo que contenga la clase Clases, en este caso, el compilador generará métodos getter y setter auxiliares para permitir que las clases externas accedan al campo, estas clases serán públicas.

5. El
scala de atributos Bean proporciona métodos getter y setter para los campos definidos, pero esto no es lo que Java espera. La especificación JavaBean define los atributos java como un par de métodos getFoo y setFoo. Muchas herramientas Java confían en este método de denominación.
Cuando marca el campo de escala como @BeanProperty, este método se sintetizará automáticamente, como por ejemplo:

import scala.beans.BeanProperty
class Person {
  @BeanProperty var name:String = _
}

Luego se generarán cuatro métodos:
1.name:String
2.name _ = (newValue: String): Unit
3.getName (): String
4.setName (newValue: String): Unit
Si un determinado se define en el constructor principal Field, y requiere los métodos getter y setter de la versión JavaBean, para que pueda:

class Person(@BeanProperty var name: String)

Inserte la descripción de la imagen aquí

6. El constructor auxiliar
scala puede tener cualquier número de constructores auxiliares. Pero el constructor principal de la clase scala es el más importante.
1. El nombre del constructor auxiliar es este: en Java, el nombre del constructor es el mismo que el nombre de la clase.
2. Cada constructor auxiliar debe comenzar
con una llamada a otro constructor auxiliar o constructor principal que se haya definido previamente. Esta es una clase con dos constructores auxiliares:

class Person {
  private var name = ""
  private var age = 0
  
  def this(name: String) {
    this()  //调用主构造器
    this.name = name
  } 
  
  def this(name: String,age: Int) {
    this(name) //调用前一个辅助构造器
    this.age = age
  }
}

Ahora podemos crear objetos de tres maneras:

val p1 = new Person //主构造器
val p2 = new Person("Fred") //第一个辅助构造器
val p3 = new Person("Fred",20) //第二个辅助构造器

7.
Cada clase en el constructor principal scala tiene un constructor principal. El constructor principal no se nombra después de esto, sino que se entrelaza con la definición de clase. Por
ejemplo:

class Person(val name: String,val age:: Int) {
...
  }

parámetros del constructor primaria se compilan campo de la ciudad, el valor pasado se inicializa parámetros configurados ciudad, el nombre y la edad del ejemplo se convierten en campos de la clase persona, como persona nueva ( "Fred", 33 ) está configurado de modo que el objeto
piense java Definición de clase y constructor, scala se implementó en solo media línea

public class Person {
  private String name;
  private int age;
  public Person(String name,int age) {
    this.name = name;
    this.age = age;
  }
  public String name(){ return this.name;}
  public int age() {return this.age;}
  ...
}

El constructor principal ejecutará todas las declaraciones en la definición de clase, como:

class Person(val name: String,val age: Int) {
  println("primary constructor")
  def description = name + "is" + age + "years old"
}

Las declaraciones println son parte del constructor principal, y estas declaraciones se ejecutan cada vez que se construye un objeto.
Esta característica es útil cuando necesitamos configurar un campo durante la construcción. Tales como:

class MyPro {
  private val props = new Properties
  props.load(new FileReader("myprog.properties"))
}

Nota: Si no hay ningún parámetro después del nombre de la clase, la clase tiene un constructor primario sin parámetros, que simplemente ejecuta todas las declaraciones de la clase.

Podemos usar los parámetros predeterminados en el constructor principal para evitar el uso excesivo de constructores auxiliares. Tales como:

class Person(val name: String = "",val age: Int = 0)

Los parámetros del constructor principal pueden estar en cualquier forma en la tabla anterior. Tales como:

class Person(val name: String,private var age: Int)

Los parámetros de construcción también pueden ser parámetros de métodos ordinarios, sin val o var, la forma de establecerlos depende de cómo se usen en la clase.
Si el parámetro sin val o var es utilizado por al menos un método, se promocionará a un campo, como:

class Person(name: String,age: Int) {
  def description = name + " is " + age + "years old"
}

El código anterior declara e inicializa el nombre y la edad de los campos inmutables, y estos dos campos son privados para el objeto, equivalente al efecto del valor privado [this] val. De lo contrario, el parámetro no se guarda como un campo, solo un parámetro ordinario al que puede acceder el código en el constructor principal.
Inserte la descripción de la imagen aquí
El constructor principal se puede entender de la siguiente manera: en scala, las clases también aceptan parámetros, al igual que los métodos.
Si desea que el constructor principal sea privado:

class Person private(val name: String){...}

Dichos usuarios solo pueden construir el objeto persona a través del constructor auxiliar.

8. En la escala de clase anidada
, podemos anidar cualquier estructura gramatical en cualquier estructura gramatical, por ejemplo, podemos definir una función en una función y una clase en una clase, como:

class Network {
  class Member(val name: String){
    val contacts = new ArrayBuffer[Member]
  }
  private val members = new ArrayBuffer[Member]
  
  def join(name: String) = {
    val m = new Member(name)
    members += m
    m
  }
}

Considere las siguientes dos redes:
val chatter = nueva red
val myFace = nueva red
En scala, cada instancia tiene su propia clase de miembro, al igual que tienen su propio campo de miembros, es decir, chatter.Member y myFace .Miembro son dos clases diferentes.
Esto es diferente de Java, en el que la clase interna está subordinada a la clase externa.
Tomando la clase de red como ejemplo, podemos agregar miembros dentro de sus respectivas redes, pero no podemos agregar miembros a través de objetos de red

val fred = chatter.join("Fred")
val wlima = chatter.join("Wlima")
fred.contacts +=wlima //OK
val barey = myFace.join("Barey")  //类型为myFace.Member
fred.contacts += barey //不可以这样做,不能将一个myFace.Member添加到chatter.Member元素缓冲中

Si desea lograr este efecto, hay dos soluciones:
puede mover la clase Miembro a otra parte, una buena ubicación es el objeto complementario de la Red

object Network {
    class Member(val name: String) {
       val contacts = new ArrayBuffer[Member]
	}
}

class Network {
	private val members = new ArrayBuffer[Network.Member]
}

O puede usar la proyección de tipo Network # Member, es decir, cualquier miembro de la red, como:

class Network {
	class Member (val name: String) {
		val contacts = new ArrayBuffer[Network#Member]
	}
	...
}

En la clase incrustada, podemos acceder a esta referencia de la clase externa a través de la clase externa.

class Network(val name: String){ outer =>
	class Member(val name: String) {
		...
}
}
14 artículos originales publicados · Me gusta1 · Visitas 684

Supongo que te gusta

Origin blog.csdn.net/qq_33891419/article/details/103603922
Recomendado
Clasificación