跳转到内容

环/教程/面向对象编程 (OOP)

来自维基教科书,开放世界中的开放书籍
<

面向对象编程 (OOP)

[编辑 | 编辑源代码]

在本章中,我们将学习如何在 Ring 编程语言中使用面向对象编程范式。

我们将学习关于

  • 类和对象
  • 使用大括号访问对象
  • 组合
  • Setter 和 Getter
  • 私有属性和方法
  • 运算符重载
  • 继承
  • 动态属性



类和对象

[编辑 | 编辑源代码]

我们可以使用以下语法定义新类

语法

	Class <Class Name> [From <Parent Class Name>]
		[Attributes]
		[Methods]
		[Private
                  [Attributes]
		  [Methods]
                ]

我们可以使用以下语法创建对象

语法

	New <Object Name> [ (init method parameters) ] |
			  [ { access object data and methods } ]   ---> Object

示例

	New point { x=10  y=20  z=30  print() }
	Class Point x y z func print see x + nl + y + nl + z + nl

.. 注意:我们可以使用 { } 来访问对象数据和方法。

.. 提示:我们可以在类名后直接声明类属性。

输出

	10
	20
	30

我们可以用另一种方式重写相同的程序

	New point 			# create new object using the point class
	{ 				# access the new object attributes and methods
		x = 10 			# set the x attribute to 10
		y = 20 			# set the y attribute to 20
		z = 30 			# set the z attribute to 30
		print() 		# call the print method
	}				# end of object access


类 Point # 定义 Point 类 x y z # 类包含三个属性 x、y 和 z func print # 定义 print 方法 see x + nl + # 打印 x 属性 y + nl + # 打印 y 属性 z + nl # 打印 z 属性


我们也可以用另一种方式编写相同的程序

	P1 = New Point
	P1.x = 10
	P1.y = 20
	P1.z = 30
	P1.Print()
	Class Point x y z func print see x + nl + y + nl + z + nl

.. 注意:我们可以使用点运算符在对象名后访问对象成员。

我们也可以用另一种方式编写相同的程序

	new point { print() } 	
	Class Point
		x = 10  y = 20  z = 30
		func print see x + nl + y + nl + z + nl

.. 注意:我们可以在声明类属性时为其设置默认值。

我们也可以用另一种方式编写相同的程序

	new point(10,20,30)
	Class Point
		x y z 
		func init p1,p2,p3 x=p1 y=p2 z=p3 print()
		func print see x + nl + y + nl + z + nl

.. 注意:我们可以在创建新对象时直接使用 () 调用 init 方法

我们也可以用另一种方式编写相同的程序

	new point( [ :x = 10 , :y = 20 , :z = 30 ] )
	Class Point x y z
	      func init aPara x = aPara[:x] y = aPara[:y] z = aPara[:z] print()


.. 提示:使用 Hash 传递方法参数使我们能够创建可选的

        parameters and change the order of parameters when adding them to the Hash.

使用大括号访问对象

[编辑 | 编辑源代码]

我们可以使用大括号 { } 在任何时候访问对象。

在大括号内,我们可以直接使用对象的属性和方法。

这可以在我们使用 New 关键字创建对象时完成,或者在任何时候使用以下语法完成

	ObjectName { access object data and methods }

示例

	See "Creating the Object" + nl
	o1 = new Point
	See "Using the Object" + nl
	o1 {
		x=5 	
		y=15
		z=25	
		print()
	}
	Class Point x y z func print see x + nl + y + nl + z

当我们调用函数或方法时,可以使用大括号来访问对象。

示例

	o1 = new Point

	print( o1 { x=10 y=20 z=30 } )
	
	func print object
		see object.x + nl + 
		    object.y + nl + 
		    object.z 

	Class Point x y z

我们可以在同一个表达式中混合使用大括号和点运算符来访问对象。


示例

	o1 = new Point

	O1 { x=10 y=20 z=30 }.print()
	
	Class Point x y z
		func print see x + nl + y + nl + z

对象可以包含其他对象作为属性。

可以使用大括号嵌套访问对象。

示例

	R1 = New Rectangle 
	{

		Name = "Rectangle 1"

		P1 
		{
			X = 10
			Y = 20
		}

		P2 
		{
			X = 200
			Y = 300
		}	

	        Color = "Blue"

	}
	
	see "Name : " + R1.Name + nl +
	    "Color: " + R1.Color + nl +
	    "P1   : (" + R1.P1.X + "," + R1.P1.Y + ")" + nl + 
	    "P2   : (" + R1.P2.X + "," + R1.P2.Y + ")"  

	Class Rectangle
		name  color
		p1 = new Point
		p2 = new Point

	Class Point x y

输出

	Name : Rectangle 1
	Color: Blue
	P1   : (10,20)
	P2   : (200,300)

Setter 和 Getter

[编辑 | 编辑源代码]

我们可以定义方法,在设置和获取对象属性时使用。

语法

	Class ClassName

		AttributeName
		...

		Func SetAttributeName
			...

		Func GetAttributeName
			...

示例

	o1 = new person

	o1.name = "Mahmoud"  see o1.name + nl

	o1 { name = "Ahmed"  see name }

	Class Person

		name family = "Fayed"

		func setname value
			see "Message from SetName() Function!" + nl
			name = value + " " + family

		func getname
			see "Message from GetName() Function!" + nl
			return "Mr. " + name

输出

	Message from SetName() Function!
	Message from GetName() Function!
	Mr. Mahmoud Fayed
	Message from SetName() Function!
	Message from GetName() Function!
	Mr. Ahmed Fayed

私有属性和方法

[编辑 | 编辑源代码]

我们可以在类体中 private 关键字后定义私有属性和方法。

示例

	o1 = new person {
		name = "Test"
		age = 20
		print()
		o1.printsalary()
	}

	try
		see o1.salary
	catch
		see cCatchError + nl
	done

	try
		o1.increasesalary(1000)
	catch
		see cCatchError + nl
	done

	Class Person

		name age 

		func print
			see "Name   : " + name + nl + 
			    "Age    : " + age + nl 

		func printsalary
		  	see "Salary : " + salary + nl 

		private

		salary = 15000

		func increasesalary x
			salary += x

输出

	Name   : Test
	Age    : 20
	Salary : 15000
	Error (R27) : Using private attribute from outside the class : salary
	Error (R26) : Calling private method from outside the class : increasesalary

运算符重载

[编辑 | 编辑源代码]

我们可以将运算符方法添加到我们的类中,以允许对类对象使用运算符。

语法

	Class ClassName

		...

		Func operator cOperator,Para

			...

函数运算符有两个参数,第一个表示运算符,第二个表示运算符后的第二个参数。

示例

	o1 = new point { x = 10 y = 10 print("P1    : ") }
	o2 = new point { x = 20 y = 40 print("P2    : ") }

	o3 = o1 + o2
	o3.print("P1+P2 : ")

	class point x y

		func operator cOperator,Para
			result = new point	
			switch cOperator
			on "+"
				result.x = x + Para.x
				result.y = y + Para.y
			on "-"
				result.x = x - Para.x
				result.y = y - Para.y
			off
			return result

		func print cPoint
			see cPoint + "X : " + x + " Y : " + y + nl

输出

	P1    : X : 10 Y : 10
	P2    : X : 20 Y : 40
	P1+P2 : X : 30 Y : 50

我们可以在类定义中使用 from 关键字从另一个类创建类。

语法

	Class <Class Name> [From <Parent Class Name>]

我们可以使用 super 对象从子类调用父类中的方法。

语法

	func methodname
		...
		super.methodname()
		...

示例

	Func main
		e1 = new Employee {
			Name = "test"
			age = 20
			job = "programmer"
			salary = 20000000
			print()
		}
	
	Class Human 
		Name Age
		func print
			see "Name : " + name + nl + "Age  : " + age + nl

	Class Employee from Human
		Job Salary
		func print
			super.print()
			see "Job  : " + job + nl + "Salary : " + salary + nl

输出

	Name : test
	Age  : 20
	Job  : programmer
	Salary : 20000000

动态属性

[编辑 | 编辑源代码]

我们可以在类名后编写指令,以便在创建新对象时执行这些指令。

示例

	o1 = new dynamicClass
	see o1.var5 + nl	# output 5

	Class DynamicClass
		for x = 1 to 10
			cStr = "var" + x + " = " + x
			eval(cStr)
		next

.. 提示:在前面的示例中,var1、var2、...、var10 将被定义为属性。

.. 提示:前面的示例的问题是,x 和 cStr 也将被定义为属性!

.. 注意:我们可以在字符串中编写类定义,然后使用 eval() 执行字符串以定义类。

我们可以使用以下语法创建一个包(一组具有共同名称的类)。

	package PackageName
		Class Class1
			...
		Class Class2
			...
		Class Class3
			...
		...

示例

	o1 = new System.output.console
	o1.print("Hello World")
	
	Package System.Output
		Class Console
			Func Print cText
				see cText + nl

.. 注意:我们可以使用点运算符作为包名称的一部分。

我们可以使用 import 命令而不是键入 PackageName.ClassName 的长名称。

当我们导入一个包时,我们可以直接使用这个包中的任何类。

示例

	import system.output
	o1 = new console {
		print("Hello World")
	}
	Package System.Output
		Class Console
			Func Print cText
				see cText + nl

打印对象

[编辑 | 编辑源代码]

我们可以使用 see 命令打印对象的 state(属性和值)。

示例

	see new point { x=10 y=20 z=30 }
	class point x y z

输出

	x: 10.000000
	y: 20.000000
	z: 30.000000


华夏公益教科书