A lot of that depends on what your use case is…
An abstract base class is often used when you want to define some core functionality that all of it’s child classes will have. It also allows us to define protected methods which can be extended/implemented in the child classes. Interfaces are by definition public methods, and until recently could not contain any functionality.
Often the two are used together.
public interface IWeapon
{
bool CanAttack(GameObject target);
void Attack(GameObject target);
}
public abstract class Firearm : MonoBehaviour, IWeapon
{
[SerializeField] protected Transform aimPoint;
[SerializeField] protected Ammo ammo;
/// An inheriting class might also check range
public virtual bool CanAttack(GameObject target)
{
return ammo.amount >=AmmoPerShot(); //AmmoPerShot() is virtual method
}
// The implementation is left up to the child class
public abstract void Attack(GameObject target);
///Must be implemented in child class, but protected method.
protected abstract int AmmoPerShot();
}
public class ShotGun : Firearm
{
// This fulfils both the IWeapon interface and extends the functionality in Firearm
public override bool CanAttack(GameObject target)
{
if(Vector3.Distance(transform.position, target.transform.position) > 5) return false;
return base.CanAttack(target);
}
public override void Attack(GameObject target)
{
//Shoot the weapon
}
///protected method required by base class and implemented in child class
protected override bool AmmoPerShot()
{
return 5;
}
}