scala基础4 —— 类
来源:互联网 发布:linux 时间格式转换 编辑:程序博客网 时间:2024/05/11 17:53
scala的类定义和java差不多,只是要更为灵活一些。
在scala中,类的声明不需要public关键字,一个文件中可以声明多个类,而这些类都是公共可见的。
比如,构造一个账户类,里面有值保存余额:
class Account { private var value = 0 // 成员必须初始化 def add(x : Int) { value += x} // 方法默认是public的 def current() = value}// 对类的使用Account myAccount = new Account() // 或者new AccountmyAccount.add(50)myAccount.current // 调用无参方法可以不需要括号
关于类方法的调用
scala对象调用方法时,对于无参方法,可以选择要不要加括号,一般的习惯是要修改(set)成员变量,则加括号;要仅仅获取(get)成员值,则习惯不加括号。
另,如果类方法在声明的时候就没有括号(这在scala中也是可以的),那么调用时候也不能加括号。
getter和setter
对于java程序,我们一般习惯将成员变量设置为private的,并且提供getter和setter方法来对成员变量进行操作。
而在scala中,getter和setter方法时编译自动完成的,其中访问控制(public,private)和变量的访问控制相同,当然,也可以自己重新定义getter和setter方法,不过名字不是getXXX和setXXX,而是xxx和xxx_=。比如:
class Person { var age : Int = 0}object Main { def main(args: Array[String]): Unit = { var p = new Person println(p.age) // 调用p.age() p.age = 10 // 调用p.age_=(10) }}
scala的这种设计符合统一访问原则(某个模块提供的所有服务都应该能通过统一的表示法访问到,通过什么方式实现,应该让使用者无感知),在上述例子中,p.age不知道是通过字段还是方法访问到的。
字段访问控制
- 类某个字段是私有的,则getter和setter也是私有的;
- 如果字段是val的,则只有getter方法生成;
- 如果不需要任何getter和setter,可以将字段声明为private[this]
- scala的类方法可以访问该类所有其他对象的私有字段,如果字段声明为private[this],则只有当前对象能访问,比如:
class Person { private var age : Int = 0 private[this] var name : String = "" def changeAge(p : Person): Unit = { this.age = p.age // OK } def changeName(p : Person): Unit = { this.name = p.name // ERROR }}
构造函数
scala和java一样可以有多个构造函数,但是不一样的地方是,scala有一个特别的构造函数,就是primary constructor(主构造器)。
每个类都有主构造器,并且,主构造器不是this方法定义,而是和类的定义交织在一起,其参数直接放在类名之后,比如:
class Person (var age : Int, val name : String) { println("this is in primary constructor!") // 类中定义的所有语句都会在主构造器中调用}object Main { def main(args: Array[String]): Unit = { val p = new Person(10, "Jack") // 必须传入参数构造 println(p.age) }}
当然,如果类名后无参数,生成的就是一个默认的无参主构造器,scala类主构造器的声明和类普通成员变量声明形式一样,主要与以下几种:
如果主构造器成员变量声明让你不容易接受,你可以使用普通方式,即辅助构造器this()来声明一个或者多个构造函数,但是我们应该学会习惯并使用主构造器,因为,scala追求的简洁我们应该要学会利用。
另,如果要让主构造器为私有的,可以如下定义:
class Person private(var age : Int, val name : String) { // 注意private关键字 println("this is in primary constructor!") }
嵌套类
scala中可以在类中定义嵌套类,但是和java的嵌套类有一些不同,scala中的内部类属于外部类的实例,即不同实例的内部类类型时不一样的;而java中内部类从属于外部类,下面从我们从一个家庭类Family和成员类Member来看看java和scala的不同:
java内部类:
public class Family { private String familyName; private List<Member> memberList = new ArrayList<>(); public Family(String familyName) { this.familyName = familyName; } public void jionMember(Member member) { memberList.add(member); } public class Member { private String name; public Member(String name) { this.name = name; System.out.println(familyName + " new member:" + this.name); } } public static void main(String[] args) { Family family = new Family("Jack's family"); Family family1 = new Family("Mark's family"); Member member = family.new Member("jackson"); // 注意声明语法 Member member1 = family1.new Member("mark"); // 注意声明语法 family.jionMember(member); // OK family.jionMember(member1); // OK }}
scala内部类
class Family (var familyName : String) { private var memberList : mutable.MutableList[Member] = mutable.MutableList() def jionMember(member: Member): Unit = { memberList += member } class Member (var name : String) { println(familyName + " new family member:" + name) }}object Family { def main(args: Array[String]) { var family = new Family("Jack's family") var family1 = new Family("Mark's family") val member : family.Member = new family.Member("jack") // 注意声明语法 val member1 : family1.Member = new family1.Member("Mark") family.jionMember(member) family.jionMember(member1) // 不可以 }}
从上面可以看出,scala中不允许不同外部类的实例声明的内部类混合使用。
如果想打破这种限制,可以将内部类放在别处,比如Family类的伴生对象中,或者使用类型投影方式(暂不介绍)。
- scala基础4 —— 类
- scala—基础I
- Scala——基础篇
- Scala学习——基础
- Scala基础—再谈HelloWorld
- Scala基础—多线程示例
- scala基础5 —— 类的继承
- Spark 基础 —— Scala 集合
- scala基础2 —— 函数
- Scala学习——基础篇1
- 《快学Scala》——基础
- Scala基础——可变参数
- 学习笔记—scala基础II
- Scala基础—再谈控制语句
- Scala基础—函数式编程示例
- Scala基础—数组操作示例
- Scala基础—面向对象编程示例
- Scala基础—Trait使用示例
- 第五周项目五
- 将C/C++注册到LUA环境中使用
- 使用Retrofit和RxJava进行轮询操作
- 详解Spring MVC 4常用的那些注解
- 关于Java线程的面试题
- scala基础4 —— 类
- 短信验证码开发教程 - 1.热身篇
- Oracle12c安装时的问题:创建TableSpace和用户的时候与11g的代码命令一样
- 解决Android Studio2.2版本FloatingActionButton按钮预览太小的问题
- iOS开发-用Photos框架自定义选取照片界面
- XShell连接串口
- jQuery Ajax 跨域请求与getJSON跨域请求
- shell脚本编程:sed命令编辑文本
- c++类中的静态成员函数总结