scala学习笔记:面向对象编程基础

来源:互联网 发布:淘宝极速退款 编辑:程序博客网 时间:2024/05/22 01:44

基本示例

新建类,类中的函数叫做方法(再提醒一遍:带等号的函数是有返回值的):

class HelloWorld{    private var name="daya"     //私有变量    def sayhello(){        println("hello "+name)}    def getname()=name    //对外接口}

创建实例并调用方法:

var helloworld=new HelloWorldhelloworld.sayhello()var name=helloworld.getname()

类中的权限问题

类域私有

定义一个类域私有变量的类:

class Student{    //name与age的访问权限限于同类对象    private var name="defualt"    private var age=0    def set_name(newname:String){        name=newname    }    def set_age(newage:Int){        if(newage>=0)   age=newage        else    println("illegal age!")    }    //下面方法是可以访问到另一个Student类中的age变量的    def older(stuedent:Student)={        age>stuedent.age    }}

执行:

var student1=new Studentvar student2=new Studentstudent1.set_age(20)student1.set_age(22)student1.older(student2)

输出:

对象域私有

相反的,定义一个对象域私有变量的类:

class Student_this{    //此时name与age不能跨对象访问    private[this] var name="defualt"    private[this] var age=0    def set_name(newname:String){        name=newname    }    def set_age(newage:Int){        if(newage>=0)   age=newage        else    println("illegal age!")    }    //此处会报错    def older(student:Student)={        age>student.age    }}

shell会报错:

scala中的构造函数

构造函数常用于在新建对象时初始化类中的变量,与Java相似的是scala中的辅助构造函数:

class Student{    private var name="default"    private var age=0    def this(name:String){        this()        this.name=name    }    def this(name:String,age:Int){        this(name)        this.age=age    }    def get_info(){        println("name:"+name+" age:"+age)    }}

执行:

var student1=new Studentvar student2=new Student("daya",20)student1.get_info()student2.get_info()

输出:

内部类

object关键字

单例对象

object创建的为对象实例,并且不能带参数。需要注意的是object示例中的构造函数只在首次调用时运行,详见示例代码与运行结果:

object ObjectDemo{    private var num=5    println("constructor is running...")    def getNum()=num}

调用两次object方法,其输出为:

伴生

同名的class与object互为伴生关系,可以互相访问对方的private成员:

class Person(name:String,age:Int){    def sayHello()={        println("Hi,"+name+",you are "+age+" years old,you have "+Person.eyeNum+" eyes.")   //这里的eyeNum是object中的私有成员    }}object Person{    private var eyeNum=2    def getEyenum=eyeNum}var p1=new Person("daya",18)p1.sayHello()

apply()方法

apply()方法是使在创建对象时能够直接使用类名,摆脱new关键字打的方法,scala中典型的例子为Array类,在新建一个Array类对象时,我们可以直接使用类名加参数即可:

var array=Array(1,2,3,4,5)  此语句实际上新建了一个对象,但没有使用new关键字

自定义apply()方法:

class Person(val name:String){}object Person{    def apply(name:String):Person={        println("creat a Person object...")        new Person(name)    }}val person=Person("daya")

继承

基础

class Person{    private val name="Person"    def getName():String=name    def sayHello():Unit={        println("Person.Hello,"+getName)    }}class Student extends Person{    private val score="A"    override def sayHello():Unit={        println("Student.Hello,"+super.getName)    }}val s1=new Students1.sayHello()

父子类型转换

这好像类似于Java中的多态,假设创建了一个子类实例,却给它赋予了父类类型,比如:

class Person{}class Student extends Person{}val person:Person=new Student

如果需要将person变量转换成Student类型,转换前需要做实例判断:

var student:Student=nullif(person.isInstanceOf[Student]){    student=person.asInstanceOf[Student]}

注意,isInstanceOf[]方法会判断对象是否是指定类及其子类的示例,判断范围较广。以上面的代码为例,当执行person.isInstanceOf[Person]时也会返回true,因为person变量是Student类的示例,而Student类是Person类的子类。

模式匹配

实际中更常用的是使用模式匹配(判断父类及其子类的示例)的方法来进行类型判断:

class Person{}class Student extends Person{}val person:Person=new Studentperson match{    case person:Person => println("it's Person.")    case _ => println("unknow type!")}

继承中的权限问题

跨实例访问继承变量

class Person{    protected val name:String="XXX"}class Student extends Person{    def makeGreeting(student:Student):Unit={        println("Hi,I'm "+name+",you are "+student.name+",rihgt?")      //第一个name为访问继承变量,第二个name为跨实例访问    }}val s1=new Studentval s2=new Students1.makeGreeting(s2)

单实例访问继承变量

将上述代码中的protected修改成protected[this],编译时会报错:

注意第六行,即访问父类变量是没错的:

抽象类

当父类中某些方法不确定(未定义)时,必须声明成抽象类,并且子类在实现抽象类中的抽象方法时不需要override关键字:

abstract class Person{    protected var name:String="XXX"    def sayHello():Unit}class Student extends Person{    def sayHello():Unit=println("Hi,I'm "+name)}val s1=new Students1.sayHello()

在Java中,当抽象类中的所有变量与方法都抽象时,可用接口interface来实现。