Mathematica`s Object Orientation

Stephan Leibbrandt

Class, Interface, Object, This, Super, New, InstanceOf, Public, Protected, Private, Static , Override, Property, Abstract, Final, Virtual, Real

Show[
        Import["D:\\Products\\SymbolsAndNumbers\\Logo\\Mathematica\\\
SymbolsAndNumbers\\SymbolsAndNumbersNamesTransparent.bmp"], 
        ImageSize -> 300];

Application for the Class Concept: Model Editor

Needs["Class`Class`"]

Needs["ModelEditor`ModelEditor`"]

Definitions

int1  =  
        New . Integrator["Int1"] . 
          setPosition[200, 300];
inv1  =  
        New . Invertor["Inv1"] . setPosition[400, 200] . 
          rotate[3];
amp1  =  
        New . Amplifier["Amp1"] . setPosition[300, 0] . rotate[2] . 
          setFactor[a];
int2  =  
        New . Integrator["Int2"] . setPosition[100, 0] . 
          rotate[2];

Connections

int1 . connect[int2, 1, 1];
int2 . connect[amp1, 1, 1];
amp1 . connect[inv1, 1, 1];
inv1 . connect[int1, 1, 1];

Draw

ModelElement . 
        getGraphics[int1, inv1, amp1, int2];
Show[%, ImageSize -> 500, PlotRange -> All]

Equations

ModelElement . solution[int1,  int2,  amp1,  inv1]

Definitions

int1  =  
        New . Integrator["Int1"] . 
          setPosition[200, 300];
inv1  =  
        New . Invertor["Inv1"] . setPosition[400, 200] . 
          rotate[3];
amp1  =  
        New . Amplifier["Amp1"] . setPosition[300, 0] . rotate[2] . 
          setFactor[a];
int2  =  
        New . Integrator["Int2"] . setPosition[100, 0] . 
          rotate[2];
inv2  =  
        New . Invertor["Inv2"] . setPosition[500, 400] . 
          rotate[1];
amp2  =  
        New . Amplifier["Amp2"] . setPosition[300, 600] . rotate[2] . 
          setFactor[b];
add  =  New . Adder["Add"] . setPosition[0, 300];

Connections

int1 . connect[add, 1, 1];
add . connect[int2, 1, 1];
int2 . connect[amp1, 1, 1];
amp1 . connect[inv1, 1, 1];
inv1 . connect[int1, 1, 1];
inv2 . connect[int1, 1, 1];
amp2 . connect[inv2, 1, 1];
add . connect[amp2, 1, 2];

Draw

ModelElement . 
        getGraphics[int1, inv1, amp1, int2, inv2, amp2, 
          add];
Show[%, ImageSize -> 500, PlotRange -> All]

Equations

ModelElement . 
      solution[int1, inv1, amp1, int2, inv2, amp2, add, Inv1[0] == 0, 
        Inv2[0] == c, Add[0] == b*c - 1]

CreateModelEditor[]

({{Positioning, Tiers  -  Applications}, {Characteristics, Benefits}, {Basic Syntax, Class - Object}, {Abstract Data Type, Field - Method}, {Inheritance, Parent - Child}, {Encapsulation, Private - Protected - Public}, {Polymorphism, Object Context - InstanceOf}, {Planets, Source for Animation}})

Positioning

Multi Tier Concept

Get["Graphics`Arrow`"];
w = 8; h = 4; g = 4; st = "Title";
rect = {{0, 0}, {w, 0}, {w, h}, {0, h}, {0, 
            0}};
shrink = {{w/4, 0}, {-1/4*w, 0}, {-1/4*w, 0}, {w/4, 0}, {w/4, 
            0}};
Show[
        Graphics[{
{Graphics`Arrow`Arrow[{w/2, 
                  rect[[3, 2]] + g},  {w/2, rect[[3, 2]]}], 
              Line[rect], 
              Text[StyleForm["Mathematica", st], 
                Apply[Plus, Part[rect, {1, 3}]]/2,  {0, 
                  0}]}, 
rect = 
              Map[# + {0, h + g} &, 
                rect]; 
{Graphics`Arrow`Arrow[{shrink[[1, 
                        1]]/2, 
                  rect[[3, 2]] + h + 2*g},  {shrink[[1, 1]]/2, 
                  rect[[3, 2]]}], 
              Graphics`Arrow`Arrow[{w - shrink[[1, 1]]/2, 
                  rect[[3, 2]] + h + 2*g},  {w - shrink[[1, 1]]/2, 
                  rect[[3, 2]]}], 
              Graphics`Arrow`Arrow[{w/2, rect[[3, 2]] + g},  {w/2, 
                  rect[[3, 2]]}], Line[rect], 
              Text[StyleForm["Objectica", st], 
                Apply[Plus, Part[rect, {1, 3}]]/2,  {0, 
                  0}]}, 
rect = 
              Map[# + {0, h + g} &, rect] + 
                shrink; 
{Graphics`Arrow`Arrow[{w/2, 
                  rect[[3, 2]] + g},  {w/2, rect[[3, 2]]}], 
              Line[rect], 
              Text[StyleForm["Library", st], 
                Apply[Plus, Part[rect, {1, 3}]]/2,  {0, 
                  0}]}, 
rect = 
              Map[# + {0, h + g} &, rect] - shrink; 
{Line[
                rect], Text[StyleForm["Application", st], 
                Apply[Plus, Part[rect, {1, 3}]]/2,  {0, 
                  0}]}
}], 
        ImageSize -> 400];

Applications - When to Use Objectica

({{Image the Real World, \(direct\ correlation\ of\ reality\ and\ program\)}, {Hierarchical Modeling, top - down or bottom - 
            up designs}, {Similar Objects, regular structures}, {Dynamic Object Creation/
              Destruction, \(birth\ \((comet)\)\ and\ death\ \((meteoroid)\)\)}, {Who, OO - programmer}, {Subject, all subjects (technology,  physics,  
              finances,   ... )}, {Class Libraries, use and sell}, {Prototyping, Matehematica  ->  Jaca/C  #/C++}, {Model Editors, like SimuLink}})

Predecessor

({{∅ (as a general concept), \(solves\ new\ kind\ of\ problems\)}}), true OO - concept

Benefits -> Higher Productivity

({{Abstract Data Types, state and behavior  ->  
            intelligence}, {Encapsulation, information hiding}, {Inheritance, reuse functionality}, {Polymorphism, object context}, {State of the Art, modern object oriented programming}, {Clearness, easy handling of huge projects}, {Exchangeability, teamwork}, {Point of View, \(colleagues\ also\ use\ object\ orientation\  -> \ easy\ discussion\)}, {Self Explanatory, code == documentation}, {Simple Syntax, Java/C  #  –like,  
          short orientation}, {Fast Execution, overhead  <  1  ms}, {Code Protection, commercial libraries}, {Convenience, consistency checks,  global references}, {Documentation, \(user`s\ guide, \ \(\(examples\)\(\ \)\(for\)\(\ \)\(everything\)\(\ \ \)\)\)}})

Standard Package

Get["Class`Class`"]

Off[General::"spell1"]

Easy Syntax

Defitinion == constructor + state + behavior

Class[Figure] := {
Figure[kind_] := type  =  kind,
type = None,
circumference[x_] := Switch[type, "Circle", 2*Pi*x, "Square", x^2, _, 
              0]
}

Object Creation

obj = New.Figure["Circle"]

Usage

obj . circumference[5]
obj . circumference[12]

obj.type = "Square"
obj . 
      circumference[5]
obj . 
      circumference[12]

Class Concept by Example

\(Hotel\ rooms\ and\ persons . 

        Why\ not\ \(\(technical\)\(?\)\)\)

Combine State and Behavior, Class Bound

Class[Room] := {
Persons  =  {},
Book[
                persons__String]  :=  Persons  =  {persons},

Static.SpecialEquipment = {},
Price[]  :=  
              50 + Length[Persons]*20 + Length[SpecialEquipment]*10,
WriteBill[]  :=  
              First[Persons] <> ", we charge " <> 
                ToString[Price[]] <> " ..."
};

Create Object

R209  =  New . Room[];
R114  =  New . Room[];

Use

R209 . Book["Mrs. Smith"];
R114 . Book["Mr. Miller",  "Mrs. Miller"];

R209 . Price[]
R114 . Price[]

R209 . WriteBill[]
R114 . WriteBill[]

Dot, Class, New, This, Object, Finalize, Static, Property, Constant, Mutable, LockClass

Derive

Class[Single, Room] := {
Override.Static.SpecialEquipment = {"minibar"}
};

Class[Double, Room] := {
Override.Static.SpecialEquipment = {"minibar", "garage"}
};

Create Object

R209  =  New . Single[];
R114  =  New . Double[];

Reuse Functionality

R114 . Book["Mr. Smith"];
R114.WriteBill[]

Super, Override, Interface, InstanceOf, TypeOf, Abstract, Final

Problem: Privacy

R209 . Book["Mrs. Smith"];
R209 . Persons

Solution

Class[Room] := {
Private.Persons = {},
Book[
                persons__String]  :=  Persons  =  {persons},

Protected.Static.SpecialEquipment = {},
Public.Price[] := 50 + Length[Persons]*20 + 
                Length[SpecialEquipment]*10,
Public.WriteBill[] := First[Persons] <> ", we charge " <> 
                ToString[Price[]] <> " ..."
};

Use

Catch[
R209 . 
        Persons, 
Class
]

R209 . Price[]

Public, Protected, Private

Problem: Special Equipment not Recognized

R209 . 
        Book["Mr. Smith"];  
R114 . Book["Mr. Smith"];   
R209 . 
      Price[]
R114 . Price[]

Solution

Class[Room] := {
Private . Persons  =  {},
Book[
                persons__String]  :=  Persons  =  {persons},

Virtual.Protected.Static.SpecialEquipment = {},
Public . Price[]  :=  
              50 + Length[Persons]*20 + Length[SpecialEquipment]*10,
Public . WriteBill[]  :=  
              First[Persons] <> ", we charge " <> 
                ToString[Price[]] <> " ..."
};

Class[Single,  Room] := {
Virtual.Override.Static.SpecialEquipment = {"minibar"}
};

Class[Double,  Room] := {
Virtual.Override.Static.SpecialEquipment = {"minibar", "garage"}
};

R209 . Price[]
R114 . Price[]

Virtual, Real

Class

Interface[Body] := {
getPosition[_] := {0, 0, 0}
};

Class[BrightStar,Body] := {
Private . mintemp  =  0,
Private . maxtemp  =  0,
Private . period  =  0,
BrightStar[mintemperature_, 
                maxtemperature_, 
                period_]  :=  (
mintemp = 
                  mintemperature; 
                maxtemp = maxtemperature; 
This . period = 
                  period
),
Override.getPosition[_] = {0, 0, 0},
getGraphics[time_] := {AbsolutePointSize[
                      16 - #*8],  RGBColor[1, 
                          Sqrt[#], #^2] &[(mintemp + (maxtemp - 
                                  mintemp)*#)/10000],  
                    Point[getPosition[0]]} &[
                Abs[Mod[time/period, 2] - 1]]
};

Class[Satellite,Body] := {
Private . center  =  Null,
Private . distance  =  0,
Private . tilt  =  0,
Private . period  =  0,
Public . getPeriod[]  :=  period,
Satellite[ 
                center_?InstanceOf::Body,  distance_Real,  
                tilt_Real]  :=  (
This . center  =  
                  center; 
This . distance  =  
                  distance;  
                period  =  
                  distance^1.5; 
This . 
                    tilt  =  {Sin[tilt*Degree], 0, 
                    Cos[tilt*Degree]}; 
),
Private . 
                getParentPosition[time_]  :=  center . getPosition[time],
Override.getPosition[time_] := Block[{rot,  ϕ  =  
                    If[period == 0, 0, 
                      time/period*2*π]}, 
rot  =  
                  Outer[Times, tilt, 
                      tilt] + (IdentityMatrix[3] - 
                          Outer[Times, tilt, tilt])*Cos[ϕ] + 
                    Map[Cross[tilt, #] &, -IdentityMatrix[3]]*
                      Sin[ϕ]; 
getParentPosition[
                    time]  +  
                  rot . {distance, 0, 0}
],
getGraphics[time_] := {Point[getPosition[time]],  
                Line[{getParentPosition[time], getPosition[time]}]}
};

Class[Planet, Satellite] := {
Private . atmosphere  =  GrayLevel[0],
Private . circle  =  {},
Planet[ center_?InstanceOf::Body,  
                distance_Real,  tilt_Real,  
                atmosphere_]  :=  (
Super[center, 
                  distance, tilt]; 
circle  =  
                  Line[Table[
                      getPosition[time],  {time, 0,  getPeriod[],  
                        getPeriod[]/20}]]; 
This . 
                    atmosphere  =  
                  RGBColor[0, atmosphere^(1/4), 
                    Sqrt[atmosphere]]
),
Override.getGraphics[time_] := {circle,  Last[#],  AbsolutePointSize[5],  
                    atmosphere,  First[#]} &[
                Super . getGraphics[time]]
};

Planets and Moons

sun  =  
        New . BrightStar[2000, 8000,  
            500.0^1.5/4];
planet1  =  
        New . Planet[sun,  500.0,  -10.0,  
            0.3];
planet2  =  
        New . Planet[sun,  2^(2/3)*500.0,  0.0,  
            0.8];
moon11  =  
        New . Satellite[planet1,  75.0,  3.0];
moon12  =  
        New . Satellite[planet1,  125.0,  -3.0];

Draw

Timing[
steps  =  100;
objects  =  {sun,  planet1,  moon11,  
            moon12,  planet2};
longest  =  
          Max[Map[# . getPeriod[] &, Drop[objects, 1]]];
gr = Table[Graphics3D[
                Join[{AbsolutePointSize[5]},  
                  Map[# . getGraphics[time] &,  objects]]], {time, 0, longest - longest/2/steps, longest/steps}];
plrange  =  
          Map[{Min[#], Max[#]} &, 
            Transpose[
              Extract[gr, Map[Append[#, 1] &, Position[gr, _Point]]]]];
Map[
          Show[#, PlotRange -> plrange,  Boxed -> False,  
              Background -> GrayLevel[1]] &, gr]
]

({{Objectica, }})

({{({{Industry, 840 € + tax, single user}, {Education, 840 € + tax, staff (max 30) + 
                  students}, {Professorship, 560 € + 
                  tax, staff (max 30)}, {University, 280 € + tax, single user}, {Student, 28 € + tax, single user}})}, {\(\(→\)\(\ \)\(Special\ \(\(Conference\)\(\ \)\) \(Offer : \(\(\(-20\) %\)\(\ \)\(←\)\)\)\)\)}})

({{Ringstraße 100, Tel  + 49/241/
                566 08 28}, {52078 Aachen,  }, {Germany, sales@symbols - and - numbers . com}})