Classes (OOP)
In object-oriented programming, a class is a blueprint for creating objects (a particular data structure), providing initial values for state (member variables or attributes), and implementations of behavior (member functions or methods).
The user-defined objects are created using the class
keyword. The class is a blueprint that defines a nature of a future object. An instance is a specific object created from a particular class. Classes are used to create and manage new objects and support inheritance—a key ingredient in object-oriented programming and a mechanism of reusing code.
The image above shows how a Car
object can be the template for many other Car
instances. In the image, there are three instances: polo
, mini
, and beetle
. Here, we will make a new class called Car
, that will structure a Car
object to contain information about the car’s model, the color, how many passengers it can hold, its speed, etc. A class can define types of operations, or methods, that can be performed on a Car
object. For example, the Car
class might specify an accelerate
method, which would update the speed
attribute of the car object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
A class is a way of organizing information about a type of data so a programmer can reuse elements when making multiple instances of that data type—for example, if a programmer wanted to make three instances of Car
, maybe a BMW, a Ferrari, and a Ford instance. The Car
class would allow the programmer to store similar information that is unique to each car (they are different models, and maybe different colors, etc.) and associate the appropriate information with each car.
Contents
Classes
Creating a Class
In Python, classes are declared by the keyword class
followed by the class name. A class
statement defines a new class just as a def
statement defines a new function.
The following example will define a simple class that defines Brilliant users.
1 |
|
The Constructor Method
After declaring the class name, a programmer must define a constructor method. In Python, this is denoted __init__()
. The __init__
function takes self
as the first argument, and then any number of arguments as desired by the programmer. For this example that describes Brilliant users, the programmer wants to know each user's name, age, and rating.
The name __init__()
is used for the "constructor method" for the class. While a class is a blueprint for a new data type, the programmer still needs to create values of this data type in order to have something that can store in variables or pass to functions.
When called, the constructor creates the new object, runs the code in the constructor, and returns the new object. This is what the user = brilliantUser ('Mursalin', 17, 4) line is. No matter what the class name is, the constructor is always named __init__
.
So far, we have
1 2 |
|
The above defines a method for the brilliantUsers class. Methods are used for functions that belong to a class.
Variables and the Body of the __init__
Method
To access the arguments and associate them with a particular instance of the class, within the __init__
method, create variables for each argument like this: self.variableName = variableName
.
Another component associated with classes are attributes. Attributes are characteristics of an object. The method called __init__()
is used to initialize the attributes of an object. Just as methods are functions defined in a class, attributes are variables defined in a class.
Each method in a class definition begins with a reference to the instance object. By convention, this is named 'self'.
In Python, the first parameter for methods is self
. The self
parameter is used to create member variables. Inside a class, we initialize any variables that might have different values depending on the specific instance of the class as self.VariableName
. For the car example, we might want to access the color
variable of car_1
and the color
variable of car_2
and in order to assign each car its own color
value, we need the self
.
The body of the constructor function for the example of Brilliant users is as follows:
1 2 3 |
|
This code creates member variables for the object that is created by the constructor. Member variables will begin with self
to show that they are member variables belonging to the object, and not just regular local variables in the method.
All put together, the class to describe Brilliant users looks like this:
1 2 3 4 5 6 7 8 9 10 |
|
Creating an Instance
An instance is a specific object created from a particular class. To create instances of a class, call the class using the class name and pass in whatever arguments its __init__
method accepts—in this example, the __init__
method takes name
, age
, and rating
.
1 |
|
Here we create a new instance of the brilliantUser
class. Or, in other words, we instantiate the brilliantUser
class.
Variables
Instance Variables
An instance variable is a variable that is associated with a specific instance of a class. For example, speed
can be an instance variable for a Car
object, and there can be two instances of Car
, a red car and a blue car, and each car can have its own speed. Even though the variables are named the same across instances, the values are independent and changing the speed of the blue car will not affect the speed of the red car.
Class Variables
A class variable refers to attributes that are simply variables of a class. They can be used like any other variable in that they are set when the class is created and can be updated by either method within the class or elsewhere in the main part of the program. These variables are shared among all instances of the class, and changing this variable will affect all instances of the class.
Example of using a class data attribute:
1 2 3 4 5 6 7>>> class bar(object): ... foo = 2 >>> print bar.foo 2 >>> bar.foo = bar.foo + 1 >>> print bar.foo 3
Whereas a class is a data structure definition type, an instance is a declaration of a variable of that type. Instances are essentially classes brought to life. A class
declaration basically describes a framework for what should exist. If a single general construction plan for any house is a class, an instance would be an actual specific type of house with its own attributes but still following the general structure. Even though many other OOP languages provide a new keyword in order to create an instance class, Python simply requires calling the class with parameters.
Example of creating an instance of a class:
1 2 3 4 5 6 7 8 9class House(object): def __init__(self, size, color): self.color = color self.size = size bluehouse = House(4, "blue") redhouse = House(2, "red") print bluehouse.color #Prints 'blue' print redhouse.color # Prints 'red'
What will the program output when you run
1 2 |
|
using the below code?
Try to walk through the program in your head to find the answer before you actually run the code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
What will the program output when you run
1 2 |
|
using the below code?
Try to walk through the program in your head to find the answer before you actually run the code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Object Variable Types and Scope
In object-oriented programming, methods and variables have various scope. Scope means that the method or variable may or may not be directly accessible to other objects or classes. Classes that do not have instances may be accessible to the system.
Class Scope: Class variables and class methods are associated with a class. An instance of the class (object) is not required to use these variables or methods. Class methods cannot access instance variables or methods, only class variables and methods.
Instance Scope: Instance variables and instance methods are associated with a specific object. They can access class variables and methods.
Private Scope: Private variables and private methods are only accessible to the object they are contained in. So if something goes wrong with that, there is usually only one source file to look at. If you have a million lines of code in your project, but your classes are kept small, this can reduce your bug tracking effort by a large factor.
Public Scope: Public variables and public methods are accessible outside the object they are contained in, which for practical considerations means "potentially anywhere." If something goes wrong with a public field, the culprit can be anywhere, so in order to track down the bug, you may have to look at quite a lot of code
Protected Scope: Protected variables and protected methods are accessible by the class they are in and inheriting classes (subclasses).
Encapsulation: The process of providing a public interface to interact with the object while hiding other information inside the object. Encapsulation means that the internal representation of an object is generally hidden from view outside of the object's definition. The main way that encapsulation helps reduce rippling effects of change is by keeping as many of the implementation details private to the class. By limiting the interface only to those members needed to use the class, many changes can be made to the implementation without affecting any code that uses the class.
Inheritance, Superclasses, and Overriding Methods
Inheritance is basically the idea that different classes can have similar components, and in order to avoid repeating code, inheritance is used to link parent classes to descendant classes. For example, in a fantasy story, there are heroes and monsters but both the heroes and the monsters are characters. And both dragons and orcs are monsters. Though dragons and orcs are different monsters, they share some qualities that a reader might want to know: they both have a color, they both have a size, they both have enemies. Orcs might have characteristics that dragons do not; for example, what kind of weapon does the orc carry? To allow for classes to share some key information before getting very specific into a descendant object, inheritance allows the classes to share information relevant to multiple parts of the code.
In the example of Brilliant members, Brilliant staff members and users share the some of the same characteristics of (name, age, level). Yet each also defines additional features that make them different: for staff
we may want to add salary, area of expertise, and so on.
Object-oriented programming allows classes to inherit commonly used state and behavior from other classes. In this example, staff
is the subclass of brilliantUsers
, and brilliantUsers
is a superclass of staff
.
1 2 3 4 5 |
|
What this is effectively saying is, "A staff
is the same as a user
," with some additional methods and member variables.
Inheritance allows code to be reused and reduces the complexity of a program. The derived classes (descendants) override or extend the functionality of base classes (ancestors).
Be aware, inheritance can be abused. Be certain that any change or update to the user
class would also be an acceptable update to the staff
class and every other subclass that user
has.
Inheritance describes how the attributes of parent classes are inherited by the child class. A subclass inherits attributes and methods from its parent classes.
Below is an example. Parent
is a simple class with no attributes. Child
is a class that derives from Parent
and is thus a subclass.
1 2 3 4 5class Parent(object): #Parent class pass class Child(Parent): #Child class pass
Let us create a method within Parent
that will override in its child class:
1 2 3 4 5 6 |
|
Now let us create the child class:
1 2 3 4 5 6 |
|
Overriding Methods
Although Child
inherits Parent
's fun
method, it is overridden because Child
defines its own fun
method. One reason for overriding methods is to add special and unique functionality to the subclass.
If you want to call the parent class method you overrode in your subclass, invoke an unbound parent class method, explicitly providing the instance of the subclass:
1 2 |
|
Modules
In order to avoid tedious, repetitive work, it is often necessary to work with modules/libraries/packages (depending on the language, these have different names). A module is a distinct thing that may contain a number of closely related classes. The trick is that a module is something a programmer imports into their code, and the import needs to be perfectly sensible to people who will read, maintain, and extend the software.
In Python, a module is imported using the import
statement.
1 |
|
In Python every file that ends with .py is a module.
1 2 3 4 5 6 7 8 9 10 11 |
|
Save this file as basic.py
:
1 2 3 4 5 6 7 8 9 10 11 |
|
Save this file as more.py
:
1 2 3 4 5 6 7 8 9 10 |
|
which will output
1 2 3 4 5 6 |
|
In the above example, the modules basic.py
and more.py
contained only one class each, but that need not be. Think of the import as the way to organize your code in concepts or chunks. Exactly how many classes are in each import doesn't matter. What matters is the overall organization that you're portraying with the import statements.
Note that both basic.py
and more.py
are themselves importing print_function
from python's inbuilt __future__
module. This allows us to run the same code on both python 2 and 3. It also demonstrates another way of harnessing the power of modules.
See Also
Basic Programming Pages
References
- , P. CPT-OOP-objects and classes. Retrieved June 13, 2016, from https://en.wikibooks.org/wiki/File:CPT-OOP-objects_and_classes.svg
- , P. Inheritance Roleplay. Retrieved June 13, 2016, from https://en.wikibooks.org/wiki/File:CPT-OOP-inheritance-roleplay.svg