Pergunta

I was doing a kind of R&D and am confused with the concept of an abstract class.

What I know about an abstract class is that it may contain concrete methods, and it may contain virtual methods. It may or may not contain an abstract method, and it may contain fields and restricting the direct creation of instances.

But we can achieve all these in a simple base class (an addition of virtual methods will do a lot because a base class with virtual methods which doesn't contain an implementation there and override is same as an abstract method). Then why do we need an abstract class though interface support multiple inheritance and events?

Foi útil?

Solução

But we can achieve all these in a simple baseclass

No, you can't. You can't have a non-abstract class that has abstract methods (methods where the signature is defined, but no implementation is given, thus forcing derived classes to provide an implementation).

Abstract classes exist so that they can provide a combination of implemented methods and abstract methods.

You can attempt to avoid using abstract classes by using concrete implementations that just don't do anything, but it has a number of drawbacks:

  • It doesn't force the caller to override the implementation.
  • It gives the impression that the type and those methods in particular are working, when in fact they are not. By adding the feature of abstract methods and types you prevent the unintended use of an incomplete type by someone who doesn't realize that it's incomplete.
  • It provides a clear contract to sub-classes as to what functionality they need to provide, versus what methods of the base class are working but can optionally be extended.

Also consider non-void methods in a world without abstract. They would need to throw (i.e. NotImplementedException) or return an invalid value (i.e. null). This could be quite a lot worse than a method that just does nothing.

Outras dicas

The main difference is the compiler won't let you instantiate an abstract class, while you could instantiate a base class (which may not make sense).

AbstractType a = new AbstractType(); //compiler error
AbstractType d = new DerivedType(); //OK

BaseType b = new BaseType(); //OK

Notice with the variable d we are guaranteed that the abstract methods have been overridden (otherwise the DerivedType class would have a compiler error).

Since you are commenting a lot of confusion still I'll give you the example I had that really made this concept click for me. Imagine you are making a tower defense game. You have a tower class, and every tower has the ability to attack, so you make an abstract tower class like this:

abstract class Tower
{
    abstract void Attack();
}

Now I can make several tower classes:

class FlameTower : Tower
{
    override void Attack()
    {
        //Shoot flames at everyone
    }
}

class IceTower : Tower
{
    override void Attack()
    {
        //Shoot ice everywhere
    }
}

Now if you want to declare a list of towers, you can write:

 List<Tower> towerList = new List<Tower>();
 towerList.Add(new FireTower());
 towerList.Add(new IceTower());

then iterate through them and make them all attack:

 foreach (Tower t in towerList)
 {
     t.Attack();
 }

And every class is guaranteed to have implemented attack because it was marked abstract and would be a compile error if they did not. Now all this could be done with a base class, except a base class would allow this:

 towerList.Add(new Tower());

Now when it tries to call attack on that new Tower() it's going to hit a blank abstract method, which is not what we want. So to forbid declaring something as a generic tower, we make the class abstract, then we know everything will have it's own definition of Attack and it will do something.

There are some classes which just don't exist in the real world, and so should conceptually be marked as abstract. For example, consider abstract class Animal. There's no such thing as an "animal" out in the real world. Instead, there are concrete types of animals such as Dog, Cat, etc.

One simple answer could be:-

Base classes have their own implementations for methods, and these implementations can be used/added to in an inherited class. You can instantiate a base class

Abstract classes have declarations for class methods. Any class inheriting the abstract class must implement it's abstract methods or becomes to abstract itself. You can not instantiate a abstract class

Example:-

public abstract class A
{
   public void Method1()
   {
     //method code
   }

   public abstract void Method2();

   public virtual void Method3()
   {
    //method code for class A, when class A calls Method3, this code is executed
   }
}

public class B : A
{
   public override void Method2()
   {
     //this must be implemented here to use it
   }

   public override void Method3()
   {
     //method code for class B, when class B calls Method3, this code is executed
     //or, if you choose not to override this method, the compiler will use the code in class A
   }
}

class B can still use Method1 from class A because it's inherited. And if class A is to be abstract, then all of the methods would be declared like Method2 and would have to be implemented in class B so that it can be used.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top