Classes
Silk supports object oriented programming. Classes are the central feature and normally it is called user-defined types.
A
class is used to specify the form of an object and it combines
data(properties) and functions(methods) which can process
data.
Class Definition
A class definition starts with the keyword class followed by the class
name; the parameter, the init and functions, enclosed by a pair of
curly braces.
Here is a sample:
class class_name( parameter )
{
init;
functions;
}
class:keyword class, a class definition starts with class.
class_name:the name of the class, the name must be unique, and it
cannot be the same as other classes/functions/variables and keywords.
parameter:
when a class object is created, you can pass the value to the parameter to initialize the data of the object. parameter is optional.
init:initialize the properties of the class object.
functions:The methods of the class, it's the same as normal function which starts with func.
Class objectWe need to use
the class by creating the class object, creating object is like calling
function, and the return of the calling is the created object.
The properties and methods of the object can be accessed using the direct member access operator (.)
Let's take a look at the following example to make the things clear:
class myClass(a,b)
{
//initialize the class properties, we need to use keyword self to access the properties
self.a=a;
self.b=b;
self.c=0;
if(a>b)
self.c=1;
//define the class methods (functions)
func test()
{
printf("a=%d, b=%d, c=%d\n",self.a,self.b,self.c);
}
func test2()
{
self.a++;
self.test();
}
}
main()
{
obj=myClass(100,200);
obj.test2();
obj.a=300;
print(obj.a);
}
selfEvery object has access to its own properties and methods through an implicit parameter called self.
The self parameter is a reference to the current instance of the class, it's actuall the object itself.
The
above class method is like the following function, but the parameter
self in method is hidden, and you do not need to pass it when you
call the method:
func test(self)
{
printf("a=%d,b=%d\n",self.a,self.b);
}
Encapsulation Properties
and methods can be accessed without any limitation, the Encapsulation
is an Object Oriented Programming concept that binds together
the properties and methods that keeps both safe from
outside interference and misuse. we can define the private
properties and methods to hide them, this means they can be
accessed only within the class, and cannot be accessed from outside.
To define the private properties and methods, just add __ before the name:
class myClass(a)
{
self.__a=a;//private property
func __test()//private method
{
printf("a=%d\n",self.__a);
}
func test2()
{
self.__a++;
self.__test();
}
}
main()
{
obj=myClass(100);
obj.test2();
print(obj.__a);//cannot access the private property, will get error
}
InheritanceOne
of the most important concepts in object-oriented programming is that
of inheritance. Inheritance allows us to define a class in terms of
another class, which makes it easier to reuse the code
functionality. When creating a class, instead of writing completely new
data and functions, the programmer can designate that the new
class should inherit the members(data and functions) of an
existing class. This existing class is called the base class, and the
new class is referred to as the derived class. Currently silk does not
support multiple base classes.
In Silk, we can assign the base class object to self to inherit the members of base class:
//base class Animal
class Animal(name)
{
self.name=name;
func description()
{
printf("this is %s\n",self.name);
}
}
//derived class Dog
class Dog(name)
{
self=Animal(name);//inherit the base class Animal
func SetName(name)
{
self.name=name;//update the property in base class
}
}
main()
{
dog=Dog("dog");
dog.description();//call the method in base class
dog.SetName("pet");//the new method in derived class
dog.description();
}
Result:
this is dog
this is pet
OverridingIf the method in base class is not what we need, we can override it and rewrite a new one in derived class:
//base class Animal
class Animal(name)
{
self.name=name;
func description()
{
printf("this is %s\n",self.name);
}
}
//derived class Dog
class Dog(name)
{
self=Animal(name);//inherit the base class Animal
func description()//override the method in base class
{
printf("I am %s, I can swim\n",self.name);
}
}
main()
{
dog=Dog("dog");
dog.description();
}
Result:
I am dog, I can swim
To
access the overridden method of the base class, we can save the base
class method before overriding it and call it later:
//base class Animal
class Animal(name)
{
self.name=name;
func description()
{
printf("this is %s\n",self.name);
}
}
//derived class Dog
class Dog(name)
{
self=Animal(name);//inherit the base class Animal
self.super_description=self.description;//save the method in base class
func SetName(name)
{
self.name=name;//update the property in base class
}
func description()//override the method in base class
{
self.super_description();//call the original method in base class
printf("I can swim\n");
}
}
main()
{
dog=Dog("dog");
dog.description();
}
Result:
this is dog
I can swim
PolymorphismPolymorphism
means having many forms. Typically, polymorphism means that a call to a
member function will cause a different method to be executed depending
on the type of object that invokes the method.
Silk is a dynamically typed language, and the type is determined at runtime, so Silk supports polymorphism
natually:
//base class Animal
class Animal(name)
{
self.name=name;
func description()
{
printf("this is %s\n",self.name);
}
}
//derived class Dog
class Dog(name)
{
self=Animal(name);
func description()
{
printf("I am dog, I can swim\n");
}
}
//derived class Bird
class Bird(name)
{
self=Animal(name);
func description()
{
printf("I am bird, I can fly\n");
}
}
func test_animal(animal)
{
//will call the method depending on the type of animal
animal.description();
}
main()
{
dog=Dog("dog");
bird=Bird("bird");
test_animal(dog);
test_animal(bird);
}
Result:
I am dog, I can swim
I am bird, I can fly