5

The reasons may vary from breaking principle/guidelines of OO to considering protected as part of public API.

Then, what should we do if some derived classes have same members? Should we declare them in base class and inherit them? Or should we declare them in derived classes multiple times?

For example, class Warrior and class Wizard both have members such as hp, atk, def, and are derived from base class Player. class Warrior has its own member fury, while class Wizard has its own member mana.

Should I:

  1. declare hp, atk, def in class Player as protected and declare fury as private in class Warrior, mana in Wizard?
  2. declare hp, atk, def, fury(Warrior only), mana(Wizard only) in class Warrior and class Wizard as private?

Which one is the better practice, and why?

PS: I was told this question is primary-opinion based, but I would still like to know how people decide when to implement one of which, thanks.

8

You're asking the question the wrong way.

The right question to ask is, "Does my base class implement the thing it is named after?"

Does a player have HP? Then HP should be a member of the player class, not of the derived classes, because otherwise, Player isn't implementing a player.

Should this member be protected? Why not make it private, and put the Player class in charge of enforcing invariants on it (such as not allowing it to drop beyond a minimum, or rise above the allowed maximum, or triggering death if it hits 0)? Again, if you don't, then Player doesn't really implement a player, but rather a "here's some grab bag of things that would be useful to a player".

  • Very much this. See Principle of Least Suprise. Things should have names that ensure that people aren't surprised by what they find inside. It makes abstraction powerful, rather than annoying. – candied_orange Dec 16 '17 at 14:05
  • Thank you for answering, I get some of your points, but (I think) the reason not to set it private is because the derived class may also need that member. – adayoegi Dec 16 '17 at 14:30
  • When HP is set to private, and class Player implements the method, it is good if HP has nothing related to derived class methods. – adayoegi Dec 16 '17 at 14:30
  • If Warrior's fury depends on its HP, it is class Warrior which needs to implement a method, but it cannot access HP unless class Player either set HP as public/protected or provide a public/protected method. – adayoegi Dec 16 '17 at 14:30
  • Under such circumstances, we cannot set HP to private. Is there any concepts I am misunderstanding or misusing? – adayoegi Dec 16 '17 at 14:33
2

Sebastian already hit the nail on the head with his advices about class design.

For the sake of completeness, here some very important additional points:

  • you should not define a data member protected or private in the base class and later redefine it in the derived class: this would just define another member with the same name and create a terrible confusion (online demo).
  • if you don't work with the clean and discipline private approach suggested by Sebastian, then you should be at least consistent with yourself: if you define some data in the derived class (e.g. Warrior), you should prefer protected over private, exactly as you have envisaged for the base class. This would help, if later you decide to further derive Warrior into BotWarrior and AlienWarrior.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.