Scala 类与单例

1. 类的基本操作

1.1. 类的定义

类或者类型,就是对客观的一类事物的抽象。用一个class关键字来描述,在这个类中可以拥有这一类事物的属性,行为等等。

​ 或者说就是用计算机的语言来描述的一类事物,就是类,在java,scala中都是用关键字class来标识。

​ 因为类是对一类事物的抽象,所以不具备具体的行为执行能力,要想完成具体的操作,就需要使用该类的实例或者对象。

//创建scala中的一个类
object _01ClassOps {
	def main(args: Array[String]): Unit = {
		/*
			scala中类对应对象的构建,和java一模一样 使用关键字new,
			以及构造函数来完成实例的创建
			scala可以使用默认的无参构造器完成实例创建,
			同时一类如果有无参构造器,在创建对象的时候,可以省略掉()
		 */
		val p = new Person()
//		val p1 = new Person

//		p.name =
		p.setName("刘嘉豪")
		p.setAge(169)

		p.show()
	}
}


class Person {
	/*
		_的作用就相当于java中private String name;
		如果要使用_,前面的成员变量就应该指定数据类型
	 */
	private var name:String = _

	private var age = 13
	def show(): Unit = {
		println(s"name=${name}\tage=${age}")
	}

	def setName(name:String):Unit = {
        //成员变量和局部变量命名冲突之后使用this关键字来进行区分
		this.name = name
	}

	def getName() = this.name
	//单行函数
//	def setAge(age:Int) = this.age = age
	def setAge(age:Int): Unit = {
		if(age < 0 || age > 150) {
			throw new RuntimeException("地球不欢迎你~")
		}
		this.age = age
	}

	def getAge = this.age
}

1.1.1. getter/setter操作

在scala中使用@BeanProperty注解来给成员变量提供getter/setter,该注解和private访问权限修饰符不可共存.
这种方式定义类似java bean的操作,在scala中几乎不用,java bean的主要作用是啥:
说白了就是在各个业务线/层之间传递数据,scala提供了另外的一种结果来模拟java中的bean–case class(样例类,样本类)

class Student {
	@BeanProperty var name:String = _

	private var age = 13
}

1.2. 类的构造

类的构造函数,在java中一个类的构造函数(器),可以分为有参构造器或者无参的构造器,或者默认构造器的说法。所谓默认构造器指的就是,用户不指定/创建相关构造器,而虚拟机会自动的为我们的类添加一个无/空参的构造器,用于对象的创建。

​ 在java中一个类,可以拥有若干个构造器,既可以拥有无参构造器,也可以拥有有参构造器,如果用户提供了构造器,此时便不会再有默认的构造器了。

.2.2. scala中的构造器

scala中有两类构造器——主构造器和辅助构造器。

构造器的说明

object _02ConstructorOps {
	def main(args: Array[String]): Unit = {
		val p = new Person("华勇", 23)
		p.show()
	}
}

class Person() {

	private var name:String = _

	private var age:Int = _

	def Person(): Unit = {
		println("--Person()--是默认的构造器吗?")
	}

	//自定义构造器 自定义构造器的第一句话必须要调用其它构造器
	def this(name:String, age:Int) {
		this()
		this.name = name
		this.age = age
		println("---------this(name:String, age:Int)---------")
	}


	println("-------------构造器~----------------")
	def show(): Unit = {
		println(s"name=${name}\tage=${age}")
	}
}

本例中的这个和类的定义交织在一起的默认的构造器,是scala类中最重要的一个构造器——主构造器(默认的构造器是无参主构造器,定义在类名和类的{之间,省略了())。

​ 其余的自定义构造器,也就是在类中通过def this(xxx)定义的构造器称之为辅助构造器,同时辅助构造器的第一句话,必须要通过this来调用本类主构造器或者其它辅助构造器

object _02ConstructorOps {
	def main(args: Array[String]): Unit = {
		val _3p = new Person(77)
		_3p.show()
	}
}

class Person(var name:String, var age:Int) {

	def Person(): Unit = {
		println("--Person()--是默认的构造器吗?")
	}

	def this() {
		this("嘿嘿", 33)
		println("---this() ---")
	}

	def this(name:String) {
		this()
		this.name = name
		println("---this(name:String) ---")
	}

	def this(age:Int) {
		this("龚天明")
		this.age = age
		println("---this(age:Int) ---")
	}
	println("-------------构造器~----------------")

	def show(): Unit = {
		println(s"name=${name}\tage=${age}")
	}
}

1.3. 内部类

主要用到这个内部类的原因,就在于如果将两个事物,每一个事物在java中都是类class,将这两个可能具有包含关系,比如人Person,心脏Heart,平行去定义,就不大符合实际的情况。而Heart是人这一类事物内部的一类其它事物,能够直接访问人这一类事物中的很多属性,如果将Heart定义在外部,要想获取人的血液,就需要在Heart并行的创建人Person对象,再进行其它操作,显然不合理。

  • 对于这类型的操作,我们就是用类的嵌套来完成定义,或者这种结构称之为嵌套类或者内部类。
public class InnerClassOps {
    public static void main(String[] args) {
        //创建内部类Inner的对象
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
        inner.show();
    }
}

class Outer {
    int x = 5;

    class Inner {
        int x = 6;

        public void show() {
            int x = 7;
            System.out.println("x = " + x);
            System.out.println("inner class x = " + this.x);
            System.out.println("Outer class x = " + Outer.this.x);
        }
    }
}

scala版本的内部类

object _03InnerClassOps {
	def main(args: Array[String]): Unit = {
		val outer = new Outer
		val inner = new outer.Inner()
		inner.show()
	}
}

class Outer { ooo =>
	 val x = 5

	class Inner { iii =>
		val x = 6

		def show(): Unit = {
			val x = 7
			System.out.println("x = " + x)
			System.out.println("inner class x = " + iii.x)
			System.out.println("Outer class x = " + ooo.x)
		}
	}
}

1.4. object对象

1.4.1. object对象

主要作用:

​ 1.给scala类提供程序运行的入口,静态的main函数

​ 2.给scala类也来提供静态成员——scala类的伴生对象来实现

scala版本的内部类
```java
object _03InnerClassOps {
	def main(args: Array[String]): Unit = {
		val outer = new Outer
		val inner = new outer.Inner()
		inner.show()
	}
}

class Outer { ooo =>
	 val x = 5

	class Inner { iii =>
		val x = 6

		def show(): Unit = {
			val x = 7
			System.out.println("x = " + x)
			System.out.println("inner class x = " + iii.x)
			System.out.println("Outer class x = " + ooo.x)
		}
	}
}

总结:scala的内部类和java的内部类的主要区别就在内部类对象的创建方式不一样。其次scala为了灵活的在内部类的局部访问内部类成员或者外部类的成员,可以给内部类和外部类的引用提供一个别名,方便操作。

. object对象

java中的main函数是静态,此时在class中定义的main是无法运行,但是吧class ObjectClassOps替换成object ObjectClassOps便可以运行,主要的原因在于,被object所修饰的结构中的所有的成员都是static静态。

​ 主要作用:

​ 1.给scala类提供程序运行的入口,静态的main函数

​ 2.给scala类也来提供静态成员——scala类的伴生对象来实现。

1.4.2. 单例

java的单例

/*
 单例设计模式之饿汉式
 应用场景:预加载类的,比如程序预加载
    所谓单例,指的就是本类只能拥有一个实例对象
        为了实现这个目标,就是私有化构造器
    此时外部便无法访问本类的实例对象
        于是乎,创建一个静态的返回值为本类引用的方法
    在第二步创建的这个方法中返回的本类实例对象需要在本类成员位置上提前创建好
    
*/

calss Singletion{
private Singletion(){}
private static Singletion singletion = new Singletion();
public static Singletion getInstance (){
   return singletion;
}
}

懒汉式 —>死记硬背

 class Singleton {
  
  private Singleton(){}
  private int x = 3;
  private static Singleton singleton;
  public static /*synchronized*/ Singleton getInstance() throws InterruptedException {
      if(singleton == null) {
          synchronized (Singleton.class) {
              if(singleton == null) {
                  singleton = new Singleton();
              }
          }
      }
      return singleton;
  }
  }

scala的单例,

object _04SingletonOps {
	def main(args: Array[String]): Unit = {
		val s1 = Singleton.getInstance()
		val s2 = Singleton.getInstance()
		s1.x = 6
		println(s1 == s2)
		println(s1.x)
		println(s2.x)
	}
}
class Singleton private () {
	var x = 5
}
object Singleton {
	private val s = new Singleton
	def getInstance():Singleton = {
		s
	}
}
```
上一篇:03——微信小程序官方demo讲解——page部分


下一篇:第二章 变量和数据类型