zoukankan      html  css  js  c++  java
  • Scala面向对象

    定义类

    //不用修饰符
    class HelloWorld{
    	//定义一个私有的field 
    	private var name = "CZM"
    	def fun(){
    		//这是一个带参数的方法
    	}
    
    	def getName = name
    	//定义一个不带参数的方法
    

    创建对象

    val helloWorld = new HelloWorld		//括号可有可无 
    

    调用方法

    //可以不写*()*
    helloWorld.fun()
    
    //不能写*()*
    helloWorld.getName
    

    getter和setter方法

    • 定义不带private的var field Scala生成面向JVM的类时,会定义成private的字段,并提供Public的getter和setter (也就是说,你在用对象调用这个值的时候,底层转换为使用pubic的getter/setter方法访问)
    • 定义带private的field,则生成的getter和setter方法也是private的,外部不能调用,只能通过暴露的方法得到
    • 定义成val field时,只会生成getter方法
    • 如果不希望生成getter和setter方法,则将field声明成privete[this]
    //自动生成的getter和setter方法,通过 val var private private[this]
    var name = "CZM"
    /*自动生成如下代码
    //getter
    def name = name
    
    //setter
    def name_ = (new_name:String)
    */
    
    //手动getter和setter
    private var name= "CZM"
    def name = "Your name is "+name		//错误,因为这样相当于两次定义了name
    
    class HelloWorld {
      private var old_name= "CZM"
        def name = "Your name is "+old_name		//正确:old_name 作为类中的私有feild,仅仅提供私有的getter和setter方法,而name作为一个提供了public的getter和setter方法的feild ==> var name并重写了public的getter和setter
        def name_=(new_name: String) {		//需要注意的是这里的语法规则,**=号前后不允许有空格**
    	old_name = new_name
        print("Your new name is " + old_name)
      }
    }
    
    //调用getter和setter
    var helloWorld = new HelloWorld()
    helloWorld.name //geter 
    helloWorld.name_= "asd" //正儿八经setter
    helloWorld.name = "asd"	//新型setter,将name作为返回,买一送一
    

    privete[this]的使用

    class Student{
    	private var myAge = 0
    	//private[this] var myAge = 0 //调用getter方法会报错,即使定义了getter和setter方法
    
    	def age = myAge
    	def age_=(newValue:Int){
    		if (newValue<0){println("illegal gar!!")}
    		else{myAge = newValue}
    	}
    	def older(s:Student){
    		myAge > s.myAge 
    	}
    }
    

    怀旧党专用,使用类JAVA的getter和setter方法

    @BeanProperty var age = 0
    @BeanProperty var age:Int = _	//使用占位符需要声明类型
    
    //同时拥有两种调用方式
    s1.getAge
    s1.age
    

    构造函数constructor

    主constructor

    • 主构造函数就是与类名在一起的构造函数,关键问题是,当主构造函数定义了之后,就不能调用无参构造函数了,也就是说,主构造函数定义了最少参数的构造函数,以后就只有更多参数的了
    • 主constructor中定义的参数,如果被使用到,则会被声明成privat[this] var name
    • 如果类中没有使用到这个参数,则不会被声明,并不会有这个feild
    //当然,可以设置默认参数 
    class Student(name:String,age:Int){}
    

    辅助constructor

    class Student(){
    	private var name = ""
    	private var age = 0
    
    	def this(name:String){
    		this()		//如果不相互调用,必须调用**主构造函数**,且要在**首行 == JAVA**
    		this.name = name
    	}
    
    	def this(name:String,age:Int){
    		this(name)
    		this.age = age
    	}
    }
    

    内部类

    与JAVA不同的是,Scala中的外部类的对象的内部类都是不同的类

    import scala.collection.mutable.ArrayBuffer
    
    class Class {
    
      class Student(name: String) {}
    
      val students = new ArrayBuffer[Student]()
    
      def getStudent(name: String) = {
        new Student(name)
      }
    }
    
    val c1 = new Class
    val c2 = new Class
    
    val s1 = c1.getStudent("CZM")		//s1: c1.Student = Class$Student@1d3f8af1
    val s2 = c2.getStudent("czm")		//s2: c2.Student = Class$Student@73589106
    
    c1.students += s1	//正确
    c1.students += s2	//错误,每一个内部类都是属于对象的,而不是独立存在的
    
    /*错误信息
    Error:(21, 24) type mismatch;
    found   : c2.Student
    required: c1.Student
    c1.students += s2
    */
    

    object对象

    由于类中定义的feild都是属于对象的,并没有属于类的字段,在JAVA中使用Static定义的字段作为所有对象共用的类的字段,在scala中提供了object来存放。

    • object 也有constructor(不属于方法的代码都是静态加载),只在第一次被调用时执行一次,不能定义带参数的constructor
    • object通常用作单例模式(只有自己一个对象),或者作为伴生对象存放静态成员,静态工具方法
    • 与class相比,object仅仅是不能定义带参数的constructor,其他都是一样的,能继承其他方法
    //定义object对象
    object Person {		//不能有括号,不能定义带参数的constructor
      private var name = ""
      println("This is constructor!")
      def getName = name
      println("This is constructor too!")
    }
    Person.getName
    
    //让object继承抽象类
    abstract class Hello {
      def syaHello(name: String): Unit
    }
    
    object HelloObject extends Hello {
      override def syaHello(name: String): Unit = {
        println("Implement from Hello, your name is " + name)
      }
    }
    
    HelloObject.syaHello("CZM")
    

    伴生对象和伴生类

    • 在同一个.scala文件中。同名的class和object,称object为class的伴生对象,class称为object的伴生类
    • 伴生对象和伴生类之间可以相互访问private的feild
    • class中的一切属于对象
    • object中的一切属于类
    class Person(name: String, age: Int) {
      def sayHello = {
        println("Hello " + name + " you are " + age + " years old, and you must have " + Person.legNum + "legs")	//需要加上Object名访问object对象变量(即使不是私有的)
      }
    }
    
    object Person {
      private var legNum = 2    def getLegNum = legNum }
    
    val p1 = new Person("czm", 18)
    p1.sayHello
    

    Apply方法(允许重载?)

    • apply方法中一般做什么?创建一个对象,并返回对象
    • 为什么要Apply方法?让创建类对象来的更简单,直接使用 类名()即可
    • 为什么要在伴生对象中创建apply方法?因为这是一个工具方法,不应该属于对象,应该用类名调用
    class Person(name: String)
    
    object Person {
      def apply(name: String): Person = new Person(name)
    }
    Person("你好")
    

    main方法

    • 为什么要main方法?作为函数的入口
    • 为什么要定义在object中?因为main是public static的,需要被JVM使用类名调用

    方法1

    //注意文件名与类名相同
    object HelloWorld {
      def main(args: Array[String]) {
        if (args.length != 0) {
          println("Hello " + args(0))
        } else {
          println("Hello World!")
        }
      }
    }
    

    方法2:继承APP Trait

    继承APP Trait,然后将需要在main中运行的代码,直接在constructor中编写。直接使用args接收传入的参数黑人问号脸??:这里的参数是来自父类APP Trait的父类DelayedInit Trait的Main方法中的args

    • 工作原理:APP Trait 继承自DelayedInit Trait 编译时会将object中的constructor中的代码放到DelayedInit Trait的delayedInit方法中执行。DelayedInit的main方法将会调用delayedInit方法(为了懒加载?)
    object HelloWorld extends App{
    	if (args.length != 0) {
          println("Hello " + args(0))
        } else {
          println("Hello World!")
        }
    }
    

    使用object实现枚举

    • 枚举是什么:枚举是一个特殊的类,就是固定的多个常量对象的集合
    • Scala没有提供类似JAVA中的Enum这样的枚举特性,可以使用object继承Enumeration类,并且调用Value方法来初始化枚举值
    • 调用时,直接使用Season(0),为什么,不会跟apply冲突吗?继承了Enumeration,Enumeration中的apply方法是final的,子类不允许再定义apply只能继承Enumeration的apply(详情亲看源码)

    scala实现枚举

    object Season extends Enumeration{
      val SPRING,SUMMER,AUTUMN,WINTER = Value	//Value方法继承于Enumeration
      //可以自定义Value的元素
      val SPRING = Value(0,"spring")
      ...
    }
    
    //调用
    //Enumeration的apply方法返回一个Value对象                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
    Season(0)
    res0: Season.Value = SPRING
    
    Season("spring")
    

    java中的枚举

    enum Weeday{
    	SUNDAY,MONDAY.TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY;
    }
    
    //在底层
    //创建了一个final的Weeday类继承Enum
    //实例化各个字段为 public final static 的 Weekday 对象,存在数组$VALUES中
    //定义了一个values方法,用于返回数组		//Weekday.values()
    //定义了一个valueOf方法,用于返回			//Weekday.valueof("SUNDAY")
    
  • 相关阅读:
    day 12 元组的魔法
    day 12 列表的魔法,及灰魔法
    day 11 Python课上练习解释与基础知识练习题试题一
    day 11 rang的用法和练习
    day 10 字符串的魔法
    day1 Python可变与不可变类型
    day1 数据类型
    Math对象
    Calendar对象
    Date对象
  • 原文地址:https://www.cnblogs.com/cenzhongman/p/7457849.html
Copyright © 2011-2022 走看看