Pure design question: protected vs private with abstract classes

  • (2 Pages)
  • +
  • 1
  • 2

24 Replies - 2211 Views - Last Post: 14 May 2012 - 11:57 AM

#1 Bearcav  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 06-May 12

Pure design question: protected vs private with abstract classes

Posted 06 May 2012 - 05:17 PM

Ok as the topic suggests my question is from a purely design point of view, not help with any actual code I've written.

Quick disclaimer; I'm rather new. I've been learning C# through Rob Mile's C# Yellow Book. It is entirely possible that I may simply lack the knowledge of some aspect of C# that would help me accomplish my goal.

Now what I want to do is create an abstract class to act as a template for enemies in a game. All enemies are going to use the same data members to represent in-game stats (health, damage, etc.) Like any good game there is going to be a variety of enemies each with different values for their data members (goblins get 5 health, ogres 20, you get the idea).

The simple and easy solution is to make the data members protected. "So then what's the problem?" you may be asking yourself. The problem comes down to convention.

Rob Miles appears to be very much against using protected data members, suggesting that I use private instead and use public methods to access them. Now this is just one man's opinion, but I don't want to get into the habit of using bad design with my coding. So is protected data member something I should avoid when designing something like the example I used above? Since I want each instance of an enemy to start with particular values going the private member/public method route seems like a considerable amount of extra coding when compared to simply setting "health = 5".

Any feedback is appreciated.

Is This A Good Question/Topic? 0
  • +

Replies To: Pure design question: protected vs private with abstract classes

#2 lesPaul456  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 173
  • View blog
  • Posts: 729
  • Joined: 16-April 09

Re: Pure design question: protected vs private with abstract classes

Posted 06 May 2012 - 08:03 PM

I've heard many arguments for both sides and I personally lean towards not using protected members. Protected members definitely have their place. However, like most things, they are often misused and abused.

I like to keep my member variables private and only expose them to client code using public properties when necessary. I will occasionally create protected properties, but the need rarely arises. So, generally speaking, I prefer to keep my member variables private.

Protected methods, on the other hand, I find very useful, especially when creating abstract classes.
Was This Post Helpful? 0
  • +
  • -

#3 bonyjoe  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 175
  • View blog
  • Posts: 548
  • Joined: 08-September 10

Re: Pure design question: protected vs private with abstract classes

Posted 07 May 2012 - 09:49 AM

I lean towards not using protected fields, I always use private fields and public properties. Sometimes using protected set methods in the properties but I can't think of many times were I actually have done this.

Why are you choosing to use an abstract class instead of an interface for this task? (Not saying it's incorrect I'm just interested)
Was This Post Helpful? 0
  • +
  • -

#4 Bearcav  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 06-May 12

Re: Pure design question: protected vs private with abstract classes

Posted 07 May 2012 - 01:03 PM

First off, thank you for the replies. They have been helpful.

View Postbonyjoe, on 07 May 2012 - 09:49 AM, said:

Why are you choosing to use an abstract class instead of an interface for this task? (Not saying it's incorrect I'm just interested)


Well, as I stated above, I'm new to C#. Each time a new concept is thrown my way I tend to create a simple program that uses it as I find it helps me "get" the concept better when I actually implement it rather than just reading theory.

For example, I attempted to see if you could make a constructor abstract. As you guys are more experienced than I am you already know how that panned out. My compiler was not happy with me for that little experiment. :)

So based on the feedback I've gotten so far, yeah, it seems like protected members are generally considered taboo. This is certainly some good info on my part as now I know to avoid them and won't fall into bad coding habits, at least on this subject.

As for interfaces they do seem closer to want I want to do, but in the book I'm reading Rob Miles has (so far) only mentioned putting methods in them, no mention of members. However I know that you can (or at least the compiler hasn't told me I can't).

Actually, this brings up another newbie question I've been wondering about. I find interfaces are useful to plan out methods for classes to use and to ensure that each class has the required methods. With members however I'm not quite sure how interfaces would help me.

I mean when you create a class constructor you can make sure that the class will start with values for the members you created, and by chaining constructors in the derived/child classes you ensure that they all get values as well. As a result I'm not really getting why I would include members in an interface. Methods sure, but not so much members, unless they are only added to help plan out the program.

Perhaps I'm not fully understanding something with interfaces and their relationship to classes. Anyone willing to give me a clarification?
Was This Post Helpful? 0
  • +
  • -

#5 Nerfpl  Icon User is offline

  • D.I.C Head

Reputation: 43
  • View blog
  • Posts: 165
  • Joined: 15-January 12

Re: Pure design question: protected vs private with abstract classes

Posted 07 May 2012 - 01:08 PM

When it comes to interfaces i always think of plugins as best example. You give interface to your friend and he can inherit it and make class which then you can check and use as that interface. So in the end plugins are always handled same way by same functions having same options or whatever no matter what else they actually have as part of their class.

Also the fact that you can inherit from multiple interfaces but only from 1 class.
So for different example:
In game some objects can be IDrawable, others can be IUpdateable, so they respectively have Draw() and Update(). But some objects maybe need to be both at same time so interfaces are good way to join those functions.
Then some collection of random objects can check is is object IDrawable, then object.Draw(), is object IUpdateable, then object.Update()

From what i know interface cannot have fields, only properties, so those are almost same as methods.

This post has been edited by Nerfpl: 07 May 2012 - 01:17 PM

Was This Post Helpful? 0
  • +
  • -

#6 Bearcav  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 06-May 12

Re: Pure design question: protected vs private with abstract classes

Posted 07 May 2012 - 03:36 PM

View PostNerfpl, on 07 May 2012 - 01:08 PM, said:

When it comes to interfaces i always think of plugins as best example. You give interface to your friend and he can inherit it and make class which then you can check and use as that interface. So in the end plugins are always handled same way by same functions having same options or whatever no matter what else they actually have as part of their class.

Also the fact that you can inherit from multiple interfaces but only from 1 class.
So for different example:
In game some objects can be IDrawable, others can be IUpdateable, so they respectively have Draw() and Update(). But some objects maybe need to be both at same time so interfaces are good way to join those functions.
Then some collection of random objects can check is is object IDrawable, then object.Draw(), is object IUpdateable, then object.Update()

From what i know interface cannot have fields, only properties, so those are almost same as methods.


Funny enough I had just finished reading up on properties before I got here. Had a sort of "Ah-ha!" moment as I believe they take care of the problem I was having earlier. Will have to write up a few tests and see.

Alright, so if I'm understanding this correctly, the real power behind interfaces is that you can have a class implement one or more depending on what you need to do. I'll use my enemy example above to make sure I'm getting this correctly.

So I want a template for all of my enemies in a game, as every enemy is going to have health, etc. etc. So I create an interface called IEnemy and set all of the methods and properties such as below (going to attempt to use the code button here...hope I get it right)

public interface IEnemy
{
void Attack();
void DisplayHealth();
public int Health
{
get;
set;
}
public int Damage
{
get;
set;
}
}



Ok, so I got my (very simplified) template for an enemy. It's going to have a method to display a message when it attacks, a method to display it's current health, and then a property related to each. (damage for the amount it does in attack, health for how much damage it can take).

Now say I want to add boss enemies to my game. Bosses will have the exact same values and methods as an enemy...but will also each have a special attack. So I make a new interface...

public interface IBoss
{
void SpecialAttack();
int SpecialDamage
{
get;
set;
}
}



Now, when I want just a regular enemy, I reference only IEnemy. But when it is a boss, I also reference IBoss along with IEnemy.

A class can have one of two different types of interfaces or both as needed. Or even dozens if, for whatever mad reason, it is required.

So am I actually getting the idea behind interfaces, or just sort of scratching the surface?
Was This Post Helpful? 0
  • +
  • -

#7 racidon  Icon User is offline

  • D.I.C Head

Reputation: 59
  • View blog
  • Posts: 172
  • Joined: 27-August 11

Re: Pure design question: protected vs private with abstract classes

Posted 07 May 2012 - 04:10 PM

Protected fields in an abstract class would be used like so:


abstract class AbstractClass
{
protected string
   valueOne,
   valueTwo;

public override ToString()
{
   return valueOne + " " + valueTwo;
}
}



class NextLevelClass:AbstractClass
{
   NextLevelClass()
   {
      valueOne = "One";
      valueTwo = "Two";
   }
}



NextLevelClass test = new NextLevelClass();

test.ToString(); //Returns "One Two"//



That's an extremely simplistic view, but protected members shouldn't be viewed as off limits, they do have their place
Was This Post Helpful? 0
  • +
  • -

#8 Nerfpl  Icon User is offline

  • D.I.C Head

Reputation: 43
  • View blog
  • Posts: 165
  • Joined: 15-January 12

Re: Pure design question: protected vs private with abstract classes

Posted 07 May 2012 - 04:14 PM

The hardest part is actually "how/when to use them". Personally i don't know that much about it (maybe someone else will explain better) but for thing like boss, enemy i would structure it differently. Character -> Goblin, Ogre. Goblin -> SuperGoblin etc

This post has been edited by Nerfpl: 07 May 2012 - 04:23 PM

Was This Post Helpful? 0
  • +
  • -

#9 Bearcav  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 06-May 12

Re: Pure design question: protected vs private with abstract classes

Posted 07 May 2012 - 05:48 PM

View Postracidon, on 07 May 2012 - 04:10 PM, said:

Protected fields in an abstract class would be used like so:



abstract class AbstractClass
{
protected string
   valueOne,
   valueTwo;

public override ToString()
{
   return valueOne + " " + valueTwo;
}
}



Quick question about this bit of code...shouldn't the ToString method be virtual here? I thought you make the method in the parent class virtual and only use override in the derived/child classes. Or maybe this is more of a question of convention rather than law.


View PostNerfpl, on 07 May 2012 - 04:14 PM, said:

The hardest part is actually "how/when to use them". Personally i don't know that much about it (maybe someone else will explain better) but for thing like boss, enemy i would structure it differently. Character -> Goblin, Ogre. Goblin -> SuperGoblin etc


Oh I'm so using SuperGoblin. :) But after playing around with properties and interfaces a bit more, I think you're right. It actually concerns another question I have...but I'll save that for a different topic on a different day. Don't want to have this thread keep going well beyond the scope of my question.

All in all you guys have been very helpful. Thank you for putting some time in to help a newbie with some simple question.
Was This Post Helpful? 0
  • +
  • -

#10 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5881
  • View blog
  • Posts: 12,758
  • Joined: 16-October 07

Re: Pure design question: protected vs private with abstract classes

Posted 07 May 2012 - 05:59 PM

abstract class AbstractClass {
	protected string valueOne, valueTwo;

	// you forgot the return type
	// the reason it's override is that all object have a base
	// method ToString -- you're overriding that.
	public override string ToString() {
		return valueOne + " " + valueTwo;
	}
}



Now, it does depend on what you mean by "fields." If they're object variables, then protected is messy. However, protected methods are another matter. In the above, we don't know where valueOne and valueTwo come from.

Consider:
abstract class AbstractClass {
	// now the implementing class must put something in here
	protected abstract string ValueOne { get; }
	// however, such values may not be appropriate for public
	protected abstract string ValueTwo { get; }

	// our abstract class can use the values not yet defined
	public override string ToString() {
		return ValueOne + " " + ValueTwo;
	}
}


Was This Post Helpful? 0
  • +
  • -

#11 racidon  Icon User is offline

  • D.I.C Head

Reputation: 59
  • View blog
  • Posts: 172
  • Joined: 27-August 11

Re: Pure design question: protected vs private with abstract classes

Posted 08 May 2012 - 12:12 AM

View PostBearcav, on 07 May 2012 - 05:48 PM, said:

View Postracidon, on 07 May 2012 - 04:10 PM, said:

Protected fields in an abstract class would be used like so:



abstract class AbstractClass
{
protected string
   valueOne,
   valueTwo;

public override ToString()
{
   return valueOne + " " + valueTwo;
}
}



Quick question about this bit of code...shouldn't the ToString method be virtual here? I thought you make the method in the parent class virtual and only use override in the derived/child classes. Or maybe this is more of a question of convention rather than law.


View PostNerfpl, on 07 May 2012 - 04:14 PM, said:

The hardest part is actually "how/when to use them". Personally i don't know that much about it (maybe someone else will explain better) but for thing like boss, enemy i would structure it differently. Character -> Goblin, Ogre. Goblin -> SuperGoblin etc


Oh I'm so using SuperGoblin. :) But after playing around with properties and interfaces a bit more, I think you're right. It actually concerns another question I have...but I'll save that for a different topic on a different day. Don't want to have this thread keep going well beyond the scope of my question.

All in all you guys have been very helpful. Thank you for putting some time in to help a newbie with some simple question.


In response to your question, since all objects have "ToString" (which is a virtual method of the Object class) I used override. It would still be the same even if ToString didn't exist you could just place Virtual instead of Override

View Postbaavgai, on 07 May 2012 - 05:59 PM, said:

abstract class AbstractClass {
	protected string valueOne, valueTwo;

	// you forgot the return type
	// the reason it's override is that all object have a base
	// method ToString -- you're overriding that.
	public override string ToString() {
		return valueOne + " " + valueTwo;
	}
}



Now, it does depend on what you mean by "fields." If they're object variables, then protected is messy. However, protected methods are another matter. In the above, we don't know where valueOne and valueTwo come from.

Consider:
abstract class AbstractClass {
	// now the implementing class must put something in here
	protected abstract string ValueOne { get; }
	// however, such values may not be appropriate for public
	protected abstract string ValueTwo { get; }

	// our abstract class can use the values not yet defined
	public override string ToString() {
		return ValueOne + " " + ValueTwo;
	}
}


Where/what the values are is irrelevant as the higher level class is what will determine what the values are used for and where.

Say you have multiple types inherit this class, that will always have 2 string values for whatever reason. The user can use the ToString to save the class in a text file or just display the values in a constant format. And yes this could also be done using abstract properties but I don't see how that is proper practice.
Was This Post Helpful? 1
  • +
  • -

#12 bonyjoe  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 175
  • View blog
  • Posts: 548
  • Joined: 08-September 10

Re: Pure design question: protected vs private with abstract classes

Posted 08 May 2012 - 10:37 AM

@Racidon - I believe what he means is when you type valueOne = "blah" in your child class, you don't know where that valueOne is defined, what it is, how it should be used etc. You may love these protected fields now because you code solo, but when you are working in a multi developer environment and while you are coding a class which is several levels down the hierarchy, you don't want to random fields that you haven't defined flying around.

@bearcav - Interfaces are very useful in that you can have a method that takes an inteface, say IEnemy as it's parameter, then you can throw any class that has that interface that inherits from it (or that inherits from something that inherits it etc) at the method and it will always know how to deal with what you are passing in, because it knows all that if it calls a method from the interface or uses a property from the interface then the class will definitely have a definition for it.

So you may do something like this

public interface IEnemy
{
  Int32 Health {get; set;}
}

public class Hero
{
  private Int32 _attack = 5;

  public void Attack(IEnemy victim)
  {
    victim.Health -= _attack;
  }
}



And the attack method will always work because you cannot compile a child of IEnemy without providing a Health property
Was This Post Helpful? 3
  • +
  • -

#13 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5881
  • View blog
  • Posts: 12,758
  • Joined: 16-October 07

Re: Pure design question: protected vs private with abstract classes

Posted 08 May 2012 - 11:18 AM

View Postracidon, on 08 May 2012 - 02:12 AM, said:

Where/what the values are is irrelevant as the higher level class is what will determine what the values are used for and where.


I disagree.

Variables have no guarantee of initialization. If you rely on them being initialized, then it matters greatly. By requiring values to be implemented through an abstract declaration, you assure that at least something will be there. At the very least you drive home the point that someone extending the class need take notice.

Interfaces define available methods. For an abstract base class, protected abstract methods assure such availability within the context of concreted instances of that base class. Some variables simply declared within a parent needn't conform to such a contract.
Was This Post Helpful? 1
  • +
  • -

#14 Bearcav  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 06-May 12

Re: Pure design question: protected vs private with abstract classes

Posted 08 May 2012 - 05:58 PM

@Racidon: In reference to the ToString question...ah, yes, makes sense.

@bonyjoe: The example you gave with using an interface within the parameters of a method call is fantastic. I've saved this thread for future reference for that. Will probably find it to be very helpful.

So after fooling around with classes (abstract and otherwise), properties, and interfaces I've become much more comfortable with private members so I think I may stick with them if at all possible. Having them private makes them at least seem more secure. Thanks to the feedback here I have a much larger appreciation for interfaces than I did before.

I actually have a bit of code written up that works based on the discussion here and would like to show it...but I don't want to violate the copy/paste rule for asking a question. It's not a homework assignment in any way, I'm trying to teach myself and just want some feedback, but would rather not be exiled. :)
Was This Post Helpful? 0
  • +
  • -

#15 racidon  Icon User is offline

  • D.I.C Head

Reputation: 59
  • View blog
  • Posts: 172
  • Joined: 27-August 11

Re: Pure design question: protected vs private with abstract classes

Posted 09 May 2012 - 03:59 AM

View Postbonyjoe, on 08 May 2012 - 10:37 AM, said:

@Racidon - I believe what he means is when you type valueOne = "blah" in your child class, you don't know where that valueOne is defined, what it is, how it should be used etc. You may love these protected fields now because you code solo, but when you are working in a multi developer environment and while you are coding a class which is several levels down the hierarchy, you don't want to random fields that you haven't defined flying around.

@bearcav - Interfaces are very useful in that you can have a method that takes an inteface, say IEnemy as it's parameter, then you can throw any class that has that interface that inherits from it (or that inherits from something that inherits it etc) at the method and it will always know how to deal with what you are passing in, because it knows all that if it calls a method from the interface or uses a property from the interface then the class will definitely have a definition for it.

So you may do something like this

public interface IEnemy
{
  Int32 Health {get; set;}
}

public class Hero
{
  private Int32 _attack = 5;

  public void Attack(IEnemy victim)
  {
    victim.Health -= _attack;
  }
}



And the attack method will always work because you cannot compile a child of IEnemy without providing a Health property



public abstract class Person
{
    /// <summary>
    /// First name of the person for those that need a complete explanation instead of just a base EXAMPLE.
    /// </summary>
    protected string
       firstName;
    /// <summary>
    /// Last name of the person for those that need a complete explanation instead of just a base EXAMPLE.
    /// </summary>
    protected string
       lastName;

    /// <summary>
    /// Gets or Sets the First Name of the Person.
    /// </summary>
    public virtual string FirstName
    {
        get{return firstName ?? string.Empty;}
        set{firstName = value;}
    }

    /// <summary>
    /// Gets or Sets the Last Name of the Person.
    /// </summary>
    public virtual string LastName
    {
        get{return lastName ?? string.Empty;}
        set{lastName = value;}
    }

    public Person()
    {
        firstName = "";
        lastName = "";
    }

    public virtual string FullName()
    {
        return firstName ?? string.Empty + " " + lastName ?? string.Empty;
    }
}

public class Student:Person
{
    /// <summary>
    /// Average mark of the student for those that need an explanation.
    /// </summary>
    private float
        averageMark;

    /// <summary>
    /// Gets or Sets the Average Mark of the Student.
    /// </summary>
    public float AverageMark
    {
        get{return averageMark;}
        set{averageMark = value;}
    }

    public Student()
        :base()
    {
        averageMark = 0f;
    }

    public Student(string firstName, string lastName)
        :this()
    {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

public class Teacher:Person
{
    /// <summary>
    /// Rate paid to the Teacher per hour worked.
    /// </summary>
    private float
        hourlyRate;


    /// <summary>
    /// Gets or Sets the hourly rate of the teacher.
    /// </summary>
    public float HourlyRate
    {
        get{return hourlyRate;}
        set{hourlyRate = value;}
    }

    public Teacher()
        :base()
    {
        hourlyRate = 0f;
    }

    public Teacher(string firstName, string lastName)
        :this()
    {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}




Hopefully now that you can see the use you might understand it a little better, I offered a "base" example not a working model.
I think you misunderstand the use of "protected", this question pertained to abstract classes, and in turn means inheritance, interfaces however a purely "definition" thus have no place here.
I don't over use protected, nor is having a protected field any different (other than being the more "accepted" way of coding) than having a protected property.
Just like properties, you can add a description to your fields too, so that those that are inherited are easily understood.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2