- Home /
Classes and subclasses typecasting in unityscript
Hi !
Code first, so i don't get lost into useless specifications:
class mydevice
{
var integrity:float=100;
var deviceName:String;
}
class battery extends mydevice
{
var storage_power:float
}
class generator extends mydevice
{
var recharge_rate:float=25;
}
Now, since my goal is to add mixed types of device subclasses (batteries and generators) into a list, in order to compute, for example, the sum of storage_power or recharge_rate
And I succeded doing that, creating a list of type "mydevice". But this way, i can only see in the inspector, the variables belonging to the "mydevice" class, but not the subclass variables (and that definitively makes sense).
My unelegant solution was to put an enum "tagging" the mydevice, and checking for it's original subclass
for(var i=0;i<ship_devices.Count;i++)
{
if ((ship_devices[i].type == ShipDeviceType.Battery))
{
var typecast = ship_devices[i] as battery;
print("this is a battery, with storage = "+typecast.storage);
}
}
I'd like to know if there is a better method than this, which by the way surprisingly works in retrieving the subclass variables. Basically what i'm looking for, is being able to add different derived subclasses to a single list, without "flatting" them to the class they extend, without having to tag them or put enums just to mark a difference between them.
Thank you and have a good day !
Hi Jamora, thanks for dropping by, By using the keyword "extends" am I using inheritance (i'm using Unityscript)? If my design isn't wrong, how would you suggest accessing my subclasses ? Thanks :)
The extends
keyword is used for inheritance. When a class "extends" another class, the first class inherits from the second one, which allows it to copy the behaviour of the superclass, while adding or tweaking functionality for the subclass.
I posted my answer on how I think accessing the subclasses should be done below. The idea is, that because you store a list of $$anonymous$$yDevices
in an object, that object is only interested in the functionality of what the class $$anonymous$$yDevice
can offer; it should not be interested in anything specific a Battery
or a Generator
can do... in fact it should not even know these types exist. As a general rule of thumb, the less your objects know about each other, the better. If you know U$$anonymous$$L diagrams, less arrows = often better design.
If you're looking for code like
var List.< $$anonymous$$YSTERY TYPE > parts = {new $$anonymous$$yDevice(), new Battery(), new Generator()};
If you wanted to access each feature of each class without type casting or other trickery, there is no way, I know of, to do this.
Answer by vik.vega · Jan 25, 2014 at 06:50 PM
Thanks Jamora for your design ideas. Since my original goal was adding all my subclasses to a list of type superclass, and be able to tell in the less expensive way, which subclass an object belongs to, here's what I ended up using
if (ship_device instanceof generator)
{
print(ship_devices+" is a generator");
}
Thank you for your contribution.
Answer by Jamora · Jan 24, 2014 at 08:32 PM
There isn't a single techincal solution to design questions, but here goes my attempt...
The whole point in inheritance is that you can use multiple different types as an instance of their super class
The simplest solution would be to not derive any classes from the Device class, instead have an enum field within that class which separates the objects. Doing it this way will bite you in the arse if you end up having a lot of devices that have different variables
public enum Device_Type{
Battery,
Generator
}
public class Device{
var deviceType : Device_Type;
var storage_power : float = 0.0;
var recharge_rate : float = 0.0;
var integrity : float = 100;
}
The second option that came to me off the top of my head is to use virtual methods... which in UnityScript means just having methods with the same name.
class MyDevice
{
private var integrity:float=100;
var deviceName:String;
function GetStoragePower( ) : float { return 0; }
function GetRechargeRate( ) : float { return 0; }
function GetIntegrity() : float { return integrity; }
}
class Battery extends mydevice
{
private var storage_power:float
public function GetStoragePower(){ return storage_power; }
}
class Generator extends mydevice
{
private var recharge_rate:float=25;
public function GetRechargeRate(){ return recharge_rate; }
}
Answer by Hoeloe · Jan 24, 2014 at 05:01 PM
The reason you can only see it like that in the inspector is because the inspector instantiates variables for you. Because of that, it has no concept of the inherited values. However, it should be noted that if the base class inherits from MonoBehaviour, then it will not create new variables for you, and instead give you a reference that you can point to an object. This will allow you to point it to any child object of the base class. The downside here is that your scripts have to be defined on other objects in the scene, rather than straight into the inspector, but generally, this is a neater approach.
Hi, thanks for your answer ! Could you please elaborate what do you mean for "if the base class inherits from $$anonymous$$onoBehaviour, then it will not create new variables for you, and ins$$anonymous$$d give you a reference that you can point to an object". Is my class mydevice inheriting from mono ? what do you suggest as a "neater approach", typecasting the same way i'm doing ?
Just to sum up, I'd like a cleaner way of keeping track of which subclass an object contained in a list of mydevice (superclass, if i'm not wrong) belongs to. Thanks !
The class mydevice currently doesn't inherit from anything - you need to explicitly specify that, by using the extends
keyword. This method would allow you to place scripts of the type mydevice
(and any of its subclasses) attached to GameObjects in the scene. Doing this, you can then reference the GameObjects through the script, rather than directly writing the values into the array. This way, placing the script you want on the object will allow you to use the subclasses.
Your answer
![](https://koobas.hobune.stream/wayback/20220613131323im_/https://answers.unity.com/themes/thub/images/avi.jpg)