I am a very amateur learner of Python, and I have recently started learning the concept of classes. I can understand the concept of classes (very) roughly, but I can't understand why I can't simply write some functions instead of writing a class?
For example, (I am learning from Interactive python) one of the exercise given (which I am supposed to write using a class) is :
Add a distanceFromPoint method that works similar to distanceFromOrigin except that it takes a Point as a parameter and computes the distance between that point and self.
Add a method reflect_x to Point which returns a new Point, one which is the reflection of the point about the x-axis. For example, Point(3, 5).reflect_x() is (3, -5).
They written the code using classes like this:
import math
class Point:
""" Point class for representing and manipulating x,y coordinates. """
def __init__(self, initX, initY):
""" Create a new point at the given coordinates. """
self.x = initX
self.y = initY
def getX(self):
return self.x
def getY(self):
return self.y
def distanceFromOrigin(self):
return ((self.x ** 2) + (self.y ** 2)) ** 0.5
def distanceFromPoint(self, otherP):
dx = (otherP.getX() - self.x)
dy = (otherP.getY() - self.y)
return math.sqrt(dy**2 + dx**2)
p = Point(3, 3)
q = Point(6, 7)
print(p.distanceFromPoint(q))
Why should I use class when I can write them simply like this:
def distanceFromPoint(p,q): # they are tuples
y = (p[0]-q[0])**(2)+(p[1]-q[1])**(2)
return y**(1/2)
def reflectx(p):
return (p[0],-p[1])
p = (3,3)
q = (6,7)
解决方案
One of the big advantages of using OOP is extensibility.
Let's say you'd written an application that processes lots of data in the form of points. Now your customer adds to the specification that as well as the x and y coordinate of each point, your app needs to know what colour each point is.
If you'd written your code to store each point as a tuple, (x, y), you might add the colour as a third value: (x, y, colour). But now you have to go through all of your code to find the places where it's broken because you changed the data format. If you'd used a class, you could simply define a new class that inherits from Point and adds the necessary capabilities:
class ColouredPoint(Point):
""" Class for points which are coloured, based on Point """
def __init__(self, initX, initY, initCol):
Point.__init__(self, initX, initY)
self.colour = initCol
p = ColouredPoint(3, 3, "green")
q = ColouredPoint(6, 7, "red")
r = Point(8, 4)
print(p.distanceFromPoint(q))
print(p.colour)
print(p.distanceFromPoint(r))
All your code that worked with the Point class will still work with the new class, and you can do this even if you didn't write, or can't change, the definition of the Point class.