-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
[class-inheritance] Concept Documentation #2960
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
3d68dcc
Update config.json
girijakar c73856a
Update config.json
girijakar 2d65f17
Update config.json
girijakar 38b2631
Update about.md
girijakar 4c11958
Update config.json
girijakar f3c8bee
Update about.md
girijakar df00240
Merge branch 'exercism:main' into main
girijakar c272ced
Update config.json
girijakar 54701e4
Update about.md
girijakar ef69e5f
Merge branch 'exercism:main' into main
girijakar 6fd43ee
Update about.md
girijakar fe2ccb7
Update about.md
girijakar 1244a82
Update about.md
girijakar a493c91
Update introduction.md
girijakar a05b2b9
Update introduction.md
girijakar 5e88b46
Update introduction.md
girijakar 0339372
Update links.json
girijakar 9ffe896
Merge branch 'exercism:main' into main
girijakar e0190c7
Update concepts/class-inheritance/.meta/config.json
girijakar 87cbb76
Update concepts/class-inheritance/.meta/config.json
girijakar d907168
Update concepts/class-inheritance/.meta/config.json
girijakar c3c2edc
Update concepts/class-inheritance/about.md
girijakar 55a3163
Update concepts/class-inheritance/about.md
girijakar 0bb7ca6
Update concepts/class-inheritance/about.md
girijakar 18321f5
Update concepts/class-inheritance/about.md
girijakar 7fd20ab
Update concepts/class-inheritance/about.md
girijakar 2dfbb1d
Merge branch 'exercism:main' into main
girijakar 8dfc81b
Remove getters, setters and name mangling
girijakar 3ca94b7
Update about.md
girijakar 36064a3
Merge branch 'main' into pr/2960
BethanyG 5ea681a
Apply suggestions from code review
BethanyG File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
{ | ||
"blurb": "TODO: add blurb for this concept", | ||
"authors": ["bethanyg", "cmccandless"], | ||
"contributors": [] | ||
"blurb": "In Object Oriented Programming ('OOP'), inheritance refers to a class's capacity to copy or 'inherit' properties and methods from another class. Python allows inheritance from a single class or multiple classes. Existing classes are known as base (or parent) classes, and new classes are known as derived (or child) classes.", | ||
"authors": ["girijakar", "bethanyg"], | ||
"contributors": [ ] | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,168 @@ | ||
#TODO: Add about for this concept. | ||
# About | ||
|
||
Inheritance is one of the ['four pillars'][four-pillars] of Object Oriented Programming (`OOP`). | ||
In situations where only a small amount of functionality needs to be customized for a new class, `inheritance` allows code re-use from one or more parent classes, and can help make programs cleaner and more maintainable. | ||
|
||
## Inheritance | ||
|
||
`Inheritance` describes `is a kind of` relationship between two or more classes, abstracting common details into super (_base_ or _parent_) class and storing specific ones in the subclass (_derived class_ or _child class_). | ||
|
||
To create a child class, specify the parent class name inside the pair of parenthesis, followed by it's name. | ||
Example | ||
```python | ||
class Child(Parent): | ||
pass | ||
``` | ||
Every child class inherits all the behaviors (_attributes, constructors, methods_) exhibited by their parent class. | ||
|
||
|
||
## Single Inheritance | ||
|
||
When a derived (or child) class inherits only from one base (or parent) class, it is known as _single inheritance_. | ||
|
||
|
||
```python | ||
# The parent or base class. | ||
class Person: | ||
|
||
def __init__(self, fname, lname): | ||
self.fname = fname | ||
self.lname = lname | ||
|
||
# The child or derived class, inheriting from Person. | ||
class Employee(Person): | ||
|
||
all_employees = [] | ||
def __init__(self, fname, lname, empid): | ||
# Using the Parent constructor to create the base object. | ||
Person.__init__(self, fname, lname) | ||
BethanyG marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Adding an attribute specific to the Child class. | ||
self.empid = empid | ||
BethanyG marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Employee.all_employees.append(self) | ||
``` | ||
`Employee` class is derived from `Person`. | ||
Now, we can create an `Employee` object. | ||
BethanyG marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
```python | ||
... | ||
p1 = Person('George', 'smith') | ||
print(p1.fname, '-', p1.lname) | ||
e1 = Employee('Jack', 'simmons', 456342) | ||
e2 = Employee('John', 'williams', 123656) | ||
print(e1.fname, '-', e1.empid) | ||
print(e2.fname, '-', e2.empid) | ||
``` | ||
After running the program we will get the following output | ||
```bash | ||
|
||
George - smith | ||
Jack - 456342 | ||
John - 123656 | ||
``` | ||
## Multiple Inheritance | ||
As we've seen, `single inheritance` is where a class inherits directly from another class. | ||
On the other side, `multiple inheritance` is a Python feature that allows a child class to inherit characteristics and methods from more than one parent class. | ||
|
||
```python | ||
class SubclassName(BaseClass1, BaseClass2, ...): | ||
pass | ||
``` | ||
### Multiple Inheritance and the Diamond Problem | ||
|
||
The "diamond problem" (also known as the "deadly diamond of death") refers to an ambiguity that occurs when two classes B and C inherit from a superclass A, while another class D inherits from both B and C. If A has a method "m" that B or C (or even both of them) has overridden, and if it does not override this method, the question becomes which version of the method D inherits. It's possible that it's from A, B, or C. | ||
Let's have a look at the problem using an example: | ||
|
||
```python | ||
class A: | ||
def m(self): | ||
print("m of A called") | ||
class B(A): | ||
def m(self): | ||
print("m of B called") | ||
class C(A): | ||
def m(self): | ||
print("m of C called") | ||
class D(B,C): | ||
pass | ||
``` | ||
If we call an instance x of class D, we will get the output as `m of B called`. But if we interchange the order of inheritance in class D i.e. `Class D(C, D)`. We will get the output as `m of C called`. | ||
To solve the diamond problem in python, we will look into a new method `mro()`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't a new method, this is how Python solves the diamond problem. |
||
### Method resolution order(MRO) | ||
|
||
To get the method resolution order of a class we can use either `__mro__` attribute or `mro()` method. By using these methods we can display the order in which methods are resolved. For Example | ||
|
||
```python | ||
class A: | ||
def m(self): | ||
print(" m of A called") | ||
class B: | ||
def m(self): | ||
print(" m of B called") | ||
|
||
# classes ordering | ||
class C(A, B): | ||
def __init__(self): | ||
print("Constructor C") | ||
|
||
r = C() | ||
|
||
# it prints the lookup order | ||
print(C.__mro__) | ||
print(C.mro()) | ||
``` | ||
The output | ||
```cmd | ||
Constructor C | ||
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>) | ||
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>] | ||
``` | ||
### Mixins | ||
A mixin is a type of multiple inheritance that is unique. Mixins are typically employed in one of two scenarios: | ||
|
||
1. We wish to give a class a number of optional features. | ||
1. We want to use a specific feature in a variety of classes. | ||
|
||
For example | ||
```python | ||
class A1(object): | ||
def method(self): | ||
return 1 | ||
|
||
class A2(object): | ||
def method(self): | ||
return 2 | ||
|
||
class B1(object): | ||
def usesMethod(self): | ||
return self.method() + 10 | ||
|
||
class B2(object): | ||
def usesMethod(self): | ||
return self.method() + 20 | ||
|
||
class C1_10(A1, B1): pass | ||
class C1_20(A1, B2): pass | ||
class C2_10(A2, B1): pass | ||
class C2_20(A2, B2): pass | ||
``` | ||
Mixins helps us to recombine functionalities with different choices of base classes. | ||
#### Pros and Cons of Mixins | ||
| Advantages | Disadvantages | | ||
|:-- | :-- | | ||
|Mixin classes tend to be simple because they represent simple orthogonal concepts. | Execution of statements at run time tends to jump around in different mixins, making it hard to follow and debug| | ||
|Helps us to recombine functionalities with different choices | Potential for long compile times| | ||
## __super()__ | ||
In a nutshell, `super()` gives us access to methods in a superclass from the subclass that inherits from it. | ||
`super()` by itself returns a temporary object of the superclass, which may subsequently be used to call the methods of that superclass. | ||
|
||
But why we want to use `super()`? | ||
|
||
Using `super()` to call already created methods avoids having to rebuild those methods in our subclass and allows us to swap out superclasses with little code modifications. | ||
girijakar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
[four-pillars]: https://www.educative.io/edpresso/what-are-the-four-pillars-of-oops-in-python | ||
|
||
[four-pillars]: https://www.educative.io/edpresso/what-are-the-four-pillars-of-oops-in-python | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,7 @@ | ||
#TODO: Add introduction for this concept. | ||
# Introduction | ||
|
||
[Inheritance](inherit) represents what is known as a relationship. When a Derived class inherits from a Base class, you've established a relationship in which Derived is a specialised version of Base. | ||
Either by using single or multiple inheritance, we can inherit the properties from the base class. Inheritance is used because it helps in code reusability. | ||
|
||
|
||
[inherit]:https://realpython.com/inheritance-composition-python/#whats-inheritance |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,42 @@ | ||
[ | ||
{ | ||
"url": "http://example.com/", | ||
"description": "TODO: add new link (above) and write a short description here of the resource." | ||
"url": "https://docs.python.org/3/tutorial/classes.html", | ||
"description": "Classes in python" | ||
}, | ||
{ | ||
"url": "http://example.com/", | ||
"description": "TODO: add new link (above) and write a short description here of the resource." | ||
"url": "https://www.geeksforgeeks.org/access-modifiers-in-python-public-private-and-protected/", | ||
"description": "Access Modifiers in python" | ||
}, | ||
{ | ||
"url": "http://example.com/", | ||
"description": "TODO: add new link (above) and write a short description here of the resource." | ||
"url": "https://www.geeksforgeeks.org/accessor-and-mutator-methods-in-python/", | ||
"description": "Functions in classes" | ||
}, | ||
{ | ||
"url": "http://example.com/", | ||
"description": "TODO: add new link (above) and write a short description here of the resource." | ||
"url": "https://realpython.com/inheritance-composition-python/#whats-inheritance", | ||
"description": "About inheritance" | ||
}, | ||
{ | ||
"url": "https://python-course.eu/oop/multiple-inheritance.php", | ||
"description": "Multiple inheritance and Diamond inheritance problem" | ||
}, | ||
{ | ||
"url": "https://stackoverflow.com/questions/533631/what-is-a-mixin-and-why-are-they-useful", | ||
"description": "Python mixins" | ||
}, | ||
{ | ||
"url": "https://raganwald.com/2016/07/16/why-are-mixins-considered-harmful.html", | ||
"description": "Mixins cons" | ||
}, | ||
{ | ||
"url": "https://gaopinghuang0.github.io/2018/12/29/dig-into-python-super-and-mro", | ||
"description": "Super and mixins functions" | ||
}, | ||
{ | ||
"url": "https://www.python.org/download/releases/2.3/mro/", | ||
"description": "MRO" | ||
}, | ||
{ | ||
"url": "https://nedbatchelder.com/blog/201210/multiple_inheritance_is_hard.html", | ||
"description": "Multiple inheritancs and mixins" | ||
} | ||
] |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.