简单定义Python和Scala的类和对象
Posted 鸿的学习笔记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单定义Python和Scala的类和对象相关的知识,希望对你有一定的参考价值。
在现代编程语言里,类和对象都是绕不过的话题。对象这个概念可以是生活的抽象,为了更好的理解使用书来做比喻,每一本书都是一个对象,也就是一个实例,书本身具有的页码等等固定不变的东西,就是属于书的性质(属性),而我们对书有着一系列的操作,比如打开书,合上书,在编程语言里称为方法。我们把各种各样的书都可以抽象为一种类型,也就是类。先有类,再有实例,类是对象的蓝本。
我们以书籍为例,先看看如何构建一个类:
Scala:
class Book{
//类的定义
}
Python:
class Book:
pass#类的定义
Scala的类使用了{}将整个类的定义包含起来,而Python的类通过缩进符来包含整个类的定义。Scala的Python选取类名的规则都是一样的,采用驼峰式命名,单词的首字母大写。Python的类都继承自object,而Scala的类就是一个纯粹的类。在Scala使用new Book来创建一个实例,而Python使用Book()来实例(实际上是__new__的语法糖)。我们可以在类的定义了加上一些好玩的东西,比如属性和实例。
a = Book.__new__(Book)
isinstance(a,Book)
Out[1]: True
说明一下:为了方便,Scala使用idea作为编辑器,构建一个Test的单例对象运行程序(后面会聊到的,先跳过)。Python使用Spyder作为编辑器,使用if __name__ == 'main':去模拟main方法。因为只是为了讲解概念,会略去很多工程上的细节。
初始化:
书一般都会有书名,假设书名可以区分书的唯一性,在创建实例时必须要给这个实例一个书名,那么如何给Book这个类添加书名这个属性:
Scala:
object Test{
def main(args: Array[String]): Unit = {
val book = new Book("Hello World!")
}
class Book(name:String){
println(name)
}
}
Python:
class Book:
def __init__(self, name:str):
self.name = name
print(self.name)
if __name__ == '__main__':
book = Book("Hello World!")
在Scala的Book类后面的圆括号里跟着一个标识符name(称为类参数),使用这种方法构造的类,要求使用者在刚开始创建这个实例时就必须要提供相应的数据,我们在Book这个类里面加上了println方法,在创建book这个实例时,就会打印出来name这个参数。Python在实例的初始化,使用__init__的内置方法,self是Python的一个习惯命名,因为Python在类方法上都会在第一个参数传入这个类的实例,我们把传入的name赋值给self.name(实例属性),再print出来。
属性:
我们去看一本书,可能会首先大概的翻一翻去获得这个本书的页数pages这个属性。
Scala:
object Test{
def main(args: Array[String]): Unit = {
val book = new Book("Hello World!")
book.pages = 100
println(book.pages)
}
class Book(name:String){
var pages = 0
println(name)
}
}
Python:
class Book:
pages = 0
def __init__(self, name:str):
self.name = name
print(self.name)
if __name__ == '__main__':
book = Book("Hello World!")
book.pages = 100
print(book.pages)
Scala和Python定义了一个类属性pages,并且在实例化后通过book.pages = 100进行赋值,表示这本叫做Hello World!的书有一百页。值得注意的是Scala我们使用了var变量,而不是val变量,这样就可以在后续代码里对其重新赋与不同的值。
私有属性:
假设这本书你已经写上属于你的独有笔记,不希望别人看到,那么我们可以定义私有属性来防止别人的偷窥。
Scala:
object Test{
def main(args: Array[String]): Unit = {
val book = new Book("Hello World!")
book.pages = 100
println(book.notes)
}
class Book(name:String){
var pages = 0
private var notes = "呵呵哒"
println(name)
}
}
Python:
class Book:
pages = 0
_notes = "呵呵哒"
def __init__(self, name:str):
self.name = name
print(self.name)
if __name__ == '__main__':
book = Book("Hello World!")
book.pages = 100
print(book.notes)
这时候Scala会报如下错误:
Error:(9, 18) value notes in class Book cannot be accessed in Test.Book
println(book.notes)
Python会告诉你:
AttributeError: 'Book' object has no attribute 'notes'
Scala通过在变量前面加上private来防止实例化后,有人偷看笔记,而Python则是在notes前面加一个下划线表示这个属性不公开(当然这不是绝对意义上的不公开,要是你知道私有属性存在,无论是Scala还是Python都会有办法看到私有属性)。
方法:
当然笔记不会是无缘无故存在的,我们需要给这本书写上笔记,这个时候我们就需要使用方法,也就是某种操作修改或者写入笔记。
Scala:
object Test{
def main(args: Array[String]): Unit = {
val book = new Book("Hello World!")
book.pages = 100
book.writeNotes("very good")
println(book.pages)
}
class Book(name:String){
var pages = 0
private var notes = "呵呵哒"
println(name)
def writeNotes(note:String):Unit = {
notes = note
}
}
}
Python:
class Book:
pages = 0
_notes = "呵呵哒"
def __init__(self, name:str):
self.name = name
print(self.name)
def write_notes(self, note:str):
self._notes = note
if __name__ == '__main__':
book = Book("Hello World!")
book.pages = 100
book.write_notes("very good!")
print(book.pages)
Scala里我们写下了writeNotes方法,它接受外部传过来的参数note,并且将"very good!"重新赋值给notes,而Python则使用write_notes将"very good!"赋值给_notes变量。这里就体现了Scala和Python对于方法命名的小小区别,Scala使用了首字母小写,其余单词开头都是大写,而Python的分隔符使用_。(这里应该要有返回值,表示确实写入成功,为了简便省略了。)
剩下的是独属于Scala的内容了,讲讲单例对象。Scala的类定义里面是不允许存在静态方法的,所以Scala提供了object这种的单例对象,单例对象和类的定义很像,但是单例对象不需要实例化,单例对象本身就是一等的对象,单例对象的名称可以理解为附加在对象的上的名称。如果在同一源码中单例对象和某个类共用名字,那么这个单例对象称为这个类的伴生对象。类和它的伴生对象可以互相访问私有成员。没有同名的类的单例对象称为独立对象,也就是上文中的test这个对象,使用main方法承载,作为程序的入口。(此代码仅仅只是示例,平时不要这么玩)
object Test{
def main(args: Array[String]): Unit = {
book1.writeNotes("3")
}
}
object book1{
def writeNotes(note:String):Unit = {
println(note)
}
}
以上是关于简单定义Python和Scala的类和对象的主要内容,如果未能解决你的问题,请参考以下文章