+ 7

How can I retain properties of an instance of base class after replacing it with instance of derived class?

I'm practicing OOP by making a cash desk script for an imaginary shop. I created a class called Customers that contains normal visitors. Another class called Members extends Customers and contains members of the shop. The shop offers offers a facility: instead of paying in cash, customers can add some amount to their "pending balance" with the shop. If a customer has a pending balance of $10 and he joins membership of the shop, his pending balance is lost. How do I retain it? Edit: I'm adding the code. https://code.sololearn.com/cNKAK3o8N28e/?ref=app

16th Nov 2018, 7:00 PM
Aditya Rana
16 Answers
+ 6
There are a few ways you can do it, but sounds like directly changing the class type of the object will achieve what you want. This way, you don't even need to initialize two objects. aditya = Customers("Aditya Rana", 1234) aditya.add_pending_balance(10) aditya.__class__ = Members print(aditya.get_pending_balance()) print(aditya.membership_balance) https://code.sololearn.com/c6vh8Mjb6rhe/?ref=app
17th Nov 2018, 2:04 AM
Hatsy Rei
Hatsy Rei - avatar
+ 5
Aditya Rana For a short exercise, it won't matter. However, the bigger and more complex your code base becomes, there is no doubt you should use composition over inheritance when possible, especially in Python. Otherwise, you will rack your brain with compromise after compromise working around the many limitations using risky, albeit cool, hacks like reassigning the class type, which may result in unforeseen side effects.
17th Nov 2018, 3:00 PM
David Carroll
David Carroll - avatar
+ 4
Why are you instantiating a new Customers instance and then instantiating a new Members instance to the same variable? Your reference to the Customers instance is being replaced by a new reference to your Members instance. Was this intentional or by mistake?
16th Nov 2018, 8:19 PM
David Carroll
David Carroll - avatar
+ 4
The logic that "A member is-a customer" and "A customer has-a membership" both sound valid. You can try out both versions if time isn't a limiting factor. However, the use of composition in this case should be a closer / more accurate representation of the real life structure. From the perspective of application, you may find it easier to manipulate your objects, as compared to how inheritance is used here.
17th Nov 2018, 2:57 PM
Hatsy Rei
Hatsy Rei - avatar
+ 3
Just one observation: If you add pending balance of member, it still returns 0. edit: Aditya Rana I was saying this way https://code.sololearn.com/cJbdn8jB5Sco/?ref=app
16th Nov 2018, 7:50 PM
Roneel
Roneel - avatar
+ 3
David Carroll Alas, I'm unaware if the practice is Pythonic, or even universally applicable. Originally, I wanted to do a deep copy from Customers to Members, but thought about casting as well, and eventually came across this: https://stackoverflow.com/questions/8062161/can-i-dynamically-convert-an-instance-of-one-class-to-another
17th Nov 2018, 3:22 AM
Hatsy Rei
Hatsy Rei - avatar
+ 2
Hatsy Rei Interesting solution. I had to do a double take on the reassignment of the class type. Is this an unofficial Pythonic approach for emulating type casting between base and derived types? It would be ideal if Python supported down and up casting as seen in static languages.
17th Nov 2018, 3:07 AM
David Carroll
David Carroll - avatar
+ 2
Aditya Rana Will members have both a pending_balance and a membership_balance? It appears that the only type difference in the derived class is the addition of the membership_balance property.
17th Nov 2018, 3:22 AM
David Carroll
David Carroll - avatar
+ 2
Aditya Rana Rather than using inheritance to define a Member is a Customer, consider using composition to define a Customer has a Membership. You can learn more about this in the following link: http://blog.thedigitalcatonline.com/blog/2014/08/20/JUMP_LINK__&&__python__&&__JUMP_LINK-3-oop-part-3-delegation-composition-and-inheritance/
17th Nov 2018, 3:45 AM
David Carroll
David Carroll - avatar
+ 2
Hatsy Rei What do you suggest? Should I change from Is-A approach to Has-A approach or should I use method suggested by you?
17th Nov 2018, 2:43 PM
Aditya Rana
+ 2
Aditya Rana I created a modified version of your code showing a basic approach using Composition over Inheritance. Since I'm not clear on what's going on in the Customers and Members classes, my class restructuring may be wrong. However, I hope the gist of how this can be done helps pave your path forward. https://code.sololearn.com/cMCDpSgfvFCR/?ref=app
18th Nov 2018, 8:17 AM
David Carroll
David Carroll - avatar
+ 1
Aditya Rana: I'm thinking... 🤔 Your last response raises quite a few questions about the overall design, approach, and understanding about the correlation of class entities with the database. It might be helpful if you can provide more details on your database model and how you plan to read and write to and from it.
17th Nov 2018, 2:34 AM
David Carroll
David Carroll - avatar
+ 1
@David Carroll Hey, actually I figured it out myself. Will be uploading compete code soon with composition. And another question too XD
18th Nov 2018, 9:22 AM
Aditya Rana
0
Roneel I think you mistyped something because it returned 10 on adding 10. Edit: yeah the reason for this is the same as what happens in case of Customers...It creates a new object or something and destroys the properties of previous object.
16th Nov 2018, 7:53 PM
Aditya Rana
0
David Carroll I want to replace the instance otherwise if many customers are converting to members then the database will have many duplicates. (Well we could create a separate algorithm that checks the database if the name and number are same then assign that customer's dues to its Members object. But why take that pain if this can be solved?)
16th Nov 2018, 8:27 PM
Aditya Rana
0
David Carroll Hatsy Rei If I use composition then how will I override "percent_discount_on_price"?
17th Nov 2018, 3:34 PM
Aditya Rana