How to implement inheritance in Ballerina
Asked Answered
B

2

7

I can see the following description in Ballerina docs regarding type equivalence and inheritance.

Ballerina is based on type equivalence, rather than type inheritance. The type system in Ballerina is based on set theory and, therefore, type equivalence has more meaning for this domain than type inheritance.

So can somebody please let me know how this set theory can be used to implement the concept of 'inheritance' or the a similar functionality? How we can do re-use of functions/class variables, etc? Is there a standard way of doing so? And please share if there are examples/blogs I can refer to.

https://v0-991.ballerina.io/learn/faq/#why-is-there-no-type-inheritance

Breechblock answered 19/4, 2020 at 17:56 Comment(0)
K
8

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).

Kierkegaard answered 19/4, 2020 at 21:20 Comment(1)
Thank you very much for the quick and descriptive answer. Probably module based function definition will be useful for me to reuse functions when required. p.s. I'm using ballerina 1.2.0 and couldn't a FAQ page in 1.2.0, hence referred a page of an old version.Breechblock
S
4

Ballerina does not support the implementation inheritance or class-based inheritance that you see in OO languages like Java. What this means is that you cannot inherit code from types in Ballerina (e.g. Ballerina objects).

The term inheritance is an overloaded term. If you want to know more about sybtyping in Ballerina, then read Pubudu's answer. It explains how you can achieve interface inheritance in Ballerina. You can map his answer to Ballerina objects as well.

Stroke answered 20/4, 2020 at 1:4 Comment(1)
thank you very much for the answer. Highly appreciate this kind of quick community support provided by Ballerina dev team.Breechblock

© 2022 - 2024 — McMap. All rights reserved.