I've been working on building several classes which inherit from one base class but I'm not entirely confident on how inheritance and polymorphism work in C# at this stage.
My base class looks like this:
abstract class Structure
{
public int currentCost = 0;
public int currentArea = 0;
public int currentPopulation = 0;
public int currentConstruction = 0;
public int currentEnergy = 0;
public int currentEconomy = 0;
public abstract int baseCost { get; }
public abstract int baseEnergy { get; }
public abstract int baseEconomy { get; }
public abstract int baseConstruction { get; }
public int baseArea = -1;
public int basePopulation = -1;
public int level = 0;
public abstract string structureName { get; }
}
Now, classes that inherit from the Structure class will be made to provide their own assignments for the abstract variables which is fine as most of the classes vary wildly in the figures they assign.
The abstract variables are used in the derived classes in the following (incomplete) manner:
class BiosphereModification : Structure
{
const int baseEconomyBiosphereModification = 0;
const int baseConstructionBiosphereModification = 0;
const int baseCostBiosphereModification = 2000;
const int baseEnergyBiosphereModification = 0;
const int baseFertilityBiosphereModification = 1;
const string structureNameBiosphereModification = "BiosphereModification";
public override int baseCost { get { return baseCostBiosphereModification; } }
public override int baseEconomy { get { return baseEconomyBiosphereModification; } }
public override int baseEnergy { get { return baseEnergyBiosphereModification; } }
public override int baseConstruction { get { return baseConstructionBiosphereModification; } }
}
However, the non-abstract variables will be the same across the majority of derived classes, but not all of them.
I could make them all abstract and force each class to provide it's own value, but this seems counter-intuitive. What I would prefer is a way to provide a value in the base class and provide an override in a derived class if needed.
Is there a way to do this? I know that this can be done with methods declared virtual. This allows the derived class to use the base classes method unless it provides one of it's own. Surely a similar thing exists for this?
What I would prefer is a way to provide a value in the base class and provide an override in a derived class if needed.
Properties can be declared virtual, as well:
public virtual int BaseCost { get { return 0; } }
public virtual int BaseEnergy { get { return 42; } }
public virtual int BaseEconomy { get { return 3982; } }
public virtual int BaseConstruction { get { return 398829; } }
You can then override them when appropriate:
public override int BaseCost { get { return 2; } }
Related
I have the following base class:
public class Base
{
public string LogicalName { get; set; }
public int NumberOfChars { get; set; }
public Base()
{
}
public Base(string logicalName, int numberOfChars)
{
LogicalName = logicalName;
NumberOfChars = numberOfChars;
}
}
and the following derived classes:
public class Derived1 : Base
{
public const string EntityLogicalName = "Name1";
public const int EntityNumberOfChars = 30;
public Derived1() : base(EntityLogicalName, EntityNumberOfChars)
{
}
}
public class Derived2 : Base
{
public const string EntityLogicalName = "Name2";
public const int EntityNumberOfChars = 50;
public Derived2()
: base(EntityLogicalName, EntityNumberOfChars)
{
}
}
and I also have this function that is provided by a service:
public IEnumerable<T> GetEntities<T>(string entityName, int numberOfChars) where T : Base
{
//Some code to get the entities
}
My problem is how can I call this function generically? I want to call it with something that looks like this:
public void TestEntities<T>() where T : Base
{
var entities = GetEntities<T>(T.EntityLogicalName, T.EntityNumberOfChars);
//some other code to test the entities
}
This of course doesn't work because at this point T is not known. How can I accomplish something similar to this? EntityLogicalName and EntityNumberOfChars are characteristics that all Base derived classes have and they never change for each derived class. Can I get them from the Base class without instantiating objects or some other way that I am not seeing?
Replace constants with getter abstract properties
public abstract class Base
{
public abstract string LogicalName { get; }
public abstract int NumberOfChars { get; }
public Base()
{
}
}
public class Derived1 : Base
{
public string LogicalName { get { return "Name1"; } }
public int NumberOfChars { get { return 30; } }
public Derived1() : base()
{
}
}
Also, you will be able to put some logic into overriden getter, e.g. :
...
public string LogicalName { get { return this.EntityMap.Name; } }
...
UPDATE: The fact that you do not want to instantiate object from class but want to be able to get that string in a strongly typed manner can be handled in one more way. It is totally separate from answer above ( Since you can't override static props in c#). Consider the following code. We are adding one more class here, but LocatorInner can be a member of BaseClass. We are using this approach a lot in several existing apps.:
public class Locator
{
public static class LocatorInner<T> where T : BaseClass
{
public static string Name { get; set; }
}
public static string GetName<T>() where T : BaseClass
{
return LocatorInner<T>.Name;
}
public static void SetName<T>(string name) where T : BaseClass
{
LocatorInner<T>.Name = name;
}
}
public class BaseClass
{
}
public class DerivedClass: BaseClass
{
static DerivedClass()
{
Locator.LocatorInner<DerivedClass>.Name = "me";
}
}
public class TestClass<T> where T : BaseClass
{
public void Method()
{
var name = Locator.GetName<T>();
}
}
IMHO, I believe using constants here is a bad design decision.
You can either solve the issue using #vittore approach, but for me it sounds like you should use meta-programming with attributes if you're looking to get data from the T generic argument
For example, what about:
public class LogicalNameAttribute : Attribute
{
public LogicalNameAttribute(string name)
{
Name = name;
}
public string Name { get; private set; }
}
public class NumberOfCharsAttribute : Attribute
{
public NumberOfCharsAttribute (int number)
{
Number = number;
}
public string Number { get; private set; }
}
[LogicalName("Name1"), NumberOfChars(30)]
public class Derived1 : Base
{
public Derived1() : base()
{
}
}
Now your service method can extract attribute metadata as follows:
public void TestEntities<T>() where T : Base
{
LogicalNameAttribute logicalNameAttr = typeof(T).GetCustomAttribute<LogicalNameAttribute>();
NumberOfCharsAttribute numberOfCharsAttr = typeof(T).GetCustomAttribute<NumberOfCharsAttribute >();
Contract.Assert(logicalNameAttr != null);
Contract.Assert(numberOfCharsAttr != null);
string logicalName = logicalNameAttr.Name;
int numberOfChars = numberOfCharsAttr.Number;
// Other stuff
}
There's a performance penalty because you need to use reflection to get attributes applied to T, but you gain the flexibility of not forcing derived classes to provide this static info.
As #vittore mentioned, move the properties to base,pass the hard coded values from derived and in creation use just defautl(T)
public IEnumerable<T> GetEntities<T>(string entityName, int numberOfChars) where T : Base
{
yield return default(T); //Is its always class use new constraint and return new T();
}
how to implement a const field which in subClasses must be overwrite, i'm using .net 4, C#
because i have many classes they all have a const field(with different value) called 'pName'.
so i want use a interface or abstract class or somthing as a parent and force these classes to override it.
it's CONST field
You cannot override a const; nor can you declare it as static and override it there. What you can do is re-declare it, but that is not robust - in that which version gets used depends on which you ask for (entirely at compile-time - completely unrelated to polymorphism):
public new const int Foo = 12;
I would suggest you use a virtual or abstract property:
public virtual int Foo { get { return 4; } } // subclasses *can* override
public abstract int Foo { get; } // subclasses *must* override
and override:
public override int Foo { get { return 12; } }
You request is contradictional: you can not define a constant value which is possible to override, so change in derived class.
What you can do is define default value in base class, and override it in derived one.
public class Base
{
public static reaondly int DEFAULT_BASE_VALUE = 0,
private int _someValue = DEFAULT_BASE_VALUE; //ASSIGN DEFAULT VALUE
public virtual int SomeValue {
get {
return _someValue;
}
}
}
public class Derived : Base
{
public override int SomeValue {
get {
return -3; //CHANGE VALUE OF BASE CLASS
}
}
}
You can't. What you can do is declare a abstract readonly property like so
abstract class A
{
public abstract int ReadOnlyProp {get;}
}
class B : A
{
public override int ReadOnlyProp
{
get { return 42; }
}
}
You can't, constants aren't virtual members.
What you could do instead is have a readonly property e.g
public class BaseClass
{
public BaseClass()
{
}
protected int MyProperty { get { return 10; } }
}
public class DerivedClass : BaseClass
{
public DerivedClass()
{
}
protected override int MyProperty { get { return 20; } }
}
I'm wondering about what's the way to go, if I need to publicate data-interfaces but want to use them internal with extended calculated properties. To make it clearer:
// The public interface
public interface IData
{
int Property { get; }
}
// The internal interface
internal interface IExtendedData : IData
{
int ExtendedProperty { get; }
}
// The assumed implementation of someone using my interface
public class Data : IData
{
public Data(int a)
{
Property = a;
}
public int Property
{
get;
private set;
}
public override string ToString()
{
return Property.ToString();
}
}
// My implementation
internal class ExtendedData : IExtendedData
{
public ExtendedData(int a)
{
Property = a;
}
public int Property
{
get;
private set;
}
public int ExtendedProperty
{
get
{
return 2 * Property;
}
}
public override string ToString()
{
return Property.ToString() + ExtendedProperty.ToString();
}
}
// publicated by me, for the person who uses my dll
public static class Calculations
{
public static int DoSomeCalculation(IData data, int parameter)
{
// This probably don't work, but maybe shows what I want to do
IExtendedData tempData = (ExtendedData)data;
return tempData.ExtendedProperty * parameter;
}
}
I'm realy frustrated, cause I feel like missing some basical programing skills.
You could solve this problem by implementing ExtendedData as a Wrapper for a class implementing IData
internal class ExtendedData : IExtendedData
{
private IData data;
public ExtendedData(IData data)
{
this.data = data;
}
public int Property
{
get { return data.Property; }
private set { data.Property = value; }
}
public int ExtendedProperty
{
get
{
return 2 * Property;
}
}
}
and use this in DoSomeCalculation like
IExtendedData tempData = new ExtendedData(data);
ExtendedData could inherit from Data:
class ExtendedData : Data
{...}
And for creation of a Data object you add a factory like so:
public class DataFactory
{
public IData CreateData()
{
return new ExtendedData();
}
}
User have to create all its Data objects by this factory. You can ensure it by making Data's constructor internal.
In your DLL you can then cast to ExtendedData.
I have a feeling I'm doing this wrong. I'm new to abstract classes and such and have been reading tutorials for a little bit, but I can't figure out how to apply it to my situation. I think that my design might be faulty but I can't think of another way to do it. My company makes a few different computers and I need to be able to monitor the battery information. Although getting the information is not the problem, figuring out how to send the different commands to the base class to do what i need it to do. Say I want to get my cell 1 voltage. On one unit the command is 0x0418, on another it is 0x453. So in my information class I run a test to see what the model is. I have a Base class called battery that has a bunch of variables that are standard for each battery (cell voltage, charge ic, charging current etc etc) I then decided it would be good to make individual classes for each of my units that extends Battery.
Now my design of the classes I think is spot on (could be wrong as I am not good at abstraction and polymorphism). I have a panel that in the end would display the information that I get from the BatteryInformation class. something like Battery1Cell1Label.Text = batteryInfo.GetCell1(1); Battery2Cell1Label = batteryInfo.GetCell1(2).
So in my base class I guess I need a GetValue(byte command) (since it is a Embedded controller command to get each different types of information.) Maybe i should stop talking and just post my code of what i have and tell you the error that I have.
battery.cs
public abstract class Battery<T> //not sure that the <T> is right
{
public string Information { get; private set; }
public float Cell1 { get; private set; }
public float Cell2 { get; private set; }
public float Cell3 { get; private set; }
public float Cell4 { get; private set; }
public int FCC { get; private set; }
public bool ChargeIC { get; private set; }
public int StartCharge { get; private set; }
public int CurrentCharge { get; private set; }
public bool Exists { get; private set; }
protected internal void GetValue(byte command)
{
//Use Embedded controller to get said value
//ECPort.ReadEC(command);
//Testing Purposeses
Console.WriteLine(command);
}
}
Battery8800.cs
class Battery8800 : Battery<Battery8800>
{
public Battery8800() : base()
{
}
public void GetValue(BatteryCommands command)
{
base.GetValue((byte)command);
}
public enum BatteryCommands
{
Battery1VoltageHigh = 0x0402,
Battery1VoltageLow = 0x0403,
Batt1ChargeCurrentHigh = 0x0404,
Batt1ChargeCurrentLow = 0x0405,
Battery1MaxError = 0x0407,
Battery1RSOC = 0x0409,
Battery1FCCHigh = 0x040E,
Battery1FCCLow = 0x040F,
Battery1DCHigh = 0x0412,
Battery1DCLow = 0x0413,
Battery1Cell1High = 0x0418,
Battery1Cell1Low = 0x0419,
Battery1Cell2High = 0x041A,
Battery1Cell2Low = 0x041B,
Battery1Cell3High = 0x041C,
Battery1Cell3Low = 0x041D,
Battery1Cell4High = 0x041E,
Battery1Cell4Low = 0x041F,
PowerSource1 = 0x0420,
//many more commands for battery 2 etc etc
}
}
BatteryInformation.cs
class BatteryInformation
{
public Battery battery1; //error says it needs 1 type of argument
public Battery battery2; //error says it needs 1 type of argument
public BatteryInformation()
{
switch (UnitModel.GetModelEnum())
{
case UnitModel.DLIModel.DLI8300M:
battery1 = new Battery8300();
battery2 = new Battery8300();
break;
case UnitModel.DLIModel.DLI8400:
battery1 = new Battery8400();
battery2 = new Battery8400();
break;
case UnitModel.DLIModel.DLI8500:
battery1 = new Battery8500();
break;
case UnitModel.DLIModel.DLI8500P:
battery1 = new Battery8500P();
break;
case UnitModel.DLIModel.DLI8800:
battery1 = new Battery8800();
break;
case UnitModel.DLIModel.DLI9200:
battery1 = new Battery9200();
break;
default:
break;
}
//for testing purposes
battery1 = new Battery8800();
battery1.DoThis(Battery8800.BatteryCommands.Batt1ChargeCurrentHigh);
}
}
YEAH FOR DRAFT SAVING!!! the power just went out, and I didn't loose but 1 sentence!
so while my computer was turning back on I was thinking it might be better to do something like this in my battery panel class.
//in my timer_tick event
BatteryInformation.UpdateBatteries();
battery1Cell1Label.Text = BatteryInformation.Battery1.Cell1.ToString();
//etc etc
but i still need to get this working but am having a hard time figuring out how to do abstraction. Thank you for your time.
EDIT
I think i'm going about this the wrong way.
class Battery1_8400 : Battery
{
public override bool Update()
{
//TODO finish
Exists = GetValue((ushort)Commands.PowerSource) != 0xFF;
if (Exists)
{
Cell1 = GetValue((ushort)Commands.Cell1Low, (ushort)Commands.Cell1High) / 1000.0f;
Cell2 = GetValue((ushort)Commands.Cell2Low, (ushort)Commands.Cell2High) / 1000.0f;
Cell3 = GetValue((ushort)Commands.Cell3Low, (ushort)Commands.Cell3High) / 1000.0f;
FCC = GetValue((ushort)Commands.FCCLow, (ushort)Commands.FCCHigh);
Voltage = GetValue((ushort)Commands.VoltageLow, (ushort)Commands.VoltageHigh);
return true;
}
else
{
return false;
}
}
private enum Commands
{
PowerSource = 0x0480,
Charge = 0x0432,
RSOC = 0x0734,
DCLow = 0x0402,
DCHigh = 0x0403,
FCCLow = 0x0404,
FCCHigh = 0x0405,
MaxError = 0x0730,
Cell1Low = 0x0778,
Cell1High = 0x0779,
Cell2Low = 0x077C,
Cell2High = 0x077D,
Cell3Low = 0x0780,
Cell3High = 0x0781,
VoltageLow = 0x0438,
VoltageHigh = 0x0439,
ChargeCurrentLow = 0x0728,
ChargeCurrentHigh = 0x0729,
ChargeIC = 0x1A03,
}
}
I have 9 files that are ALL identical in terms of how the Update command works the difference is in the enum. The commands are slightly different per class. look at batter2_8400.cs 's enum
private enum Commands
{
PowerSource = 0x0480,
Charge = 0x04C2,
RSOC = 0x0834,
DCLow = 0x0492,
DCHigh = 0x0493,
FCCLow = 0x0494,
FCCHigh = 0x0495,
MaxError = 0x0830,
Cell1Low = 0x0878,
Cell1High = 0x0879,
Cell2Low = 0x087C,
Cell2High = 0x087D,
Cell3Low = 0x0880,
Cell3High = 0x0881,
VoltageLow = 0x04C8,
VoltageHigh = 0x04C9,
ChargeCurrentLow = 0x0828,
ChargeCurrentHigh = 0x0829,
ChargeIC = 0x1A04,
}
the update command is identical in that one as well as the other 7 files. Seems kinda bad design to me, but i'm stumped as to how I should do this. By the way this is what my classes look like after the one answer I was given and the few comments that was received.
your base class BatteryInformation should have abstract properties for each value you need to retrieve like so:
public abstract class BatteryInfo {
// int should be replaced with the actual data type of the value
public abstract int VoltageHigh { get; }
public abstract int VoltageLow { get; }
// etc. for each value you need
}
Then in your child class you implement each property
public class Battery8800 : BatteryInfo {
public override int VoltageHigh {
get {
int value;
// do code to retrieve value
return value;
}
}
}
In addition, I would provide a method somewhere that your UI can consume that looks like the following:
public IEnumerable<BatteryInfo> GetAllBatteryInfo() {
// get each battery
}
That way the UI does not need to worry about how the battery info is retrieved for each battery. That allows you to use one of the list or grid style controls to view the battery info.
In the end I think i figured out what I should do. It looks clean to me and seems to make sense. Maybe you can critique it?
public abstract class Battery
{
public string Information { get; set; }
public float Cell1 { get {return GetValue(Cell1Low, Cell1High) / 1000.0f;} }
public float Cell2 { get {return GetValue(Cell2Low, Cell2High) / 1000.0f;} }
public float Cell3 { get {return GetValue(Cell3Low, Cell3High) / 1000.0f;} }
public float Cell4 { get {return GetValue(Cell4Low, Cell4High) / 1000.0f;} }
public float Voltage { get {return GetValue(VoltageLow, VoltageHigh);} }
public int DC { get {return GetValue(DCLow, DCHigh);} }
public int FCC { get {return GetValue(FCCLow, FCCHigh);} }
//public bool ChargeIC { get {return } }
//public int StartCharge { get {return } }
//public int CurrentCharge { get {return } }
public bool Exists { get {return GetValue(PowerSource) != 0xFF} }
public int FCCPercent { get {return ((FCC * 100) / DC);} }
/// <summary>
/// Gets a value depending on the Embedded controller
/// </summary>
/// <param name="low">The low byte command to process</param>
/// <param name="high">The high byte command to process</param>
/// <returns></returns>
private int GetValue(ushort low, ushort high)
{
//Use Embedded controller to get said value
//ECPort.ReadEC(command);
//Testing Purposeses
var lowValue = ECPort.ReadEC(low);
var highValue = ECPort.ReadEC(high);
return (int)((highValue << 8) + lowValue);
}
private int GetValue(ushort command)
{
return (int)ECPort.ReadEC(command);
}
public abstract ushort PowerSource {get;}
public abstract ushort Charge{get;}
public abstract ushort RSOC{get;}
public abstract ushort DCLow{get;}
public abstract ushort DCHigh{get;}
public abstract ushort FCCLow{get;}
public abstract ushort FCCHigh{get;}
public abstract ushort MaxError{get;}
public abstract ushort Cell1Low{get;}
public abstract ushort Cell1High{get;}
public abstract ushort Cell2Low{get;}
public abstract ushort Cell2High{get;}
public abstract ushort Cell3Low{get;}
public abstract ushort Cell3High{get;}
public abstract ushort Cell4Low { get; }
public abstract ushort Cell4High { get; }
public abstract ushort VoltageLow{get;}
public abstract ushort VoltageHigh{get;}
public abstract ushort ChargeCurrentLow{get;}
public abstract ushort ChargeCurrentHigh{get;}
public abstract ushort ChargeIC{get;}
}
then on my sub classes that inherit it an example would be this
class Battery1_8400 : Battery
{
public override ushort PowerSource { get {return 0x0480;}}
public override ushort Charge { get {return 0x0432;}}
public override ushort RSOC { get {return 0x0734;}}
public override ushort DCLow { get {return 0x0402;}}
public override ushort DCHigh { get {return 0x0403;}}
public override ushort FCCLow { get {return 0x0404;}}
public override ushort FCCHigh { get {return 0x0405;}}
public override ushort MaxError { get {return 0x0730;}}
public override ushort Cell1Low { get {return 0x0778;}}
public override ushort Cell1High { get {return 0x0779;}}
public override ushort Cell2Low { get {return 0x077C;}}
public override ushort Cell2High { get {return 0x077D;}}
public override ushort Cell3Low { get {return 0x0780;}}
public override ushort Cell3High { get {return 0x0781;}}
public override ushort VoltageLow { get {return 0x0438;}}
public override ushort VoltageHigh { get {return 0x0439;}}
public override ushort ChargeCurrentLow { get {return 0x0728;}}
public override ushort ChargeCurrentHigh { get {return 0x0729;}}
public override ushort ChargeIC { get {return 0x1A03;}}
}
now all i have to do is edit the one file battery.cs if i need to make a change to it.
Help me with building object model, please.
I need abstract class Unit representing each military unit in a game. There is Soldier, Tank, Jet and Bunker (children of Unit). Each of them has int properties Count and Defense, constructor with single int count parameter and one method GetTotalDefense.
My idea is following.
private abstract class Unit
{
private int Count { get; set; }
private const int Defense = 0;
protected Unit(int count)
{
Count = count;
}
public int GetTotalDefense()
{
return Count * Defense;
}
}
private class Tank : Unit
{
private const int Defense = 5;
}
Each unit has different Count and different Defense. Body of constructor and body of GetTotalDefense is always the same. What I need is in child class override Defense, because each unit has different. This property should be const, all instances of Tank (Soldier, ...) has same defense. Is there a possibility to inherit const property or each child needs its own const Defense property?
And here is an example I'd like to achieve.
Oh, there is also class Troop
public class Troop
{
private Soldier Soldiers { get; set; }
private Tank Tanks { get; set; }
private Jet Jets { get; set; }
private Fort Forts { get; set; }
public Troop(int soldiers, int tanks, int jets, int forts)
{
Soldiers = new Soldier(soldiers);
Tanks = new Tank(tanks);
Jets = new Jet(jets);
Forts = new Fort(forts);
}
public int GetTotalDefense()
{
return Soldiers.GetTotalDefense() + Tanks.GetTotalDefense() + Jets.GetTotalDefense() + Forts.GetTotalDefense();
}
}
Also, feel free to suggest better solution, thanks.
PS: I'm really strict about access modifiers, so be precise in your examples, thank you.
You can't really use a const but you can make a readonly property also are you sure you want the classes to be private and not internal or public?
public abstract class Unit {
protected Unit(int count) {
Count=count;
}
protected int Count { get; private set; }
protected abstract int Defense {get;}
public int TotalDefense {
get { return Count*Defense; }
}
}
public class Tank : Unit {
public Tank(int count) : base(count) {}
protected override int Defense {
get { return 5; }
}
}
public class Troop {
private Unit[] Troops;
public Troop(int soldiers, int tanks, int jets, int forts) {
Troops = new Unit[] {
new Soldier(soldiers),
new Tank(tanks),
new Jet(jets),
new Fort(forts)
};
}
// The using System.Linq you can do
public int TotalDefense {
get { return Troops.Sum(x=>x.TotalDefense);}
}
}
Although this solution does not use const, it achieves what you want:
internal abstract class Unit
{
private int Count { get; set; }
private int Defense { get; set; }
public int TotalDefense { get { return Count * Defense; } }
protected Unit(int defense, int count)
{
Defense = defense;
Count = count;
}
}
internal class Tank : Unit
{
protected Tank(int count)
: base(5, count) // you can use a const variable instead of 5
{
}
}
Or maybe this is more suitable:
internal abstract class Unit
{
private int Count { get; set; }
public abstract int Defense { get; }
public int TotalDefense { get { return Count * Defense; } }
protected Unit(int count)
{
Count = count;
}
}
internal class Tank : Unit
{
override public int Defense { get { return 5; } }
protected Tank(int count) : base(count)
{
}
}
What you're looking for is actually readonly. Also, since Defense is used in subclasses, you need to make it protected.
private abstract class Unit
{
private int _Count;
protected readonly const int Defense;
public int TotalDefense
{ get { return Count * Defense; } }
protected Unit (int count, int defense)
{
Defense = defense;
_Count = count;
}
}
private class Tank : Unit
{
public Tank (int Count)
: base (Count, 5)
{ }
}
public class Troop
{
public IEnumerable<Unit> Units { get; protected set; }
public Troop (int soldiers, int tanks, int jets, int forts)
{
Troops = new Unit[]
{
new Soldier (soldiers),
new Tank (tanks),
new Jet (jets),
new Fort (forts)
}
}
}
maybe something like this (but this is in java)
abstract class Unit {
Unit(int defense,int count) {
this.defense = defense;
this.count=count;
}
final int defense;
int count;
}
class Soldier extends Unit {
Soldier(int count) {
super(1,count);
}
}
class Tank extends Unit {
Tank(int count) {
super(5,count);
}
}
public class Main {
public static void main(String[] args) {
Unit[] units = { new Soldier(2), new Tank(3) };
for(Unit unit:units)
System.out.println(unit.count+" "+unit.defense);
}
}