在Nim中。proc 是定义过程的keyword。method 是定义方法的keyword。它们之间根本的差别是proc定义的过程是静态绑定。method定义的方法是动态绑定。谈到静态绑定、动态绑定又会提到重载、重写和多态等方面的内容,假设对上述的一些概念不太理解。能够看我的上一篇博文。
过程的重载:
例1:
proc print (): void = echo ("This is empty") proc print (a:int): void = echo ("int a = ",a) proc print (a:float): void = echo ("float a = ",a) print() print(1) print(1.0)
Out: This is empty int a = 1 float a = 1.0
方法的重载:
例2:
type person* = ref object of RootObj name*:string age*:int method mm(p:person): int = echo p.age,p.name echo "method" return 0 method mm(p:person,x:int): int = echo "methodint ",x return 0 method mm(p:person,x:float): int = echo "methodfloat ",x return 0 var yrs = person(name:"yrs",age:23) discard yrs.mm() discard yrs.mm(3) discard yrs.mm(3.0)
Out: 23yrs method methodint 3 methodfloat 3.0
proc定义的过程,它的參数没有什么要求,能够没有參数,能够是基本类型,也能够是自定义的类类型。
可是method定义的方法,它的參数必须至少含有一个类类型的的參数。
也就是说method方法的模块里,必须含有类。同一时候该方法的參数至少含有一个类类型的參数。
方法的重写与多态:
例3:
#Module: tProcMethod.nim type Animal* = ref object of RootObj name*: string age*: int proc SelfIntroduce*(this: Animal): void = echo ("my name is animal") method vocalize*(this: Animal): string = "..." method ageHumanYrs*(this: Animal): int = this.age type Dog* = ref object of Animal proc SelfIntroduce*(this: Dog): void = echo ("my name is ",this.name) method vocalize*(this: Dog): string = "woof" method ageHumanYrs*(this: Dog): int = this.age * 7 type Cat* = ref object of Animal proc SelfIntroduce*(this: Cat): void = echo ("my name is ",this.name) method vocalize*(this: Cat): string = "meow"
#Module:testProcMethod.nim import tProcMethod var animals : Animal animals = Dog(name: "Sparky", age: 10) echo animals.name echo animals.age echo animals.vocalize() #method方法调用。是通过 实例对象引用.方法名 echo animals.ageHumanYrs() tProcMethod.SelfIntroduce(animals) #这里调用proc过程是用 模块名.过程名,在在Windows下用命令行执行文件时,文件名称(模块名)的全部字母被觉得是小写, #这里调用过程时要注意模块名字母的大写和小写。 在Linux下则区分大写和小写。 animals = Cat(name: "Mitten", age: 10) echo animals.vocalize() echo animals.ageHumanYrs() tProcMethod.SelfIntroduce(animals)
Out: Sparky 10 woof 70 my name is animal neow 10 my name is animal
方法的重载、重写与多态:
例4:
type Far = ref object of RootObj bigSon = ref object of Far smallSon = ref object of Far x: int method collide(x:Far,y:int) = echo "to override!" method collide(x: bigSon, y: int) = echo "big1" method collide(x: smallSon, y: int) = echo "small1" method collide(x: bigSon, y: float) = echo "2" method collide(x: bigSon, y: bigSon) = echo "3" var far: Far var bigsona, bigsonb: bigSon var smallsona: smallSon new far new bigsona new bigsonb new smallsona collide(far,1) far = bigsonb collide(far,1) collide(bigsona,1.0) collide(bigsona,bigsonb) far = smallsona collide(far,1)
Out: to override! big1 2 3 small1
在例4中。第二和第三个collide方法各自是bigSon类的方法和smallSon类的方法,它们都实现了对父类方法的重写。第二、四、五collide方法是bigSon类的方法,它们实现了collide方法的重载。
由上面的两个样例能够看出。Nim中的类和方法的存在与Java和Python是不同的。它没有一个明显的界限去差别哪个方法属于哪个类,可是能够通过方法中类类型来辨别(注意动态绑定时。參数是从左至右查询的)。
这样就大大减少了程序的可读性,就像例4一样。我们能够像例3一样分开定义来添加程序的可读性。
总结:
1、过程是静态绑定。方法是动态绑定。
2、过程和方法都能重载。
3、过程可以被重写。可是不能实现多态效果。
4、方法可以被重写,可以实现多态效果。
5、注意方法和类的关系。
时间: 2024-10-07 05:47:40