- Home /
How to make an abstract class with a constructor that needs a List of custom objects?
I'm trying to create an abstract class that needs a List
of objects. When I implement it, I get an error saying
There is no argument given that corresponds to the required formal parameter 'items' of 'SomeClass.SomeClass(List<MonoBehaviour>)'
I can't find the same use case as mine so I asked here.
Here's my abstract class:
public abstract class SomeClass: MonoBehaviour {
List<MonoBehaviour> mItems;
protected SomeClass(List<MonoBehaviour> items){
mItems = items;
}
public List<MonoBehaviour> GetItems(){
return mItems;
}
public abstract GameObject GetView();
}
And this how I implemented it:
public class SomeClassHandler : Adapter{
List<Item> mItems;
public SomeClassHandler(List<Item> items){
mItems = items;
}
public override GameObject GetView(){
return new GameObject();//ignore this, I'm gonna fix this later
}
}
Answer by andrew-lukasik · Nov 19, 2021 at 02:20 PM
C# requires you to call base constructor to maintain consistency.
public abstract class AbstractClass <T>
{
List<T> m_items;
public List<T> Items () => m_items;
protected AbstractClass ( List<T> items )
{
m_items = items;
}
}
public class MyClass : AbstractClass<Item>
{
public MyClass ( List<Item> items )
: base( items )
{
}
}
public struct Item {}
MonoBehaviour constructors are reserved by engine itself. Use
Start()
,Awake()
orOnEnable()
for initialization instead.
Just in case it's not clear from the second point, you can not have a parametrized constructor for MonoBehaviour derived classes since you can never call the constructor manually. The constructor of components is called by Unity and it has to be parameterless.
A common solution when you need to initialize your component externally is to provide your own "Init" method. Declare it virtual in the base class and you can override it in the derived class.
How do I use the abstract class as a parameter while also using T as possible? I made a class with a function that needs the abstract class. Now I'm wondering if I can still use generics with the abstract class and, if possible, not making the class that needs the abstract class to be tied to it(I don't know the actual term for it) as I think that would make it more difficult to use it as a component
You mean, something like this?
public abstract class AbstractClass <T>
{
List<AbstractClass<T>> _items;
public List<AbstractClass<T>> Items () => _items;
protected AbstractClass ( List<AbstractClass<T>> items )
{
_items = items;
}
public void SetItems ( List<AbstractClass<T>> items ) => this._items = items;
public void AddItem ( AbstractClass<T> item ) => this._items.Add( item );
}
public class MyClass : AbstractClass<MyClass>
{
public MyClass ( List<AbstractClass<MyClass>> items )
: base( items )
{
}
}
KISS > DRY
But I strongly suggest you don't even go there. Syntax complexity compounds and will kill your productivity if you're not careful.
TL;DR: you will work your butt off. Save few lines in this class ("hurray, I feel smarter already!"). And few weeks/months later someone will raise a topic of serialization (networking, save system) and you will despair discovering how (crazy) unnecessarily complicated^3 all of this is to serialize.
I see, thanks for the info. I'll take that into consideration