text: When last we talked, we had a Button class that could be used to quickly create a button of a certain style. However, I also asked you to ignore certain aspects of the code. We're going to start this session off with a little resolution: it's time to explain what
  extends does.
  Over the course of this tutorial, we'll expand that Button class, gain a deeper understanding of what's actually going on, and learn a few more Object-Oriented Programming terms and techniques, namely inheritance. The Button class will get better and more useful.
  Step 1: Inheritance
  One of the powerful features of OOP is inheritance. First things first, that's inheritance in the sense of genealogy, not inheritance in the sense of receiving sums of money from a deceased uncle.
  In a nutshell, inheritance enables a given class to take an existing class and do everything that it can do, but with modifications and/or additions. In other words, suppose class
  A does two things, called
  foo and
  bar. If class
  B inherits from
  A, then it will automatically also do
  foo and
  bar.
  B can also then define an extra thing it can do, called
  baz. It can also choose to still do something called
  bar, but change the internal behavior a bit.
  A practical illustration will help explain this.
  Step 2: E.g: The DisplayObject
  In ActionScript 3, there is a class named DisplayObject. This class defines properties and methods relevant to any visual element:
  x and
  y,
  width and
  height,
  alpha,
  filters,
  mask,
  rotation,
  getBounds(),
  hitTestPoint(), etc (see the documentation for a full list). Essentially, any task appropriate for all types of displayable objects are defined here.
  There are a number of classes that extend
  DisplayObject. One of these is Shape. All that
  Shape does is define a
  graphics property, which enables programmatic vector drawing. Basically,
  Shape is a displayable object that specializes in vector graphics. And because
  Shape extends
  DisplayObject, it inherits all of those other, more general properties and methods, and a
  Shape is said to be a kind of
  DisplayObject (see the documentation for the
  Shape class).
  Another subclass of
  DisplayObject is Bitmap.
  Bitmap is sort of the pixel analog of
  Shape; it merely adds a few properties relevant to work with bitmaps (pixels) with ActionScript. Again, though, because it extends
  DisplayObject it can also be positioned, rotated, filtered, hit-tested, etc, just like
  DisplayObject, and thus
  Bitmap is said to be another kind of
  DisplayObject (see the documentation for the
  Bitmap class).
  What's more, a third class that inherits from
  DisplayObject is InteractiveObject. With
  InteractiveObject, there are half-a-dozen properties added pertaining to context menus, keyboard navigation, mouse enablement. The big thing
  InteractiveObject adds is a whole slew of events that it is capable of dispatching, from mouse rollovers to keyboard focus to any kind of possible user input. And, once again, an
  InteractiveObject is a kind of DisplayObject and so it can also be positioned, et al (documentation for the
  InteractiveObject class).
  The following graph shows the relationships of the various classes we just discussed (along with one we haven't: Video. Hopefully the purpose of this class is obvious).
  In a graph such as this, a line with an arrowhead at one end indicates an inheritance relationship. The box with the tail of the arrow is the class that extends the box with the head of the arrow.
  Step 3: The Inheritance Structure
  At this point, we've looked at four classes: one superclass, and three of its subclasses. Note that while all three subclasses share some common functionality (position, rotation, etc.), all of the overlap is defined in
  DisplayObject. The
  Shape has a
  graphics property,
  Bitmap has a
  bitmapData property, and
  InteractiveObject dispatches a
  rollOver event, and those are unique to those classes. A
  Bitmap can't be programmatically drawn into, and a
  Shape can't dispatch a
  rollOver event.
  This is a common use for inheritance: to consolidate functionality that is common to a family of classes. All of these display objects need to be positioned, so rather than putting positioning code in each of the classes, Adobe put the code in a super class from which the all other display objects can inherit.
  The list goes on:
  InteractiveObject has subclasses of its own. TextField is an impressive class that extends
  InteractiveObject but also adds many properties and methods dealing with setting, getting, and styling text. Not only does it extend
  InteractiveObject, and therefore inherits all of the events and things defined there, but it (indirectly) inherits from
  DisplayObject, so it too can be positioned, rotated, etc. That functionality continues down the family tree (see documentation for the
  TextField class).
  Another class called DisplayObjectContainer is also a subclass of
  InteractiveObject, and it adds functionality for managing other display objects that can be contained within another display object, like
  addChild() and
  swapChildren() (
  child being the general term used for a display object that is contained by another display object) (see documentation for the
  DisplayObjectContainer class). Furthermore, Sprite extends
  InteractiveObject, adding dragging capabilities along with some interactivity conveniences and a
  graphics object (see documentation for the
  Sprite class).
  The following image illustrates the entire inheritance tree as we've discussed to far.
  Step 4: The MovieClip as Example
  And last but not least, MovieClip extends Sprite, defining the ability to work with the timeline (with properties like currentFrame and methods like
  play() and
  gotoAndStop()). By the time we get to MovieClip, it has a lineage that goes up through Sprite to
  DisplayObjectContainer to
  InteractiveObject to
  DisplayObject, thus making it capable of:
  - Position, rotation, filters, and hit tests (thanks to
  DisplayObject)
  - Dealing with interactivity, namely dispatching events related to user input (thanks to
  InteractiveObject)
  - Containing other display objects (thanks to
  DisplayObjectContainer)
  - Working with dragging and being drawn into (thanks to
  Sprite)
  - Managing its timeline (thanks to
  MovieClipitself)
  That's a lot of functionality, but the hierarchy of inheritance for all display objects enables a lot of code reuse, so really MovieClip isn't adding all that much to the table. It's just the next logical step for adding features (see documentation for the
  MovieClip class).
  It's also worth noting that
  DisplayObject is itself a subclass: it extends EventDispatcher so that it's capable of dispatching events and working with the standard AS3 event model.
  MovieClip has quite a heritage.
  For an overview on Flash's display list, please see Adobe's documentation page on Display Programming, as well as my previous tutorial covering the display list.
  The following illustration summarizes the hierarchy of inheritance that we've discussed in the previous three steps, also adding a few classes we haven't talked about:
  Note that this illustration is not comprehensive; there are incomplete lists of properties and methods, and in fact there are entire classes missing. The purpose is to provide a compact representation of the extensive
  DisplayObject hierarchy.
  Step 5: Extending MovieClip
  So, when we write this:
  public class Button101 extends MovieClip
  We're saying that the class we're writing will actually merely define the extra properties and methods that we'll sort of graft on the existing
  MovieClip class. That is,
  Button101 is a
  MovieClip, only with a little extra built-in capability.
  In the end, that means that from within the
  Button101 class, we can use
  DisplayObject properties and methods as if we wrote them ourselves, like we do here:
  bgd = new Shape(); bgd.graphics.beginFill(0x999999, 1); bgd.graphics.drawRect(0, 0, 200, 50); addChild(bgd);
  That
  addChild() method is defined by
  DisplayObjectContainer, but ultimately we inherit from
  DisplayObjectContainer so we can use it.
  Similarly, any bit of code that uses a
  Button101 object can basically treat it like any other display object, like we do here, in
  DocumentClass:
  button = new Button101(); button.x = 10; button.y = 200; addChild(button);
  So, when we create the
  Button101 object, we can think of it as just a specialized
  MovieClip. It's not unlike how you create specialized
  MovieClips in the Flash IDE and store the symbols in the library. The only real difference is that in that case, you use the graphical tools instead of writing a bunch of code.
  In fact, the double whammy here is that
  DocumentClass itself extends
  MovieClip, and so it too inherits all of these methods and properties, which is how we have access to an
  addChild() method in the first place.
  (Note that you can combine those two approaches and write some custom code that is linked to a symbol in the library, but we won't address that technique in this tutorial.)
  Step 6: Now What?
  OK, that was quite a bit of theory, so take a quick breather if you need it. The point is to come to grips with the terminology and techniques, but not necessarily master it in one go. Object-Oriented Programming is a significant mental leap, so don't expect it all to sink in right away.
  In fact, if you need to, just stop reading right now and come back to this after your head stops spinning. Or even re-read the previous several steps to make sure you've got it.
  Even if you're ready to move on right now, the sole purpose of this step is to not think so much...
  Carry on when you're ready.
  Step 7: Mapping a Button to an Action
  Right now, our two buttons both have their
  CLICK events handled by the same method in the document class. Sometimes it's useful to have two buttons do the same thing to give the user a few choices, but most often different buttons do different things. How can we set up multiple actions for multiple buttons?
  There are a few approaches to this problem, and I'll outline a few.
  Step 8: Option 1 Multiple Event Handlers
  First, and probably the most obvious, is to simply set up a second event handling method. For instance (code abbreviated to focus on the relevant bits...feel free to integrate into your working project to test it out, but for the purposes of continuing tutorial this isn't officially code to enter into the document class):
  button.addEventListener(MouseEvent.CLICK, onButton1Click); button2.addEventListener(MouseEvent.CLICK, onButton2Click); // ... private function onButton1Click(e:MouseEvent):void { trace("Button 1 was clicked"); } private function onButton2Click(e:MouseEvent):void { trace("Button 2 was clicked"); }
  This is probably the most common solution to this situation, especially when two buttons perform rather disparate functions. When one button opens an informational overlay, and another purchases a product, it makes sense to do what probably comes naturally and make separate functions.
  Step 9: Option 2 Switch/Case
  However, when buttons perform very similar functions, such as multiple product thumbnails needing to open up a product detail, just with different content, then making multiple handlers can be tedious at best, and can lead to hard-to-manage code at worst. In this case, it's probably be better to utilize a conditional statement or a Dictionary (see AS3 101 - Branching for more in-depth discussions of both of these techniques).
  button.addEventListener(MouseEvent.CLICK, onButtonClick); button2.addEventListener(MouseEvent.CLICK, onButtonClick); // ... private function onButtonClick(e:MouseEvent):void { switch (e.target) { case button: trace("Button 1 was clicked"); break; case button2: trace("Button 2 was clicked"); break; } }
  If the thumbnails were dynamically generated (using external data and a loop...see AS3 101 - Loops and AS3 101 - XML), that makes it darn near impossible to create a unique event handler for each button, and even makes it pretty hard to pull off the above trick (although a
  Dictionary would work well).
  Step 10: Option 3 Objects That Store Data
  However, there is another option that starts to become attractive as OOP techniques are utilized. It's a step further than the last option; instead of comparing the event target to a known list of possible targets, we simply ask the target for the relevant piece of information.
  Without any further modification to the
  Button101 class, we can illustrate this rather simply. Suppose in our trace message, it was our goal to output the
  x position of the button that was clicked, something like this:
  The button that was clicked has an x value of 10
  We can do that very easily by simply referencing the
  x property of the
  target itself.
  private function onButtonClick(e:MouseEvent):void { trace("The button that was clicked has an x value of " + e.target.x); }
  Check that out, one line! No need for dictionaries,
  switch statements or multiple, near-identical event handlers.
  Remember that excessively long discussion about inheritance? Of course you do. Because
  e.target is a
  Button101 object, and because a
  Button101 object is ultimately a
  DisplayObject, we have an
  x property, even though we never defined that property in our
  Button101 class.
  This becomes even more powerful when we realize we can create custom properties on the
  Button101 class (or any custom class) in which its objects can store data. Suppose that, for instance, instead of the
  x value of the button, we wanted to navigate to one URL or another. And if each button instance had its own URL data stored in a
  url property, we can handle the execution of the click very easily.
  If you're thinking that this could be as simple as:
  private function onButtonClick(e:MouseEvent):void { navigateToURL(new URLRequest(e.target.url)); }
  Then you're correct. However, to get that
  url property to exist in the first place, we have some work to do in the
  Button101 class. And before we do that, we need to talk about access modifiers.
  Step 11: Public Access
  The time has come to address these
  public and
  private words I've been telling you to ignore (finally!). These are called access modifiers and define how a property or method can be accessed (or not) from other parts of the program.
  There are four modifiers:
  - private
  - protected
  - internal
  - public
  The order of that list is intentional; the amount of access increases as we go down the list. Here's a quick run down of the access types:
  private is the least accessible. The only object that will be able to access a private property or method is the one that owns it. For example, the two properties of
  Button101,
  label and
  bgd, are
  private, and so the only object that can work with those items is the
  Button101 instance itself. Note than even two instances of the same class have mutually exclusive access to their own private properties;
  button can access its
  label property, but it can't access
  button2's
  label property, and vice versa.
  protected is very similar to
  private, only that it allows any subclass to also access the property or method. So if we created a subclass of
  Button101, that subclass would not be able to access the
  label or
  bgd properties (because they are private), but could access another property that was defined as protected.
  internal expands the accessibility a little more. It grants access to any other object that is in the same
  package as the class. This one is used far less that the others and only really makes sense once you understand packages, so we won't be revisiting this one. Note, however, that
  internal is the default access if you forget to specify (don't ask me why).
  public is the most accessible. Basically, any object can access the property or method. If another object has access to a
  Button101 object, then it can call the
  setLabel() method.
  ActionScript 3 will enforce these rules. If you make a property private and then try to access it from a subclass, then the compiler will complain and you'll get an error message. The idea is that you set the rules down as you craft your class ("this should be accessible, that shouldn't") and then you need to stick to them.
  Step 12: Make a private _url property
  In Button101, declare a third property,
  _url, to hold a URL string.
  private var _url:String;
  What's up with the underscore? This is a convention that I've been glossing over until we've had a discussion on access modifiers. It's not required, but it's quite common to declare your private and protected properties with names that begin with underscores. Part of this has to do with convention, part to do with being able to recognize at a glance an object property versus a local function variable (remember scope?), and a lot to do with the topic of the next step.
  I would advise you to read up on this Quick Tip on how to choose an access modifier for your properties and methods. In a nutshell, though, the main takeaway is to always declare properties as
  private or possibly
  protected, so as to make sure they don't get changed without the object's approval. However, we still need a way to access the data, and this is where setters and getters come in.
  Step 13: Setters and Getters
  OK, so you have a private property, and you'd like to make it public. You could just change the "
  private" to "
  public" and be done with it, except you recall some crotchety tutorial author telling you to never do that. What do you do? You use setters and/or getters.
  Setters and getters are, simply put, methods that either set the value of some property, or get the value of some property. There are two kinds of setter/getter methods to keep in mind: implicit and explicit.
  Explicit setters/getters are what you're probably already thinking they are: regular old methods. Given a private property "
  _url" of type
  String, a setter might look like this:
  public function setUrl(theUrl:String):void { _url = theUrl; }
  And a getter might look like this:
  public function getUrl():String { return _url; }
  Note that the setter receives a single parameter of the same type as the property, simply sets the property's value to that incoming value, and returns nothing. The property is set, and that's it.
  Similarly, the getter does a single thing: it returns the value held by the property, and takes no arguments.
  To use these, you'd simply call them like any other method. If we had an instance of this object in the variable
  button we could do this:
  button.setUrl(""); trace(button.getUrl()); //traces ''
  And that should not be a surprise. So why am I going into so much detail on this topic? Because of the implicit setters/getters.
  Most OOP languages afford this capability, and ActionScript 3 does so with the set and get keywords. These are extra modifiers you place in your method declaration that makes these method implicit setters and getters. We'll get to what that means in a second, but for now, add this setter to the
  Button101 class:
  public function set url(theUrl:String):void { _url = theUrl; }
  Notice it looks pretty darn close to the previous setter, only the word "
  set" is out there by itself, between the word "
  function" and the name of the function. This is a subtle detail; the word "
  set" is not part of the function name. It's an extra keyword that turns a method into an implicit setter. Otherwise, though, it's purpose should be obvious.
  Next, add this getter:
  public function get url():String { return _url; }
  Again, it's almost identical to the previous getter, only with the "
  get" keyword in between the "
  function" keyword and the function name (if you added the previous explicit examples, please remove them to prevent confusion).
  Now, here's where things get interesting. Back in the DocumentClass, let's set the url, and then we'll trace it right away to (a) make sure it worked, and (b) see what using an implicit getter looks like.
  At the end of the constructor, after both buttons have been created, add the following lines:
  button.url = ""; button2.url = ""; trace(button.url); trace(button2.url);
  That's a significant difference; it looks like you're working with a property, not a method! That's the magic of implicit setters and getters. They take a method and make it look like a property. Working with it is just like setting or getting the property, but inside the class we have a function.
  Now, why go to this trouble? There are, naturally, a few compelling reasons, a few of which we'll explore in the next few steps as we add more setters and getters.
  Step 14: Get the URL
  Let's go back to the original problem of knowing what to do when a button is clicked. Earlier, I mentioned that could go in the document class; let's make that a reality.
  In DocumentClass.as, update your onButtonClick() method to look like this:
  private function onButtonClick(e:MouseEvent):void { navigateToURL(new URLRequest(e.target.url)); }
  And in the constructor, make sure the url properties are set on both buttons, but go ahead and remove the traces:
  button.url = ""; button2.url = ""; //trace(button.url); //trace(button2.url);
  Finally, you'll need to add the following import line at the beginning:
  import flash.net.*;
  For reference, the complete
  DocumentClass should look like this:
  package { import flash.display. MovieClip; import flash.text.TextField; import flash.events.MouseEvent; import flash.net.*; public class DocumentClass extends MovieClip { private var tf:TextField; private var button:Button101; private var button2:Button101; public function DocumentClass() { tf = new TextField(); addChild(tf); tf.text = "Hello World"; button = new Button101(); button.x = 10; button.y = 200; button.setLabel("Button 1"); button.url = ""; addChild(button); button.addEventListener(MouseEvent.CLICK, onButtonClick); button2 = new Button101(); button2.x = 220; button2.y = 200; button2.setLabel("Button 2"); button2.url = ""; addChild(button2); button2.addEventListener(MouseEvent.CLICK, onButtonClick); } private function onButtonClick(e:MouseEvent):void { navigateToURL(new URLRequest(e.target.url)); } } }
  And just to be sure, here is the complete
  Button101 class:
  package { import flash.display.Shape; import flash.display.Sprite; import flash.events.MouseEvent; import flash.text.TextField; import flash.text.TextFormat; public class Button101 extends Sprite { private var bgd:Shape; private var labelField:TextField; private var _url:String;; } public function set url(theUrl:String):void { if (theUrl.indexOf("http://") == -1) { theUrl = "http://" + theUrl; } _url = theUrl; } public function get url():String { return _url; } } }
  Go ahead and try it out. Clicking on the buttons will take you to one of two web pages.
  Step 15: Setting and Getting the Label
  Another reason to roll with setters and getters is the ability to make a complex task simple to execute. For example, let's add the ability to update the label using a setter. We actually already did this in the previous tutorial, but we didn't use the term setter. We'll update the existing setter to be implicit and add a getter.
  In Button101, you'll see this method:
  public function setLabel(label:String):void { labelField.text = label; }
  Remove that, and add this:
  public function set label(text:String):void { labelField.text = text; } public function get label():String { return labelField.text; }
  This lets us, from elsewhere in the program, work with a "label property" that simply sets the label text of the button. What's really going on behind the scenes, though, is a little more complicated; you need to work with a
  TextField and a
  String, not just a
  String.
  This is encapsulation again. You might think, "why not just make the
  labelField property public -- or, OK, make a setter and getter for the
  labelField -- and then do something like
  button.labelField.text = "Button 1" ?"
  That would certainly work, but do you really need to expose the
  labelField to the rest of the world? Assuming that the general style of the button is set in stone, there's really no need to work with that
  TextField outside of the
  Button101 class, except to set the label text. Exposing the
  labelField would allow another object to not only set the text, but to also position, rotate, style, or even hide the label. This is probably not desirable; even if you're a good citizen and wouldn't intentionally write code that does that, it's better to protect yourself from accidental changes. Let the compiler warn you if tried a stunt like that, as opposed to letting the application run and having your label mysteriously rotated.
  In DocumentClass, make sure to change the lines that call
  setLabel to
  label = :
  button.label = "Active Tuts"; button2.label = "Search";
  Step 16: Adjusting the Width and Height with Overrides
  We'll examine another argument in favor of the setter. We might want to adjust the width or height of the button. Since the button class extends
  MovieClip, it already has
  width and
  height properties, which is handy, except it's not quite what we want. Check out what happens if we set it:
  The above SWF was the result of setting the
  height property of the left-hand button object to
  100. If you want to try this yourself, just add the following line at the end of the constructor of your
  DocumentClass:
  button.height = 100;
  Now, this isn't terrible, but I would argue that it's undesirable. It's happening because this is the default behavior for scaling
  MovieClips (and all
  DisplayObjects, actually, since
  height is defined in
  DisplayObject). It's merely a linear stretching of the artwork contained within, text fields included. The text at least is not distorting, but its size is disconcerting.
  We can write our own method to set the width, such as
  public function setWidth(), but there's an even better way. We can override the behavior of a method defined in a superclass. We can, as a subclass, actually fine-tune the functionality to our needs by changing the definition of what an existing method does. It looks like this:
  override public function set width(w:Number):void { // Custom code here. } override public function set height(h:Number):void { // Custom code here. }
  It's a standard method declaration, except with an extra keyword at the front:
  override. Note that the order of "
  public" and "
  override" is actually interchangeable, but most code I've seen tends to put the "
  override" word first. It doesn't matter, but it's advisable to pick a standard for yourself (or your company) and stick with it.
  Let's add some functionality. Keep in mind that we are completely replacing the existing
  set width method, so we need to make sure we cover all the bases. As it turns out, it's fairly simple. Instead of stretching the main
  MovieClip container, and all of the children within it by default, we'll actually stretch each of the children individually. It's almost strange that it works, but it does:
  override public function set width(w:Number):void { labelField.width = w; bgd.width = w; } override public function set height(h:Number):void { labelField.height = h; labelField.y = (h - labelField.textHeight) / 2 - 3 bgd.height = h; }
  By setting the width and height of the text field explicitly, we avoid the awkward text scaling. We can also add in a line of logic to reposition the
  label
  TextField so that it remains vertically centered.
  Note that we are not writing a getter; the behavior defined by
  DisplayObject is just fine, and there is no need to override it.
  To try it out, simply add (or keep) the line that sets the button's height to 100 pixels in the
  DocumentClass.
  There are a number of other reasons why you'd want to start using setters and getters. I've listed five of them here.
  Step 17: Adjusting the Width Automatically
  One last item on the setter technique. Here's the goal: to make the button automatically expand in width if the label is too long. So, if you set the label to "Button 1", there is plenty of space, and the text is nicely centered. But if you were to set the label to "Press This Button To Hack the Gibson," that would be too long, and the text would get truncated.
  This sort of behavior is quite easy to manage with the use of a setter. When setting the label text, you can also do a little post-processing on the text field and background to make sure they are sized appropriately. Rework your label setter so that it looks like this:
  public function set label(text:String):void { labelField.text = text; var autoWidth:Number = Math.max(200, labelField.textWidth + 40); this.width = autoWidth; }
  The logic is relatively straightforward, but here's a rundown in case you haven't done this sort of thing before. First, we figure out what the width should be. By using the
  Math.max() function, we can pass in two numbers and get the higher one back. One of those numbers is
  200, which I'm defining as our minimum width. The other number is the width of the text in the text field, plus a 40 pixel margin (20 pixels on either side). So if the text width is small, we'll get
  200 back and even with a short label we'll have a 200-pixel-wide button. If the text width is large, however, we'll get the text width (plus a margin) back, and then we'll use that value instead.
  We finally simply set the width of the button to this value, calling the setter we just wrote in the last step. Try it out by setting the label of the second button to an unusually long bit of text:
  button2.label = "Press This Button To Hack the Gibson";
  Of course, the actual logic you take here could be any number of things. You might find it more useful to implement a "
  minimumWidth" property that specifies the minimum number of pixels (instead of
  200), or an "
  autoFit" property that signals whether or not to adjust the width automatically, to make the
  Button101 a little more flexible. I leave these options to the reader as further exercises.
  But those options bring up a good point. Adding the necessary code to implement such features will start to make your class more complex. That in itself isn't really a bad thing, but it does herald the truth that the more features you have, the more complex your code. One of the hallmarks of good Object-Oriented Programming is that complexity lies in the ways in which several objects are connected together, not in the logic of a single class. Some classes will be, by necessity, rather complex, but as a rule, more and smaller classes are preferable over fewer and larger classes.
  Take the aforementioned
  DisplayObject hierarchy as an example. The
  MovieClip class (or
  Button101 class, for that matter) is in itself rather complex, given that it can dispatch events, position itself, handle interactivity, contain other DisplayObjects, be dragged, and manage a timeline, but remember that a vast majority of that complexity is defined by classes other than
  MovieClip. Remember, everything other than the timeline-related stuff is defined in a super class. The
  DisplayObject hierarchy is a rather well-thought out system of classes, each one taking on the responsibility of a focused task.
  This is a point that's difficult to execute well, so I just want to mention it, plant that seed, and hopefully seep into your sub-conscience for a more opportune time.
  Summary
  In this installment, we took a long hard look at primarily two things: inheritance; and setters and getters.
  Inheritance is the mechanism by which one class can leverage most everything already defined in another class, but sub-classing it. The subclass can then add more functionality or even redefine existing functionality via overrides.
  Setters and getters are any method than can be used to access a private property. Implicit setters and getters look like properties themselves, but are really special methods. They can be useful for controlling access and performing validation, or executing more complex logic behind the simple setting of a property.
  There is still much to learn on this topic, so stick around for the forthcoming Part 3. You're doing great, and thank you for sticking it out this far!
  Envato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!Translate this post
  