If I'm not mistaken, you are trying to map the OOP concepts found in popular languages such as Java to Ballerina right? While it's tempting to do so, that can actually be a counter productive effort. Instead of attempting to think of a solution to a problem in an object oriented manner and trying to write OOP-style code in Ballerina, it would be better to take time to get familiar with the type system and other constructs Ballerina provides and build up the solution using those constructs. The Ballerina by Examples (BBEs) would be a good place to start.
Having said that, I'll try to briefly answer the questions you've raised. The Ballerina type system is structural. In Java, any user defined type is an object and you use inheritance to establish the relationships between the types. In Ballerina, we compare the "shape" of the value to check if it is compatible with a particular type. Every value has a shape, and a type is a set of such shapes. Here's what the 2020R1 spec of the language says regarding this and subtyping:
A type denotes a set of shapes. Subtyping in Ballerina is semantic: a type S is a subtype of type T if the set of shapes denoted by S is a subset of the set of shapes denoted by T. Every value has a corresponding shape. A shape is specific to a basic type: if two values have different basic types, then they have different shapes.
Let's take a concrete example using records to further explain this.
type Person record {
string name;
int age;
};
type Student record {
string name;
int age;
string school;
};
public function main() {
Student st = {name: "John Doe", age: 18, school: "XYZ Academy"};
Person p = st; // this is a valid assignment
io:println(p);
}
In the above code snippet we can safely use a Person
reference to manipulate a Student
value since a Student
value is guaranteed to have the same fields as a Person
value.
The Student
record definition can be written as follows as well:
type Student record {
*Person; // this is a type reference
string school;
};
Referring a type as given above copies all the fields in the specified record to the current record. While this may look like inheritance, it's not. The definition above is equivalent to the the original definition we saw earlier.
In Ballerina, code is organized by modules. Similar to packages in Java, except that a module is made up of functions, type definitions (e.g., records, objects), services, listeners, constants etc. While objects are supported, it's just another type of values; not a unit of organization for code. Functions are a module level construct and if you intend to reuse it in other modules, it needs to have the public
access modifier. To call the function, you need to import the module and qualify the function call with the module name. e.g.,
int x = foo:barFunction();
Sharing variables across modules is not allowed in Ballerina. However, you can have public constants in a module. e.g.,
public const PI = 3.14;
Hope this clears things up. If you are interested in the design of the language, you can refer to the language spec I mentioned earlier and to the following blog posts from James:
Also, note that 0.991 is a heavily outdated version. I'd recommend taking a look at the current version (1.2.2).