March 29, 2024, 01:13:46 AM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


OOP Tutorial 3

Started by Parker, March 17, 2007, 12:02:23 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Parker

In the last tutorial I introduced the private and public modifiers and added methods to our CPoint class. I also talked about using Get/Set methods to access variables instead of providing public access.

In this tutorial I am going to cover inheritance by extending the CPoint class into a 3D point (CPoint3D) which contains a Z coordinate. I also intentionally left out the protected modifier from the last tutorial because it requires using inheritance, but I will explain it here. This is also the last tutorial dealing with POINT/CPoint.

I will be using the terms inherits, derives from, and extends during this tutorial. They all mean the same thing.




The concept of inheritance is one of the basic concepts of OOP. If I have two classes A and B, and B inherits A, then we can say that B is an A. This is an IS-A relationship, something commonly expressed in OOP programming. Some examples are animals: a cat IS-AN animal, a dog IS-AN animal, so we could say that the Cat class and the Dog class both extend the Animal class. Though the two have different functionality, at a lower level they are essentially the same thing - an Animal. By recognizing this, we could group some common functionality such as Walk(), Sleep(), Speak(), etc into the Animal class, but for specifics we could provide Cat with a Purr(), and Dog with a Fetch(). As long as Cat and Dog inherit from Animal, you don't have to rewrite functionality that is already there.

We're going to use inheritance to create a 3D point out of our existing 2D point. By realizing that a 3D point is a 2D point with a little extra information (another dimension), we can skip writing a 2D point altogether and just provide the extra information that we need. In EBASIC inheritance is accomplished with the , operator. That is, the statement
class Subclass, Baseclass
creates a class Subclass that derives from Baseclass. With this knowledge we can now create the definition for CPoint3D. I left out a destructor to demonstrate that it isn't necessary when you don't need it for anything. You are also not forced to provide a constructor, but we use that for something here so we can't leave that out.
class CPoint3D, CPoint
private
def z as int

public
declare CPoint3D( )

declare SetZ( int newz )
declare GetZ( ),int
end class

That was even shorter than the original CPoint definition (see below). The reason is that most of the class is already written. By extending CPoint, the new class has just inherited all of CPoint's methods and variables. Obviously we need to provide our constructor and methods for CPoint3D before the code will compile.
sub CPoint3D::CPoint3D( )
SetZ( 1 )
end sub

sub CPoint3D::SetZ( int newz )
z = newz
end sub

sub CPoint3D::GetZ( )
return z
end sub


Now that the code will compile, we can see how inheritance works. When I said before that inheritance makes one class the same as another, the compiler knows that too. That means that we can write something like this:
   CPoint3D pt
   pt.SetX( 12 )
   print pt.GetX( )

And it will compile. You may notice that I didn't set the x or y variables in the CPoint3D constructor. That is because the CPoint constructor is automatically called for us. However that is not a feature of all languages. In Java you must explicitly use the super() construct to do this, so make sure you know how your compiler works when porting code. In EBASIC though, you can safely assume that the base class constructor will be called.

There is one more thing that the compiler recognizes as a part of the IS-A relationship. Since CPoint3D IS-A CPoint, it can be passed as a parameter to functions expecting a CPoint. You can do this because CPoint3D implements the same functionality as a CPoint. Of course, the opposite is not true. Since a CPoint has less functionality than a CPoint3D, you cannot treat it as one. So inheritance only works one way.

There is one thing left that I haven't covered yet - the protected modifier. Protected is a midpoint between private and public. If you tried to modify the x or y variable inside of CPoint3D you would have noticed that the compiler won't let you. Even though CPoint3D is a CPoint and it inherits those variables, you can't access them if they are private. That is a very strict rule. No one except the class that they were defined in has access to them. In many cases private and public would be enough. If we want someone to modify our variable, we'll provide Get/Set methods, otherwise we won't. But sometimes you need the classes that inherit this class to be able to access the variable or method. For that there is protected. If you make x and y protected inside of CPoint, you will notice that CPoint3D is now able to access them, but the outside world still can't. Protected has its uses, but in many cases you can get away with just private and public, which simplify the program a little.

The final CPoint and CPoint3D classes look like this:
class CPoint
private
def x as int
def y as int

public
declare CPoint( )
declare _CPoint( )

declare SetX( int newx )
declare GetX( ),int
declare SetY( int newy )
declare GetY( ),int
end class

sub CPoint::CPoint( )
x = 1
y = 1
end sub

sub CPoint::_CPoint( )
end sub

sub CPoint::SetX( int newx )
x = newx
end sub

sub CPoint::GetX( ),int
return x
end sub

sub CPoint::SetY( int newy )
y = newy
end sub

sub CPoint::GetY( ),int
return y
end sub

''-----

class CPoint3D, CPoint
private
def z as int

public
declare CPoint3D( )

declare SetZ( int newz )
declare GetZ( ),int
end class

sub CPoint3D::CPoint3D( )
SetZ( 1 )
end sub

sub CPoint3D::SetZ( int newz )
z = newz
end sub

sub CPoint3D::GetZ( )
return z
end sub


In the next tutorial I will create new classes and explain virtual functions and overriding.

Any questions - just ask.

Jerry Muelver

Thanks, Parker. Wikified, under "Docs and Tutorials".