HOME Try Sather download Post Messages

5. Class


1. Introduction

In this section, I will talk about how to define your won classes.

As sather is an object oriented language, classes play an important role in the language.

The class system of Sather is somehow complicated. It contains partial classes, abstracted classes, parametrized classes, and immutable classes as well as conventional ones. I am explaining about conventional and abstracted classes in this section, then I will explain about parametrized and immutable classes in section 7 and 8.

2. Conventional classes

First I talk about the conventional classes. I just show a simple example without boring explanation, as the expected readers should know well about object oriented paradigm.

Let's think about cellphones. A cellphones is a mailer as well as a telephone. Thus cellphones inherit the function of telephone and mailer. Sather supports multiple inheritance and the telephone, the mailer, and the cellphone classes can be defined like as follows.

2.1. The telephone class

The telephone class is like as follows. it has two functions, to call and to receive. See also comments in the source code.
01:     class PHONE is                      -- The telephone class
02:     
03:        private attr phone_number:STR;   -- the phone number. Keywords private and attr mean that the parameter is private and belonging to instance, respectively
04:                                         -- if not private keyword, it is public
05:     
06:        create(pn:STR):SAME is           -- create is the constructor in C++
07:           return new.init(pn);          -- new allocate memory and apply init to it
08:        end;                             -- The SAME is the class that calls create. SAME should be used as the class can be inherited.
09:     
10:        private init(pn:STR):SAME is     -- init is a function to initialize. Even there are several way to implement create,
11:           phone_number := pn;           -- return new.init suit inheritance. The function initialize the instance parameter, phone_number.
12:           return self;                  -- returning the initialized instance (self).
13:        end;
14:     
15:        get_number:STR is                -- The method to get the phone number. The self in the self.phone_number can be omitted.
16:           return phone_number;
17:        end;
18:     
19:        phone_call(to:SAME, msg:STR):STR is    -- The method to call. The argument is other phone and message.
20:           return "From: " + phone_number +    -- It just returns a string (to make it simple).
21:     	    "\nTo: " + to.phone_number +  -- You can specify the instance like to.phone_number.
22:     	    "\nSubject: " + msg + "\n";   -- This method also use SAME. Use SAME as many as possible.
23:        end;
24:     end;  -- end of PHONE
Notes: Following shows how to make an instance of the PHONE class.
 phone1:PHONE:=PHONE::create("012-345-6789");  -- Formal way. Use this if the compiler doesn't like the abbreviations.
 phone2:PHONE:=#PHONE("023-444-5555");         -- '#PHONE' is the abbreviation of PHONE::create
 phone3:PHONE:=#("023-4545-6767");             -- You can omit the class name in many cases.

2.2. The mailer class

The mailer class can be defined like as follow.
It has its own mail address and the list of new mails as instance parameters, and mailing list as a class parameters. The methods of the class are to send, to receive, to submit to the mailing list, and to read the mailing list.
01:     class MAIL is
02:        private attr address:STR;                                 -- mail address
03:        private attr newmails:LIST{STR};                          -- the list of new mail, whose type is LIST{STR}
04:        private shared mailinglist:LIST{STR}:=LIST{STR}::create;  -- declaring and defining a class parameter mailinglist whose type is LIST{STR}. 
05:                                                                  -- In the case of constant and shared, you cannot use the abbreviation with '#'.
06:        create(ad:STR):SAME is
07:           return new.init(ad);
08:        end;
09:     
10:        init(ad:STR):SAME is
11:           newmails := #LIST{STR};                                -- Making the list of new mail.
12:           address := ad;                                         -- Setting its own address
13:           return self;                                           -- returning itself
14:        end;
15:     
16:        get_address:STR is                                        -- getting the address
17:           return address;
18:        end;
19:     
20:        send(to:SAME, msg:STR) is                                 -- The mail sending method, which add the message on his list of new mails.
21:           to.newmails.append("From: " + address + "\nSubject: " + msg + "\n");
22:        end;
23:     
24:        send2mailinglist(msg:STR) is                              -- Submitting to the mailing list. it add the message to the list.
25:           mailinglist.append("From: " + address + "\nSubject: " + msg + "\n");
26:        end;
27:     
28:        read_mail:STR is                                          -- Reading mails
29:           s:STR := address + " received following new messages:\n";
30:           loop
31:     	 s := s+ newmails.elt!;                              -- Taking a new mali from the new-mail-list.
32:           end;
33:           newmails.clear;                                        -- Clearing the new-mail-list
34:           return s + "\n";
35:        end;
36:     
37:        read_mailinglist:STR is                                   -- Reading the mailing list.
38:           s:STR := "Messages in the mailing list are:\n";
39:           loop
40:     	 s := s+ mailinglist.elt!;
41:           end;
42:           return s + "\n";
43:        end;
44:     
45:     end; -- end of MAIL
есет

2.3. The cellphone class

The cellphone class (MOBILE) inherits PHONE and MAIL.
01:     class MOBILE is                                 
02:        include PHONE init -> phone_init, create ->; -- include indicates inhelitance
03:        include MAIL  init -> mail_init, create ->;  -- Renaming the MAIL's init to mail_init and forgetting MAIL's create.
04:     
05:        create(ph,ad:STR):SAME is
06:           return new.phone_init(ph).mail_init(ad); -- Concise code using parents init methods.
07:        end;
08:     
09:     end; -- end of MOBILE

2.4. Test

Following is the test code. Download and play.
01:     class MAIN is
02:     
03:        main(av: ARRAY{STR}) is
04:           if av.size = 5 then
05:     	 mob1:MOBILE := #(av[1], av[2]);   -- Making two cellphones
06:     	 mob2:MOBILE := #(av[3], av[4]);
07:     	 mobile_test(mob1, mob2);          -- and test them.
08:           else
09:     	 #ERR + "Usage:mobile PHONE_NUMBER_1 EMAIL_ADDRESS_1 PHONE_NUMBER_2 EMAIL_ADDRES_2 \n";
10:           end;
11:        end;
12:     
13:        mobile_test(mob1, mob2:MOBILE) is
14:           #OUT + "Phone number(1) is " + mob1.get_number + "\n";          -- Showing the phone number of cellphone one.
15:           #OUT + "E-mail address(1) is " + mob1.get_address + "\n";       -- Showing the mail address of cellphone one.
16:           #OUT + "\nPhone call test (1) -> (2):\n" +                      -- Calling from cellphone one to cellphone two.
17:     	    mob1.phone_call(mob2, "Hello");
18:           #OUT + "\nE-mail transfer test (2) -> (1):\n";
19:           mob2.send(mob1, "How are you?");                                -- Sending an email message to cellphone two to cellphone one.
20:           mob2.send(mob1, "I want to see you.");                          -- Sending an email message to cellphone two to cellphone one again.
21:           #OUT + mob1.read_mail;                                          -- Cellphone one check the new mails.
22:           #OUT + "\nTest for mailing list:\n";
23:           mob1.send2mailinglist("Is Sather good?");                       -- Cellphone one submit a message to the mailing list.
24:           mob2.send2mailinglist("Yes. Sather is good.");                  -- Cellphone two also submit a message to the mailing list.
25:           #OUT + mob1.read_mailinglist + "\n";                            -- Checking the mailing list
26:        end;
27:     end; -- end of MAIN
28:     
> sacomp mobile.sa -o mobile
> ./mobile 012-222-3333 foo@ab.ne.jp 023-444-5677 bar@cd.com
Phone number(1) is 012-222-3333
E-mail address(1) is foo@ab.ne.jp

Phone call test (1) -> (2):
From: 012-222-3333
To: 023-444-5677
Subject: Hello

E-mail transfer test (2) -> (1):
foo@ab.ne.jp received following new messages:
From: bar@cd.com
Subject: How are you?
From: bar@cd.com
Subject: I want to see you.


Test for mailing list:
Messages in the mailing list are:
From: foo@ab.ne.jp
Subject: Is Sather good?
From: bar@cd.com
Subject: Yes. Sather is good.

3. Partial class

The partial class is a class that is expeted to be used only as a parent. It cannot have its own instance. It has stab parameters which should be defined in the childen classes.

Let's think abou a wireless LAN (WLAN). As the WLAN has a risk of tapping, the trafic should be encoded by using a encryption technology such as WEP and WPA.

Following code defines a partial class WLAN and two children WEP and WPA_PSK.

01:     -- an example of partical classes, WLAN
02:     
03:     partial class WLAN is
04:     
05:        stub security:STR;                -- This attribure should be defined in the children classes.
06:     
07:        get_security:STR is
08:           return security;               -- getting the attribute named security.
09:        end;
10:     
11:     end;  -- WLAN
12:     
13:     
14:     class WEP is
15:        include WLAN;
16:     
17:        const security:STR := "wep";
18:        private attr key:STR;
19:     
20:        create(k:STR):SAME is
21:           return new.init(k);
22:        end;
23:     
24:        init(k:STR):SAME is
25:           key := k;
26:           return self;
27:        end;
28:     
29:        get_key:STR is
30:           return key;
31:        end;
32:     
33:     end; -- WEP
34:     
35:     class WPA_PSK is
36:        include WLAN;
37:     
38:        const security:STR := "wpa psk";
39:        private attr key:STR;
40:     
41:        create(k:STR):SAME is
42:           return new.init(k);
43:        end;
44:     
45:        init(k:STR):SAME is
46:           key := k;
47:           return self;
48:        end;
49:     
50:        get_key:STR is
51:           return key;
52:        end;
53:     
54:     end; -- WPA_PSK
55:     
56:     
57:     
58:     class MAIN is
59:     
60:        main is
61:           wlan_test;
62:        end;
63:     
64:        wlan_test is
65:           wep0:WEP:=#("foo");
66:           wpa0:WPA_PSK:=#("bar");
67:           
68:           #OUT + "Security and key of wep0 are: " + wep0.get_security + " and \"" + wep0.get_key + "\".\n";
69:           #OUT + "Security and key of wpa0 are: " + wpa0.get_security + " and \"" + wpa0.get_key + "\".\n";
70:           
71:        end;
72:     end; -- end of MAIN
Following shows the output.
$ sacomp wlan.sa -o wlan
$ ./wlan
Security and key of wep0 are: wep and "foo".
Security and key of wpa0 are: wpa psk and "bar".

4. Summerly

I have explaind about the conventional and partial classes of Sather. The language has other class type, which I will explain in the following sections.

HOME Try Sather download Post Messages