Update page 'P# v1.0 Specification'

2018-07-28 12:50:15 +02:00
parent b8dac22ae6
commit 1e24a9a047

@@ -295,7 +295,7 @@ When an expression contains multiple operators, the precedence of the operators
| 3 | increment / decrement | ++ -- | non-associative |
| 4 | unary operators | - + ~ ! @ | right-associative |
| 4 | cast operators | (typedef) | right-associative |
| 7 | binary operators | instanceof | non-associative |
| 7 | object-related | instanceof | non-associative |
| 7 | arithmetic operators | * / % | left-associative |
| 8 | arithmetic operators | + - | left-associative |
| 9 | bitwise operators | << >> | left-associative |
@@ -683,19 +683,64 @@ The inheritance is a way to form new classes using classes that have already bee
}
In this script, there are two classes: a Base class and a Derived class. The Derived class inherits from the Base class. In P#, the extends keyword is used to create inheritance relations. In the constructor of the Derived class, we call the parent constructor. We use the parent keyword, followed by two colons and a method name. The constructors of the parent classes must be called explicitly. Output od the above example is "Hello World!'.
Additionally, P# supports multiple inheritance:
### 10.10. Multiple inheritance
When one class extends more than one classes then this is called multiple inheritance. For example if class Derived extends classes Base1 and Base2 then this type of inheritance is known as multiple inheritance:
class Base1 {}
class Base2 {}
class Derived extends Base1, Base2 {}
Above code could be also written in the following way:
Multiple inheritance can lead to ambiguity. One of the example of such problem is the diamond problem that occurs in multiple inheritance. P# tries to address this problem, thus supporting multiple inheritance only partially.
class Base1 {}
class Base2 extends Base1 {}
Class Derived extends Base2{}
class Base1 {
void funcA() {
print('funcA from Base1');
}
}
### 10.10. Virtual Classes & Methods
class Base2 {
void funcB() {
print('funcB from Base2');
}
}
class Derived extends Base1, Base2 {
}
In above situation, class Derived inherits method funcA() from Base1 class, and method funcB() from Base2 class. However, only class Base1 is registered as direct base class. This means that only methods from class Base1 can be accessed by using __parent__ operator. Because both method names are different, in this specific case both of them are accessible by using $this operator.
class Base1 {
void funcA() {
print('funcA from Base1. ');
}
}
class Base2 {
void funcA() {
print('funcA from Base2. ');
}
}
class Derived1 extends Base1, Base2 {
}
class Derived2 extends Base2, Base1 {
}
class Main {
public void __construct() {
object $a = new Derived1();
object $b = new Derived2();
$a->funcA();
$b->funcA();
}
}
The ordering occurrences of classes after the __extends__ keyword has a major importance. Above example will "funcA from Base1. funcA from Base2.". This is because an instantiated object cannot inherit 2 methods with the same name. While, the first one is always valid, the second gets omited. It is also impossible to overload methods between derived classes.
### 10.11. Virtual Classes & Methods
Virtual classes cannot be instantiated. If a class contains at least one virtual method, it must be declared virtual too. Virtual methods cannot be implemented, they merely declare the methods' signatures. When a class inherits from a virtual class, all virtual methods must be implemented by the derived class. Furthermore, these methods must be declared with the same or with a less restricted visibility.
Unlike interfaces, virtual classes may have methods with full implementation and may also have defined member fields. So virtual classes may provide a partial implementation.
@@ -725,10 +770,10 @@ Unlike interfaces, virtual classes may have methods with full implementation and
}
}
### 10.11. Magic Methods
### 10.12. Magic Methods
When the print keyword is used with the object instance, the \__toString() magic method is called.
### 10.12. Class Constants
### 10.13. Class Constants
P# enables to create class constants. These constants do not belong to a concrete object. They belong to the class.
class Math {
@@ -741,13 +786,13 @@ P# enables to create class constants. These constants do not belong to a concret
In above example, the const keyword is used to define a constant. Class constants are accessed from within methods using the self keyword followed by two colons.
### 10.13. Static Keyword
### 10.14. Static Keyword
P# allows to declare class properties and methods to be static. The static properties and methods do not belong to the instance of the class. They belong to the class itself. They are accessible through the scope resolution operator.
### 10.14. Final Keyword
### 10.15. Final Keyword
Final methods cannot be overridden and final classes cannot be extended. The final keyword is a matter of design of the application. Some classes should not be extended and some methods should not be overridden. This behaviour is enforced by the final keyword.
### 10.15. Instanceof Keyword
### 10.16. Instanceof Keyword
The instanceof keyword is used to determine whether a variable is an instantiated object of a certain class.
object $obj = new MyClass();
@@ -755,7 +800,7 @@ The instanceof keyword is used to determine whether a variable is an instantiate
print("\$obj is instance of MyClass");
}
### 10.16. Interfaces
### 10.17. Interfaces
Object interfaces allow to create code which specifies which methods a class must implement, without having to define how these methods are implemented. Interfaces are defined in the same way as a class, but with the interface keyword replacing the class keyword and without any of the methods having their contents defined. All methods declared in an interface must be public; this is the nature of an interface. Note that it is possible to declare a constructor in an interface, what can be useful in some contexts, e.g. for use by factories.
interface MyInterface {
@@ -767,7 +812,7 @@ Object interfaces allow to create code which specifies which methods a class mus
}
}
### 10.17. Exceptions
### 10.18. Exceptions
Exceptions are designed to handle the occurrence of exceptions, special conditions that change the normal flow of program execution. Exceptions are raised or thrown and initiated. During the execution of script, many things might go wrong. A disk might get full and it might be unable to save a file. An Internet connection might go down while script tries to connect to a site. All these might result in a crash. To prevent happening this, script must cope with all possible errors that might occur. For this, thee exception handling can be used.
try {
@@ -778,8 +823,8 @@ Exceptions are designed to handle the occurrence of exceptions, special conditio
// code to execute regardless of whether an exception has been thrown
}
#### 10.17.1. Catch Block
#### 10.18.1. Catch Block
Multiple catch blocks can be used to catch different classes of exceptions. Normal execution (when no exception is thrown within the try block) will continue after that last catch block defined in sequence. Exceptions can be thrown (or re-thrown) within a catch block.
#### 10.17.2 Finally Block
#### 10.18.2 Finally Block
A finally block may also be specified after or instead of catch blocks. Code within the finally block will always be executed after the try and catch blocks, regardless of whether an exception has been thrown, and before normal execution resumes.