Difference between revisions of "W1501 Introduction to Objects"

From Coder Merlin
(44 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[[File:PDP-15 Graphics terminal with tablet CHM.agr.jpg|thumb|link=|PDP-15 Graphics Terminal with Tablet]]
== Prerequisites ==
== Prerequisites ==
* [[W1412 Constructors]]
* [[W1412 Constructors]]


== Research ==
== Background ==
* Read [[Media:ComputerScienceOne.pdf|Computer Science I Textbook by Bourke]] Chapter 10. Encapsulation & Objects
* Read [[Media:ComputerScienceOne.pdf|Computer Science I Textbook by Bourke]] Chapter 10. Encapsulation & Objects
* Review [[Media:1501_Objects.pdf|Presentation on Objects]]


== Explore ==
== Introduction ==
{{NewProject|Begin a '''new''' project.}}
=== Definitions ===
;Class:An ''extensible program-code-template'' for creating '''objects'''.
;Extensible:Something that is able to be ''extended'' by allowing the addition of new capabilities and functionality. 
;Template:Something that serves as a model for duplication. 
;Object:An instance of a class.  


Create an Igis shell project within your "project" directory.  
Classes are a useful construct to aid humans in constructing software that is sensible by enabling '''encapsulation'''.  In its most basic sense, ''encapsulation'' is the action of enclosing something in or as if in a capsule.  As it relates to computer science, ''encapsulation'' has a specific meaning, and refers to:
<syntaxhighlight lang="bash">
* '''Bundling''' related '''data''' (nouns, something that an object ''has'')
cd ~/projects
* '''Bundling''' related '''functions''' (verbs, something that an object ''does'')
git clone https://github.com/TangoGolfDigital/IgisShellD IgisShell-Introduction
* '''Protecting''' data by '''controlling visibility''' (restricting undesirable access to data and functions)
</syntaxhighlight>
 
Let's contrast this definition with that of an array:
{| class="wikitable"
! Array
! Object
|-
| '''Collection''' of similar '''elements''' || '''Group''' of dissimilar yet '''related data'''
|}
 
Consider the following table:
{| class="wikitable"
! First Name
! Last Name
! ID
! GPA
|-
| Tom || Baker || 74 || 3.75
|-
| Christopher || Eccleston || 5 || 3.5
|-
| David || Tennant || 10 || 4.0
|-
| Matt || Smith || 29 || 3.2
|}
 
In this table, a ''column'' is similar to an ''array'', a collection of similar elements:
{| class="wikitable"
! First Name
! Last Name
! ID
! GPA
|-
| Tom
| Baker
| style="background:red;" |  74
| 3.75
|-
| Christopher
| Eccleston
| style="background:red;" | 5
| 3.5
|-
| David
| Tennant
| style="background:red;" | 10
| 4.0
|-
| Matt
| Smith
| style="background:red;" | 29
| 3.2
|}
 
In the same table, a ''row'' is similar to an ''object'', a group of dissimilar yet related data:
{| class="wikitable"
! First Name
! Last Name
! ID
! GPA
|-
| Tom || Baker || 74 || 3.75
|- style="background:red;"
| Christopher || Eccleston || 5 || 3.5
|-
| David || Tennant || 10 || 4.0
|-
| Matt || Smith || 29 || 3.2
|}


Enter into the Sources directory of the new project.  
=== Swift Example ===
<syntaxhighlight lang="bash">
Closely review the below code segment.  Be sure to read each of the four numbered comments.
cd IgisShell-Introduction/Sources/IgisShellD/
</syntaxhighlight>


{{RunProgram|Run the program.
<syntaxhighlight lang="swift">
<syntaxhighlight lang="bash">
// 1. The next line defines a CLASS named Student.  Like all types, class names should be capitalized.
./run.sh
class Student {
</syntaxhighlight>}}
    let firstName : String    // 2. This section defines PROPERTIES, the DATA that an object HAS.
    let lastName : String    // |
    let id : Int              // |
    let GPA : Double          // |


    // 3. The next code segment is a CONSTRUCTOR.  It is invoked automatically to initialize the object.
    init(firstName:String, lastName:String, id:Int) {
        self.firstName = firstName
        self.lastName = lastName
        self.id = id
        self.GPA = 4.0
    }


Open a browser (or use a new tab on an already-open browser).
    // 4. The next code segment is a METHOD.  It's similar to a function but has access to the object's
Go to the URL:  http://www.codermerlin.com/users/user-name/dyn/index.html
    //   properties. It's something that an object DOES.
    func adjustGPA(newGPA:Double) {
        GPA = newGPA
    }
}
</syntaxhighlight>


NOTE: You MUST change '''user-name''' to your actual user nameFor example, http://www.codermerlin.com/users/john-williams/dyn/index.html
== Scenes ==
We'll begin our exploration of objects using {{SwiftLibrary|Scenes}}. {{SwiftLibrary|Scenes}} is an object-oriented, event-driven platform that enables us to write server-side Swift code which (rapidly) sends a series of instructions to a browser to generate visual effects, and optionally, an interactive experience{{SwiftLibrary|Scenes}} is built upon another framework called {{SwiftLibrary|Igis}}.


You'll know you're successful if you see the title bar change to "Coder Merlin: IGIS".  (The browser window will be blank because we haven't added any graphics yet.)
{{Caution|
It's important to understand that while many of the objects we'll be using have an associated ''visual'' representation, the majority of the objects that we build and interact with in programming will not have such a representation.
}}


{{hint|Helpful hint:  It's useful to bookmark this page in your browser.}}
== Prepare ==
{{ScenesShellPrepare|W1501}}


== Hello World ==
== Hello World ==
=== Text ===
{{StopProgram|Stop the running program.
{{StopProgram|Stop the running program.
<syntaxhighlight lang="bash">
Return to the ''console'' and press {{SpecialKey|CONTROL|C}}
Press ^C (Hold down the CONTROL key and press C)
}}
</syntaxhighlight>}}
 
Open the file {{Pathname|Background.swift}} in emacs.  Read through the file.  You'll find some code as follows:
<syntaxhighlight lang="swift">
class Background : RenderableEntity
</syntaxhighlight>
 
This defines a new {{SwiftKeyword|class}} named {{SwiftClass|Background}}.  The colon and the following identifier, {{SwiftClass|RenderableEntity}}, indicates that the {{SwiftKeyword|class}} {{SwiftClass|Background}} inherits properties and methods from the class {{SwiftClass|RenderableEntity}}.  You'll note that the {{SwiftKeyword|class}} includes a '''constructor''', indicated by the keyword {{SwiftKeyword|init}} on line 2:
<syntaxhighlight lang="swift" line>
class Background : RenderableEntity {
    init() {
        // Using a meaningful name can be helpful for debugging
        super.init(name:"Background")
    }
}
</syntaxhighlight>
 
The '''constructor''' is invoked automatically as the object (an '''instance''' of the class) is being initialized.  This is the place where you'll set up your object.  The current constructor in this file sets the object's name using the keywords {{SwiftKeyword|super}} and {{SwiftKeyword|init}}.  {{SwiftKeyword|super}} indicates that we're invoking a function (or accessing a property) on our '''parent''' class, the class from which we ''inherited''.  In this case, that would be the {{SwiftClass|RenderableEntity}}.
 
We're going to display some text on our ''canvas'' (the virtual surface on which we'll be rendering images in the browser).  In order to do that, we'll first declare a {{SwiftClass|Text}} object as follows:
<syntaxhighlight lang="swift" highlight="2" line>
class Background : RenderableEntity {
    let text : Text
 
    init() {
        // Using a meaningful name can be helpful for debugging
        super.init(name:"Background")
    }
}
</syntaxhighlight>
 
We'll ''initialize'' our text object in the constructor:
<syntaxhighlight lang="swift" highlight="5-6" line>
class Background : RenderableEntity {
    let text : Text


    init() {
        // Initialize objects
        text = Text(location:Point(x:50, y:50), text:"Hello, World!")


Open main.swift in emacs.
        // Using a meaningful name can be helpful for debugging
<syntaxhighlight lang="bash">
        super.init(name:"Background")
emacs main.swift
    }
}
</syntaxhighlight>
</syntaxhighlight>


Find the function within the Painter object named "setup"Add a line to create a Text object and then draw (render) that object on the "canvas", an imaginary surface for painting within the browser.
At this point, we have a {{SwiftClass|Text}} object that "knows" how to render itself on the canvas, but it hasn't yet actually done any rendering.  There are two methods in which we generally render.  The first is called {{SwiftIdentifier|setup}}.  The {{SwiftIdentifier|setup}} function executes onceIt's an opportunity to set up objects and/or render if we're creating a static (non-animated) display.  The other function is {{SwiftIdentifier|render}} which executes once per frame.  In this case, using {{SwiftIdentifier|setup}} is sufficient.
<syntaxhighlight lang="swift" highlight="2-3">
 
     func setup(canvas:Canvas) {
Add a new method (below ''init'') as follows:
        let text = Text(location:Point(x:50, y:50), text:"Hello, World!")
<syntaxhighlight lang="swift" line>
     override func setup(canvasSize:Size, canvas:Canvas) {
         canvas.render(text)
         canvas.render(text)
     }
     }
</syntaxhighlight>
</syntaxhighlight>


Remember to save the file, then suspend emacs.
This code instructs the ''text'' object to render itself on the canvas. 
 
Be sure to edit the file as indicated above, save the file, then suspend emacs.


{{RunProgram|Run the program and refresh the browser page.}}
{{RunProgram|Run the program and refresh the browser page.}}
   
   
{{Observe|
 
Section 1
{{Observe|: Section 1|
# What do you observe?
# What do you observe?
# How large is the text?}}
# How large is the text?}}


=== Font ===
{{StopProgram|Stop the running program.}}
{{StopProgram|Stop the running program.}}




Let's change the font.  Resume emacs and edit the line where the text object is instantiated.
Let's change the font.  Resume emacs and add a line below where the text object is instantiated.
 
<syntaxhighlight lang="swift" highlight="4">
    init() {
        // Initialize objects
        text = Text(location:Point(x:50, y:50), text:"Hello, World!")
        text.font = "30pt Arial"


<syntaxhighlight lang="swift" highlight="2">
        // Using a meaningful name can be helpful for debugging
    func setup(canvas:Canvas) {
         super.init(name:"Background")
         let text = Text(location:Point(x:50, y:50), text:"Hello, World!", font:"30pt Arial")
        canvas.render(text)
     }
     }
</syntaxhighlight>
</syntaxhighlight>
{{GoingDeeper|
[[File: Graphic_Coordinate_System.png|left|link=]]
You should notice that the location of the text above was specified as:<br/>
<syntaxhighlight lang="swift" inline>location:Point(x:50, y:50)</syntaxhighlight>.<br/>
This is familiar from your studies of the Cartesian plane in grade school.  However, it's important to note that for ''many'' (but not all) computer graphic platforms the y-axis is inverted, with the origin at the top-left of the screen and larger y values moving ''down'' the screen.
}}


Remember to save the file, then suspend emacs.
Remember to save the file, then suspend emacs.
{{RunProgram|Run the program and refresh the browser page.}}
{{RunProgram|Run the program and refresh the browser page.}}


{{Observe|
 
Section 2
{{Observe|: Section 2|
# What do you observe?
# What do you observe?
# How large is the text now?}}
# How large is the text now?}}


=== Rectangle ===
{{StopProgram|Stop the running program.}}
{{StopProgram|Stop the running program.}}




Let's add a rectangle around the text.  Resume emacs and add the following lines so that the entire function appears as:
Let's add a rectangle around the text.  Resume emacs and add the highlighted lines:
<syntaxhighlight lang="swift" highlight="5-7">
<syntaxhighlight lang="swift" highlight="4,11-12">
     func setup(canvas:Canvas) {
class Background : RenderableEntity {
         let text = Text(location:Point(x:50, y:50), text:"Hello, World!", font:"30pt Arial")
 
        canvas.render(text)
    let text : Text
     let rectangle : Rectangle
 
    init() {
         // Initialize objects
        text = Text(location:Point(x:50, y:50), text:"Hello, World!")
        text.font = "30pt Arial"


         let rect = Rect(topLeft:Point(x:20, y:10), size:Size(width:300, height:50))
         let rect = Rect(topLeft:Point(x:20, y:10), size:Size(width:300, height:50))
         let rectangle = Rectangle(rect:rect, fillMode:.stroke)
         rectangle = Rectangle(rect:rect, fillMode:.stroke)
         canvas.render(rectangle)
 
        // Using a meaningful name can be helpful for debugging
        super.init(name:"Background")
    }
</syntaxhighlight>
 
Then, update the following, highlighted line in the {{SwiftIdentifier|setup}} function:
<syntaxhighlight lang="swift" highlight="2">
    override func setup(canvasSize:Size, canvas:Canvas) {
         canvas.render(text, rectangle)
     }
     }
</syntaxhighlight>
</syntaxhighlight>
Line 102: Line 261:
{{RunProgram|Run the program and refresh the browser page.}}
{{RunProgram|Run the program and refresh the browser page.}}


{{Observe|
 
Section 3
{{Observe|: Section 3|
# What do you observe?
# What do you observe?
# What is the purpose of the location parameter in the Text constructor?
# What is the purpose of the location parameter in the Text constructor?
Line 109: Line 268:
# What is the difference between a Rect and a Rectangle?  Hint: Are you able to render a Rect?
# What is the difference between a Rect and a Rectangle?  Hint: Are you able to render a Rect?
}}
}}


{{StopProgram|Stop the running program.}}
{{StopProgram|Stop the running program.}}


== Exercises ==
== Exercises ==
{{Exercises|
{{W1501-Exercises}}
Making use of your accumulated knowledge to date (loops, functions, coding style, etc.) and using only Rectangles and Text on a single canvas:
 
# Draw a single rectangle (without any text)
[[Category:IGIS]]
# Draw a grid (at least 3 x 3)
# Draw a brick wall (at least 5 x 5)
# Draw a pyramid constructed of bricks (at least seven rows high)
# Draw a skyscraper with a large sign on the roof containing your name
# Draw at least three skyscrapers of different heights on the same Canvas, each containing your name
}}

Revision as of 21:19, 13 April 2021

Within these castle walls be forged Mavens of Computer Science ...
— Merlin, The Coder
PDP-15 Graphics Terminal with Tablet

Prerequisites[edit]

Background[edit]

Introduction[edit]

Definitions[edit]

Class
An extensible program-code-template for creating objects.
Extensible
Something that is able to be extended by allowing the addition of new capabilities and functionality.
Template
Something that serves as a model for duplication.
Object
An instance of a class.

Classes are a useful construct to aid humans in constructing software that is sensible by enabling encapsulation. In its most basic sense, encapsulation is the action of enclosing something in or as if in a capsule. As it relates to computer science, encapsulation has a specific meaning, and refers to:

  • Bundling related data (nouns, something that an object has)
  • Bundling related functions (verbs, something that an object does)
  • Protecting data by controlling visibility (restricting undesirable access to data and functions)

Let's contrast this definition with that of an array:

Array Object
Collection of similar elements Group of dissimilar yet related data

Consider the following table:

First Name Last Name ID GPA
Tom Baker 74 3.75
Christopher Eccleston 5 3.5
David Tennant 10 4.0
Matt Smith 29 3.2

In this table, a column is similar to an array, a collection of similar elements:

First Name Last Name ID GPA
Tom Baker 74 3.75
Christopher Eccleston 5 3.5
David Tennant 10 4.0
Matt Smith 29 3.2

In the same table, a row is similar to an object, a group of dissimilar yet related data:

First Name Last Name ID GPA
Tom Baker 74 3.75
Christopher Eccleston 5 3.5
David Tennant 10 4.0
Matt Smith 29 3.2

Swift Example[edit]

Closely review the below code segment. Be sure to read each of the four numbered comments.

// 1. The next line defines a CLASS named Student.  Like all types, class names should be capitalized.
class Student {
    let firstName : String    // 2.  This section defines PROPERTIES, the DATA that an object HAS.
    let lastName : String     // |
    let id : Int              // |
    let GPA : Double          // |

    // 3. The next code segment is a CONSTRUCTOR.  It is invoked automatically to initialize the object.
    init(firstName:String, lastName:String, id:Int) {
        self.firstName = firstName
        self.lastName = lastName
        self.id = id
        self.GPA = 4.0
    }

    // 4. The next code segment is a METHOD.  It's similar to a function but has access to the object's 
    //    properties.  It's something that an object DOES.
    func adjustGPA(newGPA:Double) {
        GPA = newGPA
    }
}

Scenes[edit]

We'll begin our exploration of objects using Scenes. Scenes is an object-oriented, event-driven platform that enables us to write server-side Swift code which (rapidly) sends a series of instructions to a browser to generate visual effects, and optionally, an interactive experience. Scenes is built upon another framework called Igis.

CautionWarnIcon.png

It's important to understand that while many of the objects we'll be using have an associated visual representation, the majority of the objects that we build and interact with in programming will not have such a representation.

Prepare[edit]

Create a new Scenes shell project within your Experiences directory:

ty-cam@codermerlin:~$  cd ~/Experiences

ty-cam@codermerlin:~/Experiences$  git clone https://github.com/TheCoderMerlin/ScenesShellBasic W1501


Enter the Sources/ScenesShell directory of the new project:

ty-cam@codermerlin:~/Experiences$  cd W1501/Sources/ScenesShell/


Start button green arrow
Run the program.

ty-cam@codermerlin:~/Experiences/W1501/Sources/ScenesShell$  run


Ensure that you are logged on to the wiki. Then, click on the Tools menu followed by right-clicking on IGIS and selecting the menu item Open in New Window or Open in New Tab.

You'll know you're successful if you see the title bar change to "Coder Merlin: IGIS". (The browser window will be blank because we haven't added any graphics yet.)

Hint.pngHelpful Hint
It's useful to bookmark this page in your browser.

Hello World[edit]

Text[edit]

Stop button red ex
Stop the running program.

Return to the console and press CONTROL-C

Open the file Background.swift in emacs. Read through the file. You'll find some code as follows:

class Background : RenderableEntity

This defines a new class named Background. The colon and the following identifier, RenderableEntity, indicates that the class Background inherits properties and methods from the class RenderableEntity. You'll note that the class includes a constructor, indicated by the keyword init on line 2:

class Background : RenderableEntity {
    init() {
        // Using a meaningful name can be helpful for debugging
        super.init(name:"Background")
    }
}

The constructor is invoked automatically as the object (an instance of the class) is being initialized. This is the place where you'll set up your object. The current constructor in this file sets the object's name using the keywords super and init. super indicates that we're invoking a function (or accessing a property) on our parent class, the class from which we inherited. In this case, that would be the RenderableEntity.

We're going to display some text on our canvas (the virtual surface on which we'll be rendering images in the browser). In order to do that, we'll first declare a Text object as follows:

class Background : RenderableEntity {
    let text : Text

    init() {
        // Using a meaningful name can be helpful for debugging
        super.init(name:"Background")
    }
}

We'll initialize our text object in the constructor:

class Background : RenderableEntity {
    let text : Text

    init() {
        // Initialize objects
        text = Text(location:Point(x:50, y:50), text:"Hello, World!")

        // Using a meaningful name can be helpful for debugging
        super.init(name:"Background")
    }
}

At this point, we have a Text object that "knows" how to render itself on the canvas, but it hasn't yet actually done any rendering. There are two methods in which we generally render. The first is called setup. The setup function executes once. It's an opportunity to set up objects and/or render if we're creating a static (non-animated) display. The other function is render which executes once per frame. In this case, using setup is sufficient.

Add a new method (below init) as follows:

    override func setup(canvasSize:Size, canvas:Canvas) {
        canvas.render(text)
    }

This code instructs the text object to render itself on the canvas.

Be sure to edit the file as indicated above, save the file, then suspend emacs.

Start button green arrow
Run the program and refresh the browser page.


ObserveObserveIcon.png
Observe, Ponder, and Journal: : Section 1
  1. What do you observe?
  2. How large is the text?

Font[edit]

Stop button red ex
Stop the running program.


Let's change the font. Resume emacs and add a line below where the text object is instantiated.

    init() {
        // Initialize objects
        text = Text(location:Point(x:50, y:50), text:"Hello, World!")
        text.font = "30pt Arial"

        // Using a meaningful name can be helpful for debugging
        super.init(name:"Background")
    }
Going DeeperGoingDeeperIcon.png
Graphic Coordinate System.png

You should notice that the location of the text above was specified as:
location:Point(x:50, y:50).
This is familiar from your studies of the Cartesian plane in grade school. However, it's important to note that for many (but not all) computer graphic platforms the y-axis is inverted, with the origin at the top-left of the screen and larger y values moving down the screen.


Remember to save the file, then suspend emacs.

Start button green arrow
Run the program and refresh the browser page.


ObserveObserveIcon.png
Observe, Ponder, and Journal: : Section 2
  1. What do you observe?
  2. How large is the text now?

Rectangle[edit]

Stop button red ex
Stop the running program.


Let's add a rectangle around the text. Resume emacs and add the highlighted lines:

class Background : RenderableEntity {

    let text : Text
    let rectangle : Rectangle

    init() {
        // Initialize objects
        text = Text(location:Point(x:50, y:50), text:"Hello, World!")
        text.font = "30pt Arial"

        let rect = Rect(topLeft:Point(x:20, y:10), size:Size(width:300, height:50))
        rectangle = Rectangle(rect:rect, fillMode:.stroke)

        // Using a meaningful name can be helpful for debugging
        super.init(name:"Background")
    }

Then, update the following, highlighted line in the setup function:

    override func setup(canvasSize:Size, canvas:Canvas) {
        canvas.render(text, rectangle)
    }

Remember to save the file, then suspend emacs.

Start button green arrow
Run the program and refresh the browser page.


ObserveObserveIcon.png
Observe, Ponder, and Journal: : Section 3
  1. What do you observe?
  2. What is the purpose of the location parameter in the Text constructor?
  3. What is the corresponding parameter named in the Rectangle?
  4. What is the difference between a Rect and a Rectangle? Hint: Are you able to render a Rect?


Stop button red ex
Stop the running program.

Exercises[edit]

Template:W1501-Exercises