C
C#12mo ago
Tijmen

Inheritance

I'm trying to create a setup where the data and logic of my weapons are separate. Hence there being a Weapon class, and WeaponData. We have many types of weapons, that also inherit deeply. Think Pistol inherits from SingleShotWeapon which inherits from FireArm which inherits from Weapon. Usually each type also has a separate config class, WeaponData_Pistol. I'm struggling to find a way to nicely have this sub-class defined in the class itself. The deep inheritance chain makes generics difficult, i cant just add a generic field and constraint to Weapon and end that chain at any point since it will be inherited even further. It also means we need to construct our class like this: `new FireArm<FireArmData>, which is a bit odd. It should always use a FireArmData.
No description
8 Replies
Tijmen
TijmenOP12mo ago
This new obviously wont work, the base classes wont be assigned
Tijmen
TijmenOP12mo ago
Generics but i dont like that much either. There is no final class, so i always have to define the T just to pass it through. Its odd to have to pass this type in the pistol constructor
No description
Omnissiah
Omnissiah12mo ago
my first thouguht would be use less inheritance
Tijmen
TijmenOP12mo ago
Yeah i agree but a) legacy and b) there is some shared code in all of them. But yes, we wouldve loved to separate these in more components and use composition instead.
Omnissiah
Omnissiah12mo ago
for example SingleShotWeapon to me it doesn't look like it should be part of the identity of the weapon it's a property i'm not sure i would go even deeper than FireArm i could maybe think of composing the inherited FireArm classes with interfaces (it depends on how variable items are), but not inheriting them from Weapon i would avoid this at all costs it would probably be unusable
Tijmen
TijmenOP12mo ago
Thanks for your response
Omnissiah
Omnissiah12mo ago
in the end it depends on how you use this stuff, for sure
Mao
Mao12mo ago
public class Weapon
{
public WeaponData data;

public Init(WeaponData data)
{
//if you're doing some dependency injection approach
}

public ShootGrenade()
{
if(data.GrenadeComponent.HasGrenade)
{
//shoot grenade
}
}
}

public class WeaponData
{
public string WeaponName;

public WeaponStats WeaponStats;
public GrenadeComponent GrenadeComponent;
public LaserSightComponent LaserSightComponent;

public struct WeaponStats
{
public float WeaponDamage;
public float Capacity;
}

public struct GrenadeComponent
{
public bool HasGrenade;
public float GrenadeDamage;
}

public struct LaserSightComponent
{
public bool HasLaserSight;
public float LaserRange;
}
}
public class Weapon
{
public WeaponData data;

public Init(WeaponData data)
{
//if you're doing some dependency injection approach
}

public ShootGrenade()
{
if(data.GrenadeComponent.HasGrenade)
{
//shoot grenade
}
}
}

public class WeaponData
{
public string WeaponName;

public WeaponStats WeaponStats;
public GrenadeComponent GrenadeComponent;
public LaserSightComponent LaserSightComponent;

public struct WeaponStats
{
public float WeaponDamage;
public float Capacity;
}

public struct GrenadeComponent
{
public bool HasGrenade;
public float GrenadeDamage;
}

public struct LaserSightComponent
{
public bool HasLaserSight;
public float LaserRange;
}
}
Enjoy my crappy composition approach. I've actually tried something similar to what you have up there with generics, which turned into covariance, which turned into me digging a gigantic hole.
Want results from more Discord servers?
Add your server