Inheritance in Python

These are my notes on inheritance in python.

My book on Cloud Computing with Amazon. It is only $0.99 and buying it helps support my family and I. Thank you in advance.



When a class instance object is created it is allocated a unique memory address
that can be seen using the built in id() function. Python automatically performs
garbage collection to free up memory space by periodically deleting un-neded
objects such as class instances, so their memory address becomes vacat. 

Whenever an object gets assigned a new name or gets placed in a container, such
as a list, its reference count increases. Conversely, whenever these are removed
or go out of scope its count decreases. The object becomes elegible for
collection when the count is zero. 

Destorying an instance of a class may call upon a destructor to execute a _del_
method, explicitly reclaiming occupied memory space and executing any specified
statements.

The second instance created here is allocated the memory address vacated when
the first instance was deleted. 

Inheriting Features
A python class can be created as a brand new class, like those in previous
examples, or can be derived from an existing class. Importantly, a derived class
inherits members of the parent class from which it is derived, in addition to
its own members.

The ability to inherit members from a base class allows derived classes to be
created that share certain common properties, which have been defined in the
base class. For example, a 'polygon' base class may define width and height
properties that are common to all polygons. Classes of 'rectangle' and
'triangle' could be derived from the polygon class, inheriting width and height
properties, in addition to their own members defining their unique features. 

The virtue of inheritance is extremely powerful , and is the second principle of
object oriented programming.

A derived class declaration adds () parentheses after its class name specifying
the name of its parent class. 

class polygon:
    width=0
    height=0
    def set_values(self, width, height):
        polygon.width=width
        polygon.height=height

Now, create a new file that declares a derived class with a method to return
manipulated class variable values.

from polygon import *
class rectangle(polygon):
    def area(self):
        return self.width * self.height

Create another new file that declares a derived class with a method to return
manipulated class variable values.

from polygon import *
class triangle(polygon):
    def area(self):
        return(self.width * self.height) / 2

Now, start a new file making features of both derived classes available. 

from rectangle import *
from triangle import *
rect=rectangle()
trey=triangle()
rect.set_values(4,5)
trey.set_values(4,5)
print("Rectangle Area:", rect.area())
print("Triangle Area:", trey.area())

A class declaration can derive from more than one class by listing multiple base
classes in the parentheses after its name in the declaration. Don't confuse
class instances and derived instances. An instance is a copy of a class,
whjereas a derived class is a new class that inherits properties of the base
class from which it is derived.

Overriding Base Methods
A method can be declared in a derived class to override a matching method in the
base class-if both method declarations have the same name and the same number of
listed arguments. This effectively hides the base class method as it becomes
inaccessible unless it is called explicitly, using the base class name for
identification. 

Where a method in a base class supplies a default argument value this can be
used in an explcit call to the base methods, or alternative values can be
supplied by overriding methods.

The method declaration in the derived class must exactly match that in the base
class to override it. 

Polymorphism
The three cornerstones of object oriented programming are encapsulation,
inheritance, and polymorphism. Examples earlier have demonstrated how data can
be encapsulated within a python class, and how derived classes inherit the
properties of their base class. This example introduces the final cornerstone
principle of polymorphism.

The term polymorphism describes the ability to assign a different meaning or
purpose to an entity according to its context.

In python, the + character entity can be described as polymorphic because it
represents either the arithmetical addition operator or the string concatenation
operator, in the context of character operands.

Perhaps more importantly, python class methods can also be polymorphic because
the python language uses duck typing.

In a duck typing language you can create a function to take an object of any
type and call that object's methods. If the object does indeed have the call
methods they are executed, otherwise the function signals a run-time error.

Like-named methods of multiple classes can be created and instances of those
same classes will execute the associated version.

Object-oriented programming with python allows data encapsulation, inheritance,
and polymorphism. Base class methods can be overridden by like-named emthods in
derived classes. Python does not support the technique of overloading found in
other languages-in which methods of the same name can be created with different
argument lists in a single class. 

A class can have only one method-method overloading is not supported in python.

A class is a data structure prototype describing object properties with its
methods and attribute members. Each class declaration begins with the class
keyword, and is followed by an indented code block that may contain a class
document string, class variables, and class methods.

Class variables have global scope, but instance variables have only local scope.
instance variables encapsulate data securely in a class structure, and are
initialized when a class instance is created.

Properties of a class are referenced by dot notation, and are addressed
internally using the self prefix. A class instance is a copy of the prototype
that automatically calls its __init__() method when the instance is first
created.

An attribute of a class can be added, modified, or removed using dot notation or
manipulated using the built-in functions getattr(), hasattr(), and delattr().
The name of attributes automatically supplied by python begins with an
underscore character to notionally indicate privacy.

The built-in __dict__ attribute contains a namespace dictionary of class
component keys and values. Python automatically performs garbage collection, but
the del keyword can remove objects and call the class destructor. A derived
class inherits the method and attribute members of the parent base class from
which it is derived.

A method of a derived class can override a matching method of the same name in
its parent class. Python is a duck-typed language that supports polymorphism for
like-named methods of multiple classes.