+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

11/16/2018 7:00:23 PM

Aditya Rana

16 Answers

New Answer

+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

+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?

+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.

+4

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.

+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

+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

+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.

+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.

+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/python-3-oop-part-3-delegation-composition-and-inheritance/

+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?

+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

+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.

+1

@David Carroll Hey, actually I figured it out myself. Will be uploading compete code soon with composition. And another question too XD

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.

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?)

0

David Carroll Hatsy Rei If I use composition then how will I override "percent_discount_on_price"?