62

I'm not really sure what looks better or when do I really use in abstract classes and properties, or when to use non abstract properties. I'll try to make a simple example. Let's say I have this:

abstract class Human
{
  public GenderType Gender { get; set; }
  public string Name { get; set; }
  public Date Born { get; set; }
  public bool IsNerd { get; set; }

  abstract public void Speak();
  abstract public void Sleep();
  abstract public void AnoyingPeopleOnStackOverflow();
  //... so on
}

class Peter : Human
{
  //Peter is special, he got a second name
  //But thats all, everything else is the same as like on other humans
  public string SecondName { get; set; }

  //...override abstract stuff
}

Is this alright? As I understood, I don't have to use an abstract property if I dont want to override it. And in this situation it would be ok, just the methods like Speak, Sleep and so on should be abstract.

Now, if this is ok, when would or should I use an abstract property?

Adi Lester
  • 24,731
  • 12
  • 95
  • 110
miri
  • 1,611
  • 5
  • 20
  • 24
  • 1
    "When would or should I use an abstract property" --- when you want to assert that child class has to provide a specific method implementation – zerkms Sep 03 '12 at 21:58
  • 1
    1) If this were Java, there probably wouldn't be any issue. You'd probably just use an "interface". That's essentially what you're doing here in C#, isn't it? 2) My personal feeling is that if it needs to be part of the "contract", then it's appropriate to declare it in your abstract class. In other words, I think what you've done is perfectly OK. IMHO... – paulsm4 Sep 03 '12 at 21:59
  • 2
    @paulsm4 you can do that with C# too. – Jon Hanna Sep 03 '12 at 22:01

5 Answers5

100

Use an abstract property when you have no default implementation and when derived classes must implement it.

Use a virtual property when you have an implementation in the base class but want to allow overriding.

Use the override keyword to override a member. Mark the member as sealed override if it should not be overridden again.

Don't mark the property as abstract or virtual if you don't want it to be overridden.

Use the new keyword to hide a non-abstract, non-virtual member (this is rarely a good idea).

How to: Define Abstract Properties

I find that abstract properties often occur in a design which implies that they will have type-specific logic and/or side effects. You are basically saying, "here is a data point that all subclasses must have, but I don't know how to implement it". However, properties which contain a large amount of logic and/or cause side effects may not be desirable. This is an important consideration, though there is no fixed right/wrong way to do it.

See:

Personally, I find that I use abstract methods frequently but abstract properties rarely.

Community
  • 1
  • 1
Tim M.
  • 53,671
  • 14
  • 120
  • 163
47

I know what I want them to do, I don't care how they do it: Interface.

I know what I want them to do, I don't care how they do some of it, but I've firm ideas on how they'll (or at least most of them) do other bits: Abstract class.

I know what I want them to do, and how most of them will do it: Concrete class with virtual members.

You can have other cases such as e.g. an abstract class with no abstract members (you can't have an instance of one, but what functionality it offers, it offers completely), but they're rarer and normally come about because a particular hierarchy offers itself cleanly and blatantly to a given problem.

(Incidentally, I wouldn't think of a Peter as a type of Human, but of each peter as an instance of human who happens to be called Peter. It's not really fair to pick on example code in this way, but when you're thinking about this sort of issue it's more pertinent than usual).

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
  • 3
    +1 - Agree, `Peter` should be an instance of a subclass of `Human`, e.g. `HumansWithTwoNames` – Tim M. Sep 03 '12 at 22:18
  • 2
    @TimMedora Yeah, and we all think of bad names when making up example code, and it normally doesn't matter, but this is one question where it matters more than most. – Jon Hanna Sep 03 '12 at 22:24
18

Abstract members are simply virtual members that you have to override. You use this for something that has to be implemented, but can't be implemented in the base class.

If you want to make a virtual property, and want that it has to be overridden in the class that inherits your class, then you would make it an abstract property.

If you for example have an animal class, its ability to breathe would not be possible to detemine just from the information that it's an animal, but it's something that is pretty crucial:

public abstract class Animal {

  public abstract bool CanBreathe { get; }

}

For a fish and a dog the implementation would be different:

public class Dog : Animal {

   public override bool CanBreathe { get { return !IsUnderWater; } }

}

public class Fish : Animal {

   public override bool CanBreathe { get { return IsUnderWater; } }

}
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
8

Use abstract when all sub-classes have to implement the method/property. If there's no need for each and every sub-class to implement it, then don't use it.

As for your example, if SecondName is not required for each person, then there's no need to make an abstract property in the base class. If on the other hand, every person does need a second name, then make it an abstract property.

Example of correct usage of an abstract property:

public class Car
{
    public abstract string Manufacturer { get; }
}

public class Odyssey : Car
{
    public override string Manufacturer
    {
         get 
         {
             return "Honda";
         }
    }
}

public class Camry : Car
{
    public override string Manufacturer
    {
         get 
         {
             return "Toyota";
         }
    }
}

Making Maker abstract is correct because every car has a manufacturer and needs to be able to tell the user who that maker is.

Daniel
  • 2,944
  • 3
  • 22
  • 40
2

An abstract property would be used where you want the class to always expose the property, but where you can't pin down the implemetation of that property - leaving it up to/forcing the inheriting class to do so.

There's an example here, where the abstract class is named Shape, and it exposes an abstract Area property. You can't implement the Area property in the base class, as the formula for area will change for each type of shape. All shapes have an area (of some sort), so all shapes should expose the property.

Your implementation itself looks just fine. Was trying to think of a sensible example of an abstract property for a Human, but couldn't think of anything reasonable.

Jon Egerton
  • 40,401
  • 11
  • 97
  • 129