Hello everyone
I am now at the Abstraction part of the OOP.
To be honest, CodeCademy’s explanation and implementation is horrible and I just cannot understand anything for that concept.
I don’t understand what Abstraction is, why should I use it or what it is of use to me
I would be appreciative for an explanation because I am truly lost right now.
Hi,
Abstraction is where you only deal with relevant details and hide the rest. It’s sort of the other side of Encapsulation.
So, whereas encapsulation is bundling stuff together and hiding it away. abstraction is allowing access to only the relevant data.
For example, say you have a car racing game and each different car was an instance of the Car class.
It could have a method that gets called when you press accelerate. All that method needs to know is ‘player presses accelerate, increase speed by this much’ and that would be the same no matter the type of car.
It doesn’t and shouldn’t need to know any other details about the car.
You can then apply the same method no matter the type of car (sports, truck, etc) and know it’ll respond in the same way for each - e.g. it wouldn’t suddenly break if you applied it to a car with 3 wheels, because that’s a detail it doesn’t know or care about.
Hope that’s helped a bit, but to be honest it took me a while to get it.
It may be useful to consider a functional type of abstraction. Consider,
def df(a=-9.81):
'''
displacement due to acceleration as a function of time and initial velocity
'''
def f(t,v=0):
return v + a / 2 * t ** 2 # in the absence of friction with air
return f
>>> dg = df()
>>> dg(10)
-490.5
>>> dg(1)
-4.905
A function factory is a function that returns a function with closure around the parameters of the parent function. Notice above we call df()
with no arguments. That is because it has a default parameter. We can overwrite it if we want a different acceleration in our return function. The default is acceleration due to gravity, which is a vector downwards, so has a negative value.
The returned function has that value tucked away as a constant so that we never need to provide it when we use that function. As well, our return function also presets initial velocity to zero, as though dropped from a height. Drop a ball from the roof of a bungalow and it will take about 1 second to hit the ground.
Our returned function only needs one input, time in seconds. We can include an initial velocity. This is perhaps a complicated example, but study it to get a grasp on how abstraction can be used in programming to simplify operations. The term is rather general, as there are multiple uses of abstraction, especially in D. R. Y. code.
Disclaimer: The above response by @pluginmaybe is completely notwithstanding. This is just a different example.
It is still new to me, but from my point of view a “template class” might be a better name.
For example, if I want to define a class that finds the perimeter and area of planar objects such as a square, circle, trapezoid….
I’ll make a Geo class that can convert centimeters to meters and return the perimeter and area of a rectangle.
But then I want want a class that does the same thing for a circle. I can inherit from the Geo class and create new definitions for perimeter and area, like this. (centimeters to meters stays the same.)
class Geo():
def cm_to_m(self,x):
return x/100
def perimeter(self,a,b):
return 2a+2b
def area(self,a,b):
return a*b
class Circle(Geo):
def perimeter(self,r):
return 23.14r
def area(self,r):
return 3.14rr
rect=Geo()
print(rect.perimeter(2,3))
print(rect.area(2,3))
circ=Circle()
print(circ.perimeter(3))
print(circ.area(3))
I could then go on to do the same thing for other planar shapes. Like a square or hexagon…
But what was the use in even defining perimeter and area (in Geo) in the first place if I have to keep redefining them? So I’ll make Geo an abstract class. I won’t even specify the code for perimeter and area. All my planar classes (rectangle, square, circle, hexagon…) with inherit from Geo, but since Geo is an abstract class. I am forced to specify the definition for perimeter and area for each class that inherits from Geo. If I don’t I’ll get a typeError.
from abc import ABC, abstractmethod
class Geo(ABC):
def cm_to_m(self,x):
return x/100
@abstractmethod
def perimeter():
pass
@abstractmethod
def area():
pass
class Circle(Geo):
def perimeter(self,r):
return 23.14r
def area(self,r):
return 3.14rr
class Rect(Geo):
def perimeter(self,a,b):
return 2a+2b
def area(self,a,b):
return a*b
rect=Rect()
print(rect.perimeter(2,3))
print(rect.area(2,3))
circ=Circle()
print(circ.perimeter(3))
print(circ.area(3))
The abstract class is then a template for a family of classes that should all have the same methods but for which some methods have to be individually defined.
Please correct if this is the wrong way of thinking about it.
It is still new to me, but from my point of view a “template class” might be a better name.
For example, if I want to define a class that finds the perimeter and area of planar objects such as a square, circle, trapezoid….
I’ll make a Geo class that can convert centimeters to meters and return the perimeter and area of a rectangle.
But then I want want a class that does the same thing for a circle. I can inherit from the Geo class and create new definitions for perimeter and area, like this.
class Geo():
def cm_to_m(self,x):
return x/100
def perimeter(self,a,b):
return 2a+2b
def area(self,a,b):
return a*b
class Circle(Geo):
def perimeter(self,r):
return 23.14r
def area(self,r):
return 3.14rr
rect=Geo()
print(rect.perimeter(2,3))
print(rect.area(2,3))
circ=Circle()
print(circ.perimeter(3))
print(circ.area(3))
I could then go on to do the same thing for other planar shapes. Like a square or hexagon…
But what was the use in even defining perimeter and area in the first place. So I’ll make Geo an abstract class. I won’t even specify the code for perimeter and area. All my planar classes (rectangle, square, circle,hexagon…) with inherit from Geo, but since Geo is an abstract class, I am forced to specify the definition for perimeter and area.
from abc import ABC, abstractmethod
class Geo(ABC):
def cm_to_m(self,x):
return x/100
@abstractmethod
def perimeter():
pass
@abtractmethod
def area():
pass
class Circle(Geo):
def perimeter(self,r):
return 23.14r
def area(self,r):
return 3.14rr
class Square(Geo):
def perimeter(self,a,b):
return 2a+2b
def area(self,a,b):
return a*b
sq=Square()
print(sq.perimeter(2,3))
print(sq.area(2,3))
circ=Circle()
print(circ.perimeter(3))
print(circ.area(3))
The abstract class is then a template for a family of classes that should all have the same methods but for which some methods have to be individually defined.
Here is your code in runnable form:
from abc import ABC, abstractmethod
class Geo(ABC):
def cm_to_m(self, x):
return x / 100
@abstractmethod
def perimeter():
pass
@abstractmethod
def area():
pass
class Circle(Geo):
def perimeter(self,r):
return 2 * 3.14 * r
def area(self,r):
return 3.14 * r ** 2
class Square(Geo):
def perimeter(self,a,b):
return 2 * (a + b)
def area(self, a, b):
return a * b
sq=Square()
print(sq.perimeter(2,3))
print(sq.area(2,3))
circ=Circle()
print(circ.perimeter(3))
print(circ.area(3))
10
6
18.84
28.26
Thanks mtf! My first post and was not clear on how to post code.
Have you found the instructions on how to post code samples?
Yes, I think I have it straight now.
Thanks!